Просмотр исходного кода

chore: merge main into release

zhangyumei.0319 7 месяцев назад
Родитель
Сommit
13de2784e9
49 измененных файлов с 439 добавлено и 164 удалено
  1. 1 1
      CONTRIBUTING-en-US.md
  2. 1 1
      CONTRIBUTING.md
  3. 38 35
      README.md
  4. 6 6
      content/plus/jsonviewer/index-en-US.md
  5. 6 6
      content/plus/jsonviewer/index.md
  6. 1 1
      content/show/tooltip/index-en-US.md
  7. 3 3
      content/show/tooltip/index.md
  8. 16 7
      content/start/changelog/index-en-US.md
  9. 16 9
      content/start/changelog/index.md
  10. 4 2
      cypress/e2e/scrollList.spec.js
  11. 11 2
      packages/semi-foundation/cascader/cascader.scss
  12. 19 2
      packages/semi-foundation/cascader/foundation.ts
  13. 2 0
      packages/semi-foundation/cascader/variables.scss
  14. 1 1
      packages/semi-foundation/form/interface.ts
  15. 1 1
      packages/semi-foundation/jsonViewer/jsonViewer.scss
  16. 10 5
      packages/semi-foundation/navigation/foundation.ts
  17. 1 2
      packages/semi-foundation/navigation/itemFoundation.ts
  18. 31 0
      packages/semi-foundation/navigation/navigation.scss
  19. 21 9
      packages/semi-foundation/resizable/group/index.ts
  20. 25 8
      packages/semi-foundation/resizable/single/index.ts
  21. 6 3
      packages/semi-foundation/resizable/types.ts
  22. 3 0
      packages/semi-foundation/select/select.scss
  23. 2 0
      packages/semi-foundation/select/variables.scss
  24. 2 1
      packages/semi-foundation/timePicker/ComboxFoundation.ts
  25. 3 0
      packages/semi-foundation/treeSelect/treeSelect.scss
  26. 1 0
      packages/semi-foundation/treeSelect/variables.scss
  27. 2 2
      packages/semi-icons-lab/package.json
  28. 1 1
      packages/semi-icons/package.json
  29. 1 1
      packages/semi-illustrations/package.json
  30. 31 10
      packages/semi-ui/cascader/_story/cascader.stories.jsx
  31. 11 1
      packages/semi-ui/cascader/index.tsx
  32. 6 2
      packages/semi-ui/form/baseForm.tsx
  33. 5 0
      packages/semi-ui/form/group.tsx
  34. 3 0
      packages/semi-ui/form/hoc/withField.tsx
  35. 3 2
      packages/semi-ui/jsonViewer/index.tsx
  36. 6 4
      packages/semi-ui/navigation/Item.tsx
  37. 5 1
      packages/semi-ui/navigation/SubNav.tsx
  38. 39 0
      packages/semi-ui/navigation/_story/navigation.stories.jsx
  39. 13 3
      packages/semi-ui/radio/_story/radio.stories.jsx
  40. 13 5
      packages/semi-ui/radio/radioGroup.tsx
  41. 2 2
      packages/semi-ui/resizable/group/resizeContext.ts
  42. 21 9
      packages/semi-ui/resizable/group/resizeGroup.tsx
  43. 8 1
      packages/semi-ui/resizable/group/resizeHandler.tsx
  44. 20 8
      packages/semi-ui/resizable/single/resizable.tsx
  45. 2 0
      packages/semi-ui/resizable/single/resizableHandler.tsx
  46. 3 1
      packages/semi-ui/scrollList/scrollItem.tsx
  47. 10 0
      packages/semi-ui/select/_story/select.stories.jsx
  48. 1 1
      packages/semi-ui/treeSelect/_story/treeSelect.stories.jsx
  49. 2 5
      packages/semi-ui/typography/util.tsx

+ 1 - 1
CONTRIBUTING-en-US.md

@@ -27,7 +27,7 @@ corepack enable
 ```
 
 ```bash
-npm install --global lerna
+npm install --global lerna@6
 ```
  - Install the dependencies
 ```bash

+ 1 - 1
CONTRIBUTING.md

@@ -28,7 +28,7 @@ git checkout -b <TOPIC_BRANCH_NAME>
 >安装环境前确保本地有 `lerna` 和 `yarn` 的依赖,如果没有则运行:
 ```bash
 corepack enable
-npm install --global lerna
+npm install --global lerna@6
 ```
  - 完成项目依赖安装
 ```bash

+ 38 - 35
README.md

@@ -6,15 +6,14 @@
         A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps.
     </p>
 </article>
-    
+
 <div align="center">
 
 [![Twitter Follow](https://img.shields.io/twitter/follow/SemiDesignUI?style=social)](https://twitter.com/SemiDesignUI)
 
-[![LICENSE][license-badge]][license-url] [![NPM][npm-badge]][npm-url] [![CONTRIBUTORS][contributors-badge]][contributors-url]  ![Design Token][Design Token] [![FIGMA][figma-badge]][figma-url] 
+[![LICENSE][license-badge]][license-url] [![NPM][npm-badge]][npm-url] [![CONTRIBUTORS][contributors-badge]][contributors-url]  ![Design Token][Design Token] [![FIGMA][figma-badge]][figma-url]
 [![CODECOV][codecov-badge]][codecov-url] [![Chromatic][chromatic-badge]][chromatic-url] [![Cypress][cypress-badge]][cypress-url]
 
-
 [npm-badge]: https://img.shields.io/npm/v/@douyinfe/semi-ui.svg
 [contributors-badge]: https://img.shields.io/github/contributors/DouyinFE/semi-design
 [contributors-url]: https://github.com/DouyinFE/semi-design/graphs/contributors
@@ -32,13 +31,11 @@
 [cypress-badge]: https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/k83u7j&style=flat&logo=cypress
 [cypress-url]: https://dashboard.cypress.io/projects/k83u7j/runs
 
-
 [build-js-badge]: https://img.badgesize.io/https:/unpkg.com/@douyinfe/semi-ui/dist/umd/semi-ui.min.js?label=semi.min.js&compression=gzip
 [build-js-url]: https://unpkg.com/browse/@douyinfe/semi-ui/dist/umd/semi-ui.min.js
 [build-css-badge]: https://img.badgesize.io/https:/unpkg.com/@douyinfe/semi-ui/dist/css/semi.min.css?label=semi.min.css&compression=gzip
 [build-css-url]: https://unpkg.com/browse/@douyinfe/semi-ui/dist/css/semi.min.css
 
-
 </div>
 
 <p>
@@ -51,15 +48,15 @@ English | [简体中文](./README-zh_CN.md)
 
 # 🎉 Features
 
-- 💪 Up to 70+ high-quality Components. Stable update since 2019
-- 🚀 Official Design to Code (D2C) support, convert figma draft to real code in a few seconds
-- 💅 Code to Design (C2D), automatically generate Figma UI Kit according to different themes, keep same between design and code
+- 💪 Up to 70+ high-quality Components. Stable updates since 2019
+- 🚀 Official Design to Code (D2C) support, convert Figma draft to real code in a few seconds
+- 💅 Code to Design (C2D), automatically generate Figma UI Kit according to different themes, keep consistency  between design and code
 - 💕 Complete A11y support, follows W3C standards to provide keyboard interaction, focus management and ARIA for all components
 - 💅 Design system management Semi DSM, up to 3000+ Design Tokens, make Semi Design to Any Design quickly.
-- 🌍 Internationalization Support for Dozens of Languages, timezone, RTL support
-- ⚙️ Strict quality assurance, covering unit testing, E2E testing, visual testing.
+- 🌍 Internationalization Support for Dozens of Languages, timezone, and RTL support
+- ⚙️ Strict quality assurance, covering unit testing, E2E testing, and visual testing.
 - 👏 Written in Typescript, friendly Static Type Support. Based on Foundation/Adapter architecture, easy to read and contribute
-- 🥳 SSR (Server Side Rendering) Compatible. 
+- 🥳 SSR (Server Side Rendering) Compatible.
 - 📦 Easily compatible with web components, providing a complete adaptation solution, more suitable for building SDKs, browser plugins and other scenarios that require DOM isolation.
 
 # 🔥 Install
@@ -68,6 +65,14 @@ English | [简体中文](./README-zh_CN.md)
 npm install @douyinfe/semi-ui
 ```
 
+```sh
+yarn add @douyinfe/semi-ui
+```
+
+```sh
+pnpm add @douyinfe/semi-ui
+```
+
 # 👍 Component Usage
 
 Here is a quick example to get you started, it's all you need:
@@ -95,7 +100,7 @@ root.render(<App />);
 
 Install [Semi Figma Plugin](https://www.figma.com/community/plugin/1166339852662786534/Semi-Design-%E8%AE%BE%E8%AE%A1%E8%BD%AC%E4%BB%A3%E7%A0%81). Translate Figma to real code in seconds. Support multiple output formats: JSX + SCSS / Emotion/Tailwind, or JSON Schema DSL
 
-- Support figma devmode, selecting a layer, directly get corresponding code on the right
+- Support Figma devmode, selecting a layer, directly get corresponding code on the right
   
 ![design2code](https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/github/devmode.gif)
 
@@ -103,43 +108,42 @@ Install [Semi Figma Plugin](https://www.figma.com/community/plugin/1166339852662
   
 ![codesandboxdemo](https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/github/1080p-fps5.gif)
 
-
 # 🎨 DSM Usage
 
-Define your own design system base on Semi UI with DSM in one click, Provide more than 3000 tokens for you to configure every detail. Sync between Figma and Code at all times.
+Define your own design system based on Semi UI with DSM in one click, Provide more than 3000 tokens for you to configure every detail. Sync between Figma and Code always.
 
 ![dsmintro](https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/github/dsmintro.png)
 
-
 # 📰 News about Semi UI
-* [Follow on Twitter](https://twitter.com/SemiDesignUI)
-* [Follow on Medium](https://medium.com/@semi-design)
-* [Follow on Dev.to](https://dev.to/semidesign)
 
+- [Follow on Twitter](https://twitter.com/SemiDesignUI)
+- [Follow on Medium](https://medium.com/@semi-design)
+- [Follow on Dev.to](https://dev.to/semidesign)
 
 # 📌 Documentation
-* [Semi DSM](https://semi.design/dsm)
-* [Design to Code](https://semi.design/code/en-US)
-* [Semi Figma Plugin](https://www.figma.com/community/plugin/1166339852662786534/Semi-Design-%E8%AE%BE%E8%AE%A1%E8%BD%AC%E4%BB%A3%E7%A0%81)
-* [Quick Start](https://semi.design/en-US/start/getting-started)
-* [Components Overview](https://semi.design/en-US/start/overview)
-* [Customizing Themes](https://semi.design/en-US/start/customize-theme)
-* [Design Tokens](https://semi.design/en-US/basic/tokens)
-* [Dark Mode](https://semi.design/en-US/start/dark-mode)
-* [Semi Icons](https://semi.design/en-US/basic/icon)
-* [Global Config](https://semi.design/en-US/other/configprovider)
-* [Internationalization](https://semi.design/en-US/other/locale)
-* [FAQ](https://semi.design/en-US/start/faq)
-* [CHANGELOG](https://semi.design/en-US/start/changelog)
+
+- [Semi DSM](https://semi.design/dsm)
+- [Design to Code](https://semi.design/code/en-US)
+- [Semi Figma Plugin](https://www.figma.com/community/plugin/1166339852662786534/Semi-Design-%E8%AE%BE%E8%AE%A1%E8%BD%AC%E4%BB%A3%E7%A0%81)
+- [Quick Start](https://semi.design/en-US/start/getting-started)
+- [Components Overview](https://semi.design/en-US/start/overview)
+- [Customizing Themes](https://semi.design/en-US/start/customize-theme)
+- [Design Tokens](https://semi.design/en-US/basic/tokens)
+- [Dark Mode](https://semi.design/en-US/start/dark-mode)
+- [Semi Icons](https://semi.design/en-US/basic/icon)
+- [Global Config](https://semi.design/en-US/other/configprovider)
+- [Internationalization](https://semi.design/en-US/other/locale)
+- [FAQ](https://semi.design/en-US/start/faq)
+- [CHANGELOG](https://semi.design/en-US/start/changelog)
 
 # 📝 Blogs
+
 - [The Evolution of Semi D2C Design to Code](https://juejin.cn/post/7267418854124699702)
 - [How to design component library architecture to adapt to different mvvm frameworks](https://bytedance.feishu.cn/wiki/wikcnOVYexosCS1Rmvb5qCsWT1f)
 - [How we test semi ui](https://medium.com/front-end-weekly/how-we-test-semi-design-component-libraries-64b854f63b65)
 - [In-depth explanation of Semi theme](https://mp.weixin.qq.com/s/noHoWRuA25PgqFNcurhIUA)
 - [Accessibility in Semi Design](https://mp.weixin.qq.com/s/O3js-SZDNPEOjGxh-aAkbw)
 
-
 # 👌 Platform Support
 
 Semi UI supports all major modern browsers.
@@ -162,7 +166,6 @@ Thanks to [Chromatic](https://www.chromatic.com/) for providing the visual testi
 
 Thanks to [Cypress](https://www.cypress.io/) for providing E2E testing.
 
-
 <div>
   <a href="https://www.visactor.com#gh-light-mode-only" target="_blank">
     <img alt="VisActor Logo" height="30" src="https://lf-dp.bytetos.com/obj/dp-open-internet-cn/visactor-site/bytedance/client/img/visactor/navigator-logo.svg"/>
@@ -174,15 +177,15 @@ Thanks to [Cypress](https://www.cypress.io/) for providing E2E testing.
 
 Thanks to [VisActor](https://www.visactor.com/) for providing the data visualization solution.
 
-
 ## 👐 Contributing
+
 Thanks to all the people who already contributed!
 
 <a href="https://github.com/DouyinFE/semi-design/graphs/contributors">
   <img src="https://contrib.rocks/image?repo=DouyinFE/semi-design" />
 </a>
 
-Read the contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Semi UI.
+Read the contributing guide to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes to Semi UI.
 
 See [CONTRIBUTING](CONTRIBUTING-en-US.md) documentation.
 

+ 6 - 6
content/plus/jsonviewer/index-en-US.md

@@ -49,7 +49,7 @@ class SimpleJsonViewer extends React.Component {
     render() {
         return (
             <div style={{ marginBottom: 16 }}>
-                <JsonViewer height={100} width={400} value={data} />
+                <JsonViewer height={100} width={700} value={data} />
             </div>
         );
     }
@@ -74,13 +74,13 @@ class SimpleJsonViewerWithLineHeight extends React.Component {
         return (
             <div>
                 <div style={{ marginBottom: 20 }}>
-                    <JsonViewer height={100} width={320} value={data} options={{ lineHeight: 20 }} />
+                    <JsonViewer height={100} width={700} value={data} options={{ lineHeight: 20 }} />
                 </div>
                 <div style={{ marginBottom: 20 }}>
-                    <JsonViewer height={120} width={320} value={data} options={{ lineHeight: 24 }} />
+                    <JsonViewer height={120} width={700} value={data} options={{ lineHeight: 24 }} />
                 </div>
                 <div style={{ marginBottom: 20 }}>
-                    <JsonViewer height={120} width={320} value={data} options={{ lineHeight: 26 }} />
+                    <JsonViewer height={120} width={700} value={data} options={{ lineHeight: 26 }} />
                 </div>
             </div>
         );
@@ -106,7 +106,7 @@ class SimpleJsonViewerWithAutoWrap extends React.Component {
     render() {
         return (
             <div style={{ marginBottom: 16 }}>
-                <JsonViewer height={120} width={800} value={data} options={{ autoWrap: true }} />
+                <JsonViewer height={120} width={700} value={data} options={{ autoWrap: true }} />
             </div>
         );
     }
@@ -139,7 +139,7 @@ function FormatJsonComponent() {
                 <JsonViewer
                     ref={jsonviewerRef}
                     height={100}
-                    width={400}
+                    width={700}
                     value={data}
                     options={{ formatOptions: { tabSize: 4, insertSpaces: true, eol: '\n' } }}
                 />

+ 6 - 6
content/plus/jsonviewer/index.md

@@ -45,7 +45,7 @@ class SimpleJsonViewer extends React.Component {
     render() {
         return (
             <div style={{ marginBottom: 16 }}>
-                <JsonViewer height={100} width={400} value={data} />
+                <JsonViewer height={100} width={700} value={data} />
             </div>
         );
     }
@@ -70,13 +70,13 @@ class SimpleJsonViewerWithLineHeight extends React.Component {
         return (
             <div>
                 <div style={{ marginBottom: 12, overflow: 'hidden' }}>
-                    <JsonViewer height={100} width={320} value={data} options={{ lineHeight: 20 }} />
+                    <JsonViewer height={100} width={700} value={data} options={{ lineHeight: 20 }} />
                 </div>
                 <div style={{ marginBottom: 12, overflow: 'hidden' }}>
-                    <JsonViewer height={120} width={320} value={data} options={{ lineHeight: 24 }} />
+                    <JsonViewer height={120} width={700} value={data} options={{ lineHeight: 24 }} />
                 </div>
                 <div style={{ marginBottom: 12, overflow: 'hidden' }}>
-                    <JsonViewer height={120} width={320} value={data} options={{ lineHeight: 26 }} />
+                    <JsonViewer height={120} width={700} value={data} options={{ lineHeight: 26 }} />
                 </div>
             </div>
         );
@@ -102,7 +102,7 @@ class SimpleJsonViewerWithAutoWrap extends React.Component {
     render() {
         return (
             <div style={{ marginBottom: 16 }}>
-                <JsonViewer height={120} width={800} value={data} options={{ autoWrap: true }} />
+                <JsonViewer height={120} width={700} value={data} options={{ autoWrap: true }} />
             </div>
         );
     }
@@ -135,7 +135,7 @@ function FormatJsonComponent() {
                 <JsonViewer
                     ref={jsonviewerRef}
                     height={100}
-                    width={400}
+                    width={700}
                     value={data}
                     options={{ formatOptions: { tabSize: 4, insertSpaces: true, eol: '\n' } }}
                 />

+ 1 - 1
content/show/tooltip/index-en-US.md

@@ -259,7 +259,7 @@ function Demo() {
 
 ### Override Style
 
-Configure specific styles for the pop-up layer through the `className` and `style` API, such as overriding the default maxWidth (280px)
+Configure specific styles for the pop-up layer through the `className` and `style` API, such as overriding the default maxWidth (240px)
 
 ```jsx live=true
 import React from 'react';

+ 3 - 3
content/show/tooltip/index.md

@@ -260,7 +260,7 @@ function Demo() {
 
 ### 覆盖特定样式
 
-你可以通过 className、style 为弹出层配置特定样式,例如覆盖默认的 maxWidth (280px)
+你可以通过 className、style 为弹出层配置特定样式,例如覆盖默认的 maxWidth (240px)
 ```jsx live=true
 import React from 'react';
 import { Tooltip, Tag } from '@douyinfe/semi-ui';
@@ -285,7 +285,7 @@ import { Tooltip, Tag } from '@douyinfe/semi-ui';
 
 传入 `getPopupContainer`,弹层将会渲染至该函数返回的 DOM 中。 这会改变浮层 DOM 树位置,但不会改变视图渲染位置。
 
-**需要注意的是:** 返回的容器如果不是 `document.body`,**`position` 需要设为 `"relative"`**(版本 >= 0.18.0)。
+**需要注意的是:** 返回的容器如果不是 `document.body`,**`position` 需要设为 `"relative"`**
 
 ```jsx live=true hideInDSM
 import React from 'react';
@@ -387,7 +387,7 @@ function Demo() {
 | style    | 弹出层的内联样式                                                                                                                                             | object |  |  |
 | spacing | 弹出层与 `children` 元素的距离,单位 px(object类型自 v2.45后支持)                                                                                                                     | number | <ApiType detail='{ x: number; y: number }'>SpacingObject</ApiType>  | 8 |  |
 | showArrow | 是否显示箭头三角形                                                                                                                                            | boolean | true |  |
-| stopPropagation | 是否阻止弹层上的点击事件冒泡                                                                                                                                       | boolean | false | **0.34.0** |
+| stopPropagation | 是否阻止弹层上的点击事件冒泡                                                                                                                                       | boolean | false |  |
 | transformFromCenter | 是否从包裹的元素水平或垂直中心处变换,该参数仅影响动效变换的 `transform-origin`,一般无需改动                                                                                             | boolean | true |  |
 | trigger | 触发展示的时机,可选值:`hover` / `focus` / `click` / `custom` / `contextMenu` (v2.42后提供)                                                                                                   | string | 'hover' |  |
 | visible | 是否展示弹出层                                                                                                                                              | boolean |  |  |

+ 16 - 7
content/start/changelog/index-en-US.md

@@ -15,21 +15,30 @@ Version:Major.Minor.Patch (follow the **Semver** specification)
 -   **Patch version**: Only include bug fix, the release time is not limited
 
 ---
+
+#### 🎉 2.75.0 (2025-02-21)
+- 【Design Token】
+    - Select adds $color-select_prefix_suffix_text-default, Cascader adds $color-cascader_prefix_suffix_text-default, and TreeSelect adds $color-treeSelect_prefix_text-default to control the prefix and suffix colors. In addition, keep the font-size and font-weight settings of the prefix and suffix consistent with the settings of insetLabal (**Note: There are changes in styles before and after modification**)  [#2721](https://github.com/DouyinFE/semi-design/issues/2721)
+- 【Fix】
+    - Fixed the bug where the accessibility rendering of aria attributes in Chrome v133 caused Chrome to crash after clicking the month selector of the DatePicker [#2723](https://github.com/DouyinFE/semi-design/pull/2723)
+    - Fixed the issue that Resizable could not be used on touchscreens [#2697](https://github.com/DouyinFE/semi-design/issues/2697) [#2712](https://github.com/DouyinFE/semi-design/pull/2712)
+    - Removed the use of the outdated React syntax ReactDOM.render() in Typography and replaced it with other methods to clear the container used for testing the appropriate ellipsis length  [#2699](https://github.com/DouyinFE/semi-design/issues/2699)
+    - Fixed the problem that when using formApi.scrollToField in Form, if there are multiple Forms on the page and the fields have the same name, only the DOM of the first field with the same name can be scrolled to [#2719](https://github.com/DouyinFE/semi-design/pull/2719)
+    - Fixed the problem that when only extraText is configured in Form.InputGroup and extraPosition is not configured, extraText cannot be displayed correctly [#2719](https://github.com/DouyinFE/semi-design/pull/2719)
+- 【Chore】
+    - Fix the problem of the TypeScript type definition error of Form formApi.scrollToError.[#2719](https://github.com/DouyinFE/semi-design/pull/2719)
+
+
 #### 🎉 2.75.0-beta.1 (2025-02-19)
 - 【Docs】
     - List component drag demo updated to use dnd-kit
 - 【Feat】
     - add renderPicClose to custom close icon under listType picture
-    - Tree/TreeSelect supports expandIcon API for customizing the expand icon  [#2704 ](https://github.com/DouyinFE/semi-design/issues/2704)
+    - Tree/TreeSelect supports expandIcon API for customizing the expand icon  [#2704](https://github.com/DouyinFE/semi-design/issues/2704)
 - 【Fix】
-    - Fixed the problem that Pagination's page capacity switcher cannot switch languages ​​correctly in multi-language scenarios  [#2696 ](https://github.com/DouyinFE/semi-design/issues/2696)
+    - Fixed the problem that Pagination's page capacity switcher cannot switch languages ​​correctly in multi-language scenarios  [#2696](https://github.com/DouyinFE/semi-design/issues/2696)
     - fix iOS input interruption in PinCode component with format='number' (switches from number/character to letter keyboard after input a digit) [@SaltyfishEd](https://github.com/SaltyfishEd)
 
-#### 🎉 2.75.0-beta.0 (2025-02-18)
-- 【Feat】
-  - Tree/TreeSelect supports expandIcon API for customizing the expand icon  [#2704 ](https://github.com/DouyinFE/semi-design/issues/2704)
-- 【Fix】
-  - fix iOS input interruption in PinCode component with format='number' (switches from number/character to letter keyboard after input a digit) [@SaltyfishEd](https://github.com/SaltyfishEd)
 
 #### 🎉 2.74.0 (2025-02-07)
 - 【Fix】

+ 16 - 9
content/start/changelog/index.md

@@ -13,22 +13,29 @@ Semi 版本号遵循 **Semver** 规范(主版本号-次版本号-修订版本
 -   修订版本号(patch):仅会进行 bugfix,发布时间不限
 -   不同版本间的详细关系,可查阅 [FAQ](/zh-CN/start/faq)
 
+
+#### 🎉 2.75.0 (2025-02-21)
+- 【Design Token】
+    - Select 新增 $color-select_prefix_suffix_text-default, Cascader 新增 $color-cascader_prefix_suffix_text-default, TreeSelect 新增 $color-treeSelect_prefix_text-default 用于控制控制前后缀颜色。另外,将前后缀的 font-size 和 font-weight 的设置和 insetLabal的设置保持统一(**注意:修改前后样式有变化**) [#2721](https://github.com/DouyinFE/semi-design/issues/2721)
+- 【Fix】
+    - 修复 Chrome v133 版本无障碍渲染 aria 属性 Bug 导致的点击 DatePicker 月份选择器后 Chrome 崩溃问题 [#2723](https://github.com/DouyinFE/semi-design/pull/2723)
+    - 修复 Resizable 无法在触摸屏使用问题 [#2697](https://github.com/DouyinFE/semi-design/issues/2697) [#2712](https://github.com/DouyinFE/semi-design/pull/2712)
+    - 去除 Typography 中过时 React 语法ReactDOM.render() 的使用,改为其他方式清空用于测试合适省略长度的容器  [#2699](https://github.com/DouyinFE/semi-design/issues/2699)
+    - 修复 Form 使用 formApi.scrollToField时,若页面存在多个 Form,且 Field 同名时,仅可滚动到首个同名 Field DOM 的问题 [#2719](https://github.com/DouyinFE/semi-design/pull/2719)
+    - 修复 Form.InputGroup 仅配置 extraText,未配置 extraPosition时,extraText未能正确显示的问题 [#2719](https://github.com/DouyinFE/semi-design/pull/2719)
+- 【Chore】
+    - 修复 Form formApi.scrollToError TS 类型定义错误的问题 [#2719](https://github.com/DouyinFE/semi-design/pull/2719)
+
 #### 🎉 2.75.0-beta.1 (2025-02-19)
 - 【Docs】
     - List 组件拖拽 Demo 更新为用 dnd-kit 实现 [#2717](https://github.com/DouyinFE/semi-design/pull/2717)
 - 【Feat】
-    - 在图片墙场景下添加 renderPicClose 用于自定义关闭图标 [#2714](https://github.com/DouyinFE/semi-design/pull/2714)
-    - Tree/TreeSelect 支持 expandIcon API 用于自定义展开图标  [#2704 ](https://github.com/DouyinFE/semi-design/issues/2704) [#2709](https://github.com/DouyinFE/semi-design/pull/2709)
+    - Upload 在图片墙场景下添加 renderPicClose 用于自定义关闭图标 [#2714](https://github.com/DouyinFE/semi-design/pull/2714)
+    - Tree/TreeSelect 支持 expandIcon API 用于自定义展开图标  [#2704](https://github.com/DouyinFE/semi-design/issues/2704) 
 - 【Fix】
     - 修复 Pagination 的页容量切换器在多语言场景无法切换语言问题  [#2696 ](https://github.com/DouyinFE/semi-design/issues/2696) [#2698](https://github.com/DouyinFE/semi-design/pull/2698)
     - 修复 PinCode 组件 format='number' 情况下,iOS端输入被打断问题(输入一个数字后,自动从数字/字符键盘切换到字母键盘) [@SaltyfishEd](https://github.com/SaltyfishEd) [#2702](https://github.com/DouyinFE/semi-design/pull/2702)
 
-#### 🎉 2.75.0-beta.0 (2025-02-18)
-- 【Feat】
-  - Tree/TreeSelect 支持 expandIcon API 用于自定义展开图标  [#2704 ](https://github.com/DouyinFE/semi-design/issues/2704) [#2709](https://github.com/DouyinFE/semi-design/pull/2709)
-- 【Fix】
-  - 修复 PinCode 组件 format='number' 情况下,iOS端输入被打断问题(输入一个数字后,自动从数字/字符键盘切换到字母键盘) [@SaltyfishEd](https://github.com/SaltyfishEd) [#2702](https://github.com/DouyinFE/semi-design/pull/2702)
-
 #### 🎉 2.74.0 (2025-02-07)
 - 【Fix】
     - 修复 List 组件 dataSource 为空时被 Spin 组件遮挡问题 [@LonelySnowman](https://github.com/LonelySnowman) [#2693](https://github.com/DouyinFE/semi-design/pull/2693)
@@ -42,7 +49,7 @@ Semi 版本号遵循 **Semver** 规范(主版本号-次版本号-修订版本
 - 【Feat】
   - Chat 组件支持 markdownRenderProps API,用于设置对话渲染的 MarkdownRender 组件  [#2640 ](https://github.com/DouyinFE/semi-design/issues/2640) [#2679](https://github.com/DouyinFE/semi-design/pull/2679)
 - 【Fix】
-  - 修复JsonViewer输入小写z无效的问题 [@anjiazhuyouxing](https://github.com/anjiazhuyouxing) [#2680](https://github.com/DouyinFE/semi-design/pull/2680)
+  - 修复 JsonViewer 输入小写z无效的问题 [@anjiazhuyouxing](https://github.com/anjiazhuyouxing) [#2680](https://github.com/DouyinFE/semi-design/pull/2680)
 
 #### 🎉 2.73.0 (2025-01-13)
 - 【Fix】

+ 4 - 2
cypress/e2e/scrollList.spec.js

@@ -6,7 +6,8 @@ describe('scrollList', () => {
         cy.get('.semi-scrolllist-item-sel').contains('5');
     });
 
-    it('infinite scroll', () => {
+    // todo: due to the https://github.com/DouyinFE/semi-design/pull/2723, temporarily skip this test case
+    it.skip('infinite scroll', () => {
         cy.visit('http://127.0.0.1:6006/iframe.html?id=scrolllist--single-scroll-list&args=&viewMode=story');
         cy.wait(500);
         cy.get('li[aria-selected="true"]').contains(0);
@@ -17,7 +18,8 @@ describe('scrollList', () => {
         cy.get('.semi-scrolllist-item-wheel .semi-scrolllist-list-outer').scrollTo('bottom', { duration: 2000 });
     });
 
-    it('click option', () => {
+    // todo: due to the https://github.com/DouyinFE/semi-design/pull/2723, temporarily skip this test case
+    it.skip('click option', () => {
         cy.visit('http://127.0.0.1:6006/iframe.html?id=scrolllist--single-scroll-list&args=&viewMode=story');
         cy.get('li[aria-selected="true"]').contains(0);
         cy.get('.semi-scrolllist-list-outer').contains(59).click();

+ 11 - 2
packages/semi-foundation/cascader/cascader.scss

@@ -246,6 +246,9 @@ $module: #{$prefix}-cascader;
 
         &-text {
             margin: 0 $spacing-cascader_text-marginX;
+            font-weight: $font-weight-bold;
+            @include font-size-regular;
+            color: $color-cascader_prefix_suffix_text-default;
         }
 
         &-icon {
@@ -312,16 +315,20 @@ $module: #{$prefix}-cascader;
         border-bottom: $width-cascader_search-border solid $color-cascader_search-border-default;
     }
 
-    .#{$module}-option-empty {
+    .#{$module}-option-lists .#{$module}-option-empty {
         @include font-size-regular;
         border-radius: $radius-cascader_option_empty;
-        min-width: $width-cascader_option;
+        // min-width: $width-cascader_option;
         color: $color-cascader_option_empty-text-default;
         margin: 0;
         padding: $spacing-cascader_option_empty-paddingY $spacing-cascader_option_empty-paddingX;
         user-select: none;
         text-align: center;
         cursor: not-allowed;
+
+        &:hover {
+            background-color: transparent;
+        }
     }
 }
 
@@ -378,6 +385,8 @@ $module: #{$prefix}-cascader;
 
     &-empty {
         height: auto;
+        justify-content: center;
+        cursor: not-allowed;
     }
 
     ul,

+ 19 - 2
packages/semi-foundation/cascader/foundation.ts

@@ -1,4 +1,4 @@
-import { isEqual, get, difference, isUndefined, assign, isEmpty, isNumber, includes, isFunction, isObject } from 'lodash';
+import { isEqual, get, difference, isUndefined, assign, isEmpty, isNumber, includes, isFunction, isObject, isString } from 'lodash';
 import BaseFoundation, { DefaultAdapter } from '../base/foundation';
 import {
     findAncestorKeys,
@@ -186,6 +186,7 @@ export interface BasicCascaderProps {
 }
 
 export interface BasicCascaderInnerData {
+    emptyContentMinWidth: number;
     isOpen: boolean;
     rePosKey: number;
     keyEntities: BasicEntities;
@@ -239,7 +240,9 @@ export interface CascaderAdapter extends DefaultAdapter<BasicCascaderProps, Basi
     updateLoadingKeyRefValue: (keys: Set<string>) => void;
     getLoadingKeyRefValue: () => Set<string>;
     updateLoadedKeyRefValue: (keys: Set<string>) => void;
-    getLoadedKeyRefValue: () => Set<string>
+    getLoadedKeyRefValue: () => Set<string>;
+    setEmptyContentMinWidth: (minWidth: number) => void;
+    getTriggerWidth: () => number;
 }
 
 export default class CascaderFoundation extends BaseFoundation<CascaderAdapter, BasicCascaderProps, BasicCascaderInnerData> {
@@ -259,6 +262,19 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
         }
     }
 
+    _setEmptyContentMinWidth() {
+        const { style } = this.getProps();
+        let width;
+        if (style && isNumber(style.width)) {
+            width = style.width;
+        } else if (style && isString(style.width) && !style.width.includes('%')) {
+            width = style.width;
+        } else {
+            width = this._adapter.getTriggerWidth();
+        }
+        this._adapter.setEmptyContentMinWidth(width);
+    }
+
     handleKeyDown = (e: any) => {
         if (e.key === ESC_KEY) {
             const isOpen = this.getState('isOpen');
@@ -531,6 +547,7 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
         }
         this._adapter.notifyDropdownVisibleChange(true);
         this._adapter.registerClickOutsideHandler(e => this.close(e));
+        this._setEmptyContentMinWidth();
     }
 
     reCalcActiveKeys() {

+ 2 - 0
packages/semi-foundation/cascader/variables.scss

@@ -43,6 +43,8 @@ $color-cascader_danger-border-focus: var(--semi-color-danger); // 级联选择
 $color-cascader_danger-bg-active: var(--semi-color-danger-light-active); // 级联选择触发器危险背景颜色 - 按下
 $color-cascader_danger-border-active: var(--semi-color-danger-light-active); // 级联选择触发器危险描边颜色 - 按下
 
+$color-cascader_prefix_suffix_text-default: var(--semi-color-text-2); // 级联选择前后缀文字颜色
+
 $spacing-cascader_selection-paddingLeft: 12px; // 级联选择触发器左侧内边距
 $spacing-cascader_selection-paddingRight: 12px; // 级联选择触发器右侧内边距
 $spacing-cascader_selection_multiple-paddingLeft: $spacing-extra-tight; // 级联选择触发器多选时左侧内边距

+ 1 - 1
packages/semi-foundation/form/interface.ts

@@ -67,7 +67,7 @@ export type FieldPathValue<T, P extends FieldPath<T>> =
 export type ScrollToErrorOptions<K> = {
     field?: K;
     index?: number;
-    scrollConfig?: ScrollIntoViewOptions
+    scrollOpts?: ScrollIntoViewOptions
 }
 
 // use object replace Record<string, any>, fix issue 933

+ 1 - 1
packages/semi-foundation/jsonViewer/jsonViewer.scss

@@ -111,7 +111,7 @@ $module: #{$prefix}-json-viewer;
         align-items: flex-start;
         gap: 8px;
         &-input {
-            width: 200px;
+            width: 200px !important;
             flex-shrink: 0;
         }
         .#{$prefix}-button-group {

+ 10 - 5
packages/semi-foundation/navigation/foundation.ts

@@ -80,6 +80,11 @@ export default class NavigationFoundation<P = Record<string, any>, S = Record<st
                     }
                     if (itemKey) {
                         keysMap[itemKey] = [...parentKeys];
+                        // Children is not a recommended usage and may cause some bug-like performance, but some users have already used it, so here we only delete the ts definition instead of deleting the actual code
+                        // children 并不是我们推荐的用法,可能会导致一些像 bug的表现,但是有些用户已经用了,所以此处仅作删除 ts 定义而非删除实际代码的操作
+                        // refer https://github.com/DouyinFE/semi-design/issues/2710
+                        // @ts-ignore  
+                        const itemChildren = item.props?.children;
 
                         if (Array.isArray(item.items) && item.items.length) {
                             NavigationFoundation.buildItemKeysMap(
@@ -87,11 +92,11 @@ export default class NavigationFoundation<P = Record<string, any>, S = Record<st
                                 keysMap,
                                 [...parentKeys, itemKey],
                                 keyPropName
-                            );
-                        } else if (item.props && item.props.children) {
-                            const children = Array.isArray(item.props.children)
-                                ? item.props.children
-                                : [item.props.children];
+                            );  
+                        } else if (itemChildren) { 
+                            const children = Array.isArray(itemChildren) 
+                                ? itemChildren
+                                : [itemChildren];
                             NavigationFoundation.buildItemKeysMap(
                                 children,
                                 keysMap,

+ 1 - 2
packages/semi-foundation/navigation/itemFoundation.ts

@@ -13,8 +13,7 @@ export interface ItemProps {
     isSubNav?: boolean;
     link?: string;
     linkOptions?: Record<string, any>;
-    disabled?: boolean;
-    children?: any
+    disabled?: boolean
 }
 
 export type ItemKey = string | number;

+ 31 - 0
packages/semi-foundation/navigation/navigation.scss

@@ -483,6 +483,37 @@ $module: #{$prefix}-navigation;
                 }
             }
         }
+
+        // 兼容 renderWrapper 的场景,详见 issue: https://github.com/DouyinFE/semi-design/issues/2690
+        &-list  .#{$module}-sub-wrap {
+            & > .#{$module}-sub-title {
+
+                &-disabled {
+                    @include item-disabled;
+                }
+
+                &:hover {
+                    &:not(.#{$module}-sub-title-selected) {
+                        @include item-hover;
+                    }
+
+                    &.#{$module}-sub-title-selected {
+                        @include item-hover-selected;
+                    }
+                }
+
+                &:hover {
+                    &.#{$module}-sub-title-disabled {
+                        &:not(.#{$module}-sub-title-selected) {
+                            @include item-disabled;
+                        }
+                        &.#{$module}-sub-title-selected {
+                            @include item-disabled-selected;
+                        }
+                    }
+                }
+            }
+        }
     }
 
     .#{$module}-item:last-of-type {

+ 21 - 9
packages/semi-foundation/resizable/group/index.ts

@@ -1,6 +1,6 @@
 import { getItemDirection, getPixelSize } from "../utils";
 import BaseFoundation, { DefaultAdapter } from '../../base/foundation';
-import { ResizeStartCallback, ResizeCallback } from "../types";
+import { ResizeStartCallback, ResizeCallback, ResizeEventType } from "../types";
 import { adjustNewSize, judgeConstraint, getOffset } from "../utils";
 import { debounce } from "lodash";
 export interface ResizeHandlerAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
@@ -49,8 +49,8 @@ export interface ResizeGroupAdapter<P = Record<string, any>, S = Record<string,
     getItemChange: (index: number) => ResizeCallback;
     getItemEnd: (index: number) => ResizeCallback;
     getItemDefaultSize: (index: number) => string | number;
-    registerEvents: () => void;
-    unregisterEvents: () => void
+    registerEvents: (type: ResizeEventType) => void;
+    unregisterEvents: (type: ResizeEventType) => void
 }
 
 export class ResizeGroupFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ResizeGroupAdapter<P, S>, P, S> {
@@ -72,6 +72,7 @@ export class ResizeGroupFoundation<P = Record<string, any>, S = Record<string, a
     itemMinusMap: Map<number, number>; // 这个是为了给handler留出空间,方便维护每一个item的size为cal(percent% - minus)
     totalMinus: number;
     itemPercentMap: Map<number, number>; // 内部维护一个百分比数组,消除浮点计算误差
+    type?: ResizeEventType;
 
 
     init(): void {
@@ -86,14 +87,15 @@ export class ResizeGroupFoundation<P = Record<string, any>, S = Record<string, a
 
     
     registerEvents = () => {
-        this._adapter.registerEvents();
+        this._adapter.registerEvents(this.type);
     }
 
     unregisterEvents = () => {
-        this._adapter.unregisterEvents();
+        this._adapter.unregisterEvents(this.type);
     }
 
-    onResizeStart = (handlerIndex: number, e: MouseEvent) => { // handler ref
+    onResizeStart = (handlerIndex: number, e: MouseEvent | Touch, type: ResizeEventType) => { // handler ref
+        this.type = type;
         let { clientX, clientY } = e;
         let lastItem = this._adapter.getItem(handlerIndex), nextItem = this._adapter.getItem(handlerIndex + 1);
         let lastOffset: number, nextOffset: number;
@@ -135,15 +137,25 @@ export class ResizeGroupFoundation<P = Record<string, any>, S = Record<string, a
         }
     }
 
+    onMouseMove = (e: MouseEvent) => {
+        this.onResizing(e);
+    }
 
-    onResizing = (e: MouseEvent) => {
+    onTouchMove = (e: TouchEvent) => {
+        // prevent page move in mobile
+        e.preventDefault();
+        this.onResizing(e);
+    }
+
+
+    onResizing = (e: MouseEvent | TouchEvent) => {
         const state = this.getStates();
         if (!state.isResizing) {
             return;
         }
         const { curHandler, originalPosition } = state;
         let { x: initX, y: initY, lastItemSize, nextItemSize, lastOffset, nextOffset } = originalPosition;
-        let { clientX, clientY } = e;
+        let { clientX, clientY } = this.type === 'mouse' ? e : (e as any).targetTouches[0];
 
         const props = this.getProps();
         const { direction } = props;
@@ -193,7 +205,7 @@ export class ResizeGroupFoundation<P = Record<string, any>, S = Record<string, a
         }
     }
 
-    onResizeEnd = (e: MouseEvent) => {
+    onResizeEnd = (e: MouseEvent | TouchEvent) => {
         const { curHandler } = this.getStates();
         let lastItem = this._adapter.getItem(curHandler), nextItem = this._adapter.getItem(curHandler + 1);
         let lastFunc = this._adapter.getItemEnd(curHandler),

+ 25 - 8
packages/semi-foundation/resizable/single/index.ts

@@ -1,5 +1,5 @@
 import BaseFoundation, { DefaultAdapter } from '../../base/foundation';
-import { DEFAULT_SIZE, Size, NumberSize, Direction, NewSize } from "../types";
+import { DEFAULT_SIZE, Size, NumberSize, Direction, NewSize, ResizeEventType } from "../types";
 import { getStringSize, getNumberSize, has, calculateNewMax, findNextSnap, snap, clamp } from "../utils";
 export interface ResizableHandlerAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
     registerEvent: () => void;
@@ -16,9 +16,14 @@ export class ResizableHandlerFoundation<P = Record<string, any>, S = Record<stri
     }
 
     onMouseDown = (e: MouseEvent) => {
-        this.getProp('onResizeStart')(e, this.getProp('direction'));
+        this.getProp('onResizeStart')(e, this.getProp('direction'), 'mouse');
     };
 
+    onTouchStart = (e: TouchEvent) => {
+        const touch = e.targetTouches[0];
+        this.getProp('onResizeStart')(touch, this.getProp('direction'), 'touch');
+    }
+
     destroy(): void {
         this._adapter.unregisterEvent();
     }
@@ -26,8 +31,8 @@ export class ResizableHandlerFoundation<P = Record<string, any>, S = Record<stri
 
 export interface ResizableAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
     getResizable: () => HTMLDivElement | null;
-    registerEvent: () => void;
-    unregisterEvent: () => void
+    registerEvent: (type: ResizeEventType) => void;
+    unregisterEvent: (type: ResizeEventType) => void
 }
 
 export class ResizableFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ResizableAdapter<P, S>, P, S> {
@@ -53,6 +58,7 @@ export class ResizableFoundation<P = Record<string, any>, S = Record<string, any
     }
 
     flexDirection?: 'row' | 'column';
+    type?: ResizeEventType;
 
     lockAspectRatio = 1;
     resizable: HTMLElement | null = null;
@@ -202,11 +208,11 @@ export class ResizableFoundation<P = Record<string, any>, S = Record<string, any
     }
 
     registerEvents() {
-        this._adapter.registerEvent();
+        this._adapter.registerEvent(this.type);
     }
 
     unregisterEvents() {
-        this._adapter.unregisterEvent();
+        this._adapter.unregisterEvent(this.type);
     }
 
     getCssPropertySize(newSize: number | string, property: 'width' | 'height'): number | string {
@@ -380,7 +386,8 @@ export class ResizableFoundation<P = Record<string, any>, S = Record<string, any
     }
 
 
-    onResizeStart = (e: MouseEvent, direction: Direction) => {
+    onResizeStart = (e: MouseEvent, direction: Direction, type: ResizeEventType) => {
+        this.type = type;
         this.resizable = this._adapter.getResizable();
         if (!this.resizable || !this.window) {
             return;
@@ -456,6 +463,16 @@ export class ResizableFoundation<P = Record<string, any>, S = Record<string, any
 
 
     onMouseMove = (event: MouseEvent) => {
+        this.changePosition(event);
+    }
+
+    onTouchMove = (event: TouchEvent) => {
+        event.preventDefault();
+        const touch = event.targetTouches[0];
+        this.changePosition(touch);
+    }
+
+    changePosition = (event: Touch | MouseEvent) => {
         const states = this.getStates();
         const props = this.getProps();
 
@@ -583,7 +600,7 @@ export class ResizableFoundation<P = Record<string, any>, S = Record<string, any
     }
 
 
-    onMouseUp = (event: MouseEvent) => {
+    onMouseUp = (event: MouseEvent | TouchEvent) => {
         const { isResizing, direction, original } = this.getStates();
 
         if (!isResizing || !this.resizable) {

+ 6 - 3
packages/semi-foundation/resizable/types.ts

@@ -14,9 +14,12 @@ export interface HandleClassName {
     topLeft?: string
 }
 
+export type ResizeEventType = 'mouse' | 'touch'; 
+
 export type HandlerCallback = (
     e: MouseEvent,
-    direction: Direction
+    direction: Direction,
+    type?: ResizeEventType,
 ) => void;
 
 export interface Enable {
@@ -51,12 +54,12 @@ export const DEFAULT_SIZE = {
 
 export type ResizeCallback = (
     size: Size,
-    event: MouseEvent,
+    event: MouseEvent | TouchEvent,
     direction: Direction,
 ) => void;
 
 export type ResizeStartCallback = (
-    e: MouseEvent,
+    e: MouseEvent | Touch,
     dir: Direction,
 ) => void | boolean;
 

+ 3 - 0
packages/semi-foundation/select/select.scss

@@ -309,6 +309,9 @@ $overflowList: #{$prefix}-overflow-list;
 
         &-text {
             margin: $spacing-select_prefix_suffix_text-marginY $spacing-select_prefix_suffix_text-marginX;
+            color: $color-select_prefix_suffix_text-default;
+            @include font-size-regular;
+            font-weight: $font-weight-bold;
         }
 
         &-icon {

+ 2 - 0
packages/semi-foundation/select/variables.scss

@@ -59,6 +59,8 @@ $color-select_inset_label-text: var(--semi-color-text-2); // 分组选择器菜
 $color-select_create_tips-text: var(--semi-color-text-2); // 分组选择器菜单项提示文本颜色
 $color-select_group-text: var(--semi-color-text-2); // 分组选择器菜单项分组标题文本颜色
 
+$color-select_prefix_suffix_text-default: var(--semi-color-text-2); // 选择器输入框前后缀文本颜色
+
 // Width/Height
 $width-select_icon_right: ($width-icon-medium + $spacing-tight * 2); // 选择器右侧图标大小
 $height-select_large: $height-control-large; // 选择器输入框高度 - 大尺寸

+ 2 - 1
packages/semi-foundation/timePicker/ComboxFoundation.ts

@@ -145,7 +145,8 @@ class ComboboxFoundation extends BaseFoundation<DefaultAdapter> {
      */
 
     createDateDefault() {
-        return new Date(parseInt(String(Date.now() / DAY), 10) * DAY - 8 * HOUR);
+        const now = new Date();
+        return new Date(now.getFullYear(), now.getMonth(), now.getDate());
     }
 }
 

+ 3 - 0
packages/semi-foundation/treeSelect/treeSelect.scss

@@ -337,6 +337,9 @@ $module: #{$prefix}-tree-select;
         @include all-center;
 
         &-text {
+            color: $color-treeSelect_prefix_suffix_text-default;
+            font-weight: $font-weight-bold;
+            @include font-size-regular;
             margin: $spacing-treeSelect_prefix_text-marginY $spacing-treeSelect_prefix_text-marginX;
         }
 

+ 1 - 0
packages/semi-foundation/treeSelect/variables.scss

@@ -85,6 +85,7 @@ $color-treeSelect_inputTrigger-border-default: none; // 带搜索的树选择器
 $color-treeSelect_inputTrigger-bg-default: transparent; // 带搜索的树选择器触发器背景颜色
 $color-treeSelect_insertLabel-text-default: var(--semi-color-text-2); // 带搜索的树前缀标签文本颜色
 $font-treeSelect_insertLabel-fontWeight: 600; // 带搜索的树前缀标签文本字重
+$color-treeSelect_prefix_suffix_text-default: var(--semi-color-text-2); // 带搜索的树选择器前后缀文本颜色
 
 $width-treeSelect_arrow: 32px; // 树选择器展开箭头宽度
 $width-treeSelect_option:  230px; // 树选择器菜单项宽度

+ 2 - 2
packages/semi-icons-lab/package.json

@@ -50,8 +50,8 @@
     "ts-loader": "^5.4.5"
   },
   "peerDependencies": {
-    "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
-    "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+    "react": ">=16.0.0",
+    "react-dom": ">=16.0.0"
   },
   "_unpkg": true,
   "unpkgFiles": [

+ 1 - 1
packages/semi-icons/package.json

@@ -50,7 +50,7 @@
         "ts-loader": "^5.4.5"
     },
     "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+        "react": ">=16.0.0"
     },
     "_unpkg": true,
     "unpkgFiles": [

+ 1 - 1
packages/semi-illustrations/package.json

@@ -22,7 +22,7 @@
         "url": "https://github.com/DouyinFE/semi-design"
     },
     "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+        "react": ">=16.0.0"
     },
     "devDependencies": {
         "case-sensitive-paths-webpack-plugin": "2.4.0",

+ 31 - 10
packages/semi-ui/cascader/_story/cascader.stories.jsx

@@ -2398,14 +2398,6 @@ export const SearchInTopSlot = () => {
   );
 }
 
-export const suffix = () => {
-  return (<Cascader
-    suffix={<IconGift />}
-    style={{ width: 300 }}
-    treeData={treeData1}
-    placeholder="请选择所在地区"
-  />);
-}
 
 export const EmptyContent = () => {
   return (
@@ -2425,7 +2417,13 @@ export const EmptyContent = () => {
       placeholder="输入 v 查看搜索状态下 emptyContent 为 null 效果"
       filterTreeNode
     />
-    <br />
+    <br /><br />
+    <Cascader
+      style={{ width: 400 }}
+      treeData={[]}
+      placeholder="点击 trigger 查看默认 emptyContent 效果"
+      filterTreeNode
+    />
   </>)
 }
 
@@ -2496,4 +2494,27 @@ export const PlaceHolderChange = () => {
       />
     </div>
   )
-} 
+} 
+
+export const PrefixSuffix = () => {
+  return (
+    <>
+      <Cascader
+        prefix={<IconGift />}
+        suffix={<IconGift />}
+        style={{ width: 300 }}
+        treeData={treeData1}
+        placeholder="请选择所在地区"
+      />
+      <br /><br />
+      <Cascader
+        prefix={"Prefix"}
+        suffix={"Prefix"}
+        style={{ width: 300 }}
+        treeData={treeData2}
+        placeholder="请选择所在地区"
+        filterTreeNode
+      />
+    </>
+  )
+}

+ 11 - 1
packages/semi-ui/cascader/index.tsx

@@ -236,6 +236,7 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
     constructor(props: CascaderProps) {
         super(props);
         this.state = {
+            emptyContentMinWidth: null,
             disabledKeys: new Set(),
             isOpen: props.defaultOpen,
             /* By changing rePosKey, the dropdown position can be refreshed */
@@ -342,6 +343,13 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
             ...super.adapter,
             ...filterAdapter,
             ...cascaderAdapter,
+            setEmptyContentMinWidth: minWidth => {
+                this.setState({ emptyContentMinWidth: minWidth });
+            },
+            getTriggerWidth: () => {
+                const el = this.triggerRef.current;
+                return el && el.getBoundingClientRect().width;
+            },
             updateStates: states => {
                 this.setState({ ...states } as CascaderState);
             },
@@ -721,8 +729,10 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
         const searchable = Boolean(filterTreeNode) && isSearching;
         const popoverCls = cls(dropdownClassName, `${prefixcls}-popover`);
         const renderData = this.foundation.getRenderData();
+        const isEmpty = !renderData || !renderData.length;
+        const realDropDownStyle = isEmpty ? {...dropdownStyle, minWidth: this.state.emptyContentMinWidth } : dropdownStyle;
         const content = (
-            <div className={popoverCls} role="listbox" style={dropdownStyle} onKeyDown={this.foundation.handleKeyDown}>
+            <div className={popoverCls} role="listbox" style={realDropDownStyle} onKeyDown={this.foundation.handleKeyDown}>
                 {topSlot}
                 <Item
                     activeKeys={activeKeys}

+ 6 - 2
packages/semi-ui/form/baseForm.tsx

@@ -214,8 +214,12 @@ class Form<Values extends Record<string, any> = any> extends BaseComponent<BaseF
                     `form[x-form-id="${xId}"] .${cssClasses.PREFIX}-field-error-message`
                 );
             },
-            getFieldDOM: (field: string) =>
-                document.querySelector(`.${cssClasses.PREFIX}-field[x-field-id="${field}"]`),
+            getFieldDOM: (field: string) => {
+                const { formId } = this.state;
+                const { id } = this.props;
+                const xId = id ? id : formId;
+                return document.querySelector(`form[x-form-id="${xId}"] .${cssClasses.PREFIX}-field[x-field-id="${field}"]`);
+            },
             getFieldErrorDOM: (field: string) => {
                 const { formId } = this.state;
                 const { id } = this.props;

+ 5 - 0
packages/semi-ui/form/group.tsx

@@ -47,6 +47,11 @@ const GroupError = (props: GroupErrorProps) => {
 class FormInputGroup extends Component<InputGroupProps> {
     static contextType = FormUpdaterContext;
     context: FormUpdaterContextType;
+
+    static defaultProps = {
+        extraTextPosition: 'bottom'
+    }
+
     renderLabel(label: LabelProps, formProps: BaseFormProps) {
         if (label) {
             if (isString(label)) {

+ 3 - 0
packages/semi-ui/form/hoc/withField.tsx

@@ -219,6 +219,7 @@ function withField<
                     )
                     .then(res => {
                         if (isUnmounted.current || validatePromise.current !== rootPromise) {
+                            console.warn(`[Semi Form]: When FieldComponent (${field}) has an unfinished validation process, you repeatedly trigger a new validation, the old validation will be abandoned, and will neither resolve nor reject. Usually this is an unreasonable practice. Please check your code.`);
                             return;
                         }
                         // validation passed
@@ -228,6 +229,7 @@ function withField<
                     })
                     .catch(err => {
                         if (isUnmounted.current || validatePromise.current !== rootPromise) {
+                            console.warn(`[Semi Form]: When FieldComponent (${field}) has an unfinished validation process, you repeatedly trigger a new validation, the old validation will be abandoned, and will neither resolve nor reject. Usually this is an unreasonable practice. Please check your code.`);
                             return;
                         }
                         let { errors, fields } = err;
@@ -275,6 +277,7 @@ function withField<
                     maybePromisedErrors.then((result: any) => {
                         // If the async validate is outdated (a newer validate occurs), the result should be discarded
                         if (isUnmounted.current || validatePromise.current !== rootPromise) {
+                            console.warn(`[Semi Form]: When Field: (${field}) has an unfinished validation process, you repeatedly trigger a new validation, the old validation will be abandoned, and will neither resolve nor reject. Usually this is an unreasonable practice. Please check your code.`);
                             return;
                         }
 

+ 3 - 2
packages/semi-ui/jsonViewer/index.tsx

@@ -156,7 +156,7 @@ class JsonViewerCom extends BaseComponent<JsonViewerProps, JsonViewerState> {
 
     renderSearchBox() {
         return (
-            <div className={`${prefixCls}-search-bar-container`}>
+            <div className={`${prefixCls}-search-bar-container`} style={{ position: 'absolute', top: 20, right: 20 }}>
                 {this.renderSearchBar()}
                 {this.renderReplaceBar()}
             </div>
@@ -300,7 +300,7 @@ class JsonViewerCom extends BaseComponent<JsonViewerProps, JsonViewerState> {
                                 isDragging = true;
                             }}
                         >
-                            <div style={{ position: 'absolute', top: 20, left: width - 52 }}>
+                            <div style={{ position: 'absolute', top: 0, left: width }}>
                                 {!this.state.showSearchBar ? (
                                     <Button
                                         className={`${prefixCls}-search-bar-trigger`}
@@ -314,6 +314,7 @@ class JsonViewerCom extends BaseComponent<JsonViewerProps, JsonViewerState> {
                                             this.foundation.showSearchBar();
                                         }}
                                         icon={<IconSearch />}
+                                        style={{ position: 'absolute', top: 20, right: 20 }}
                                     />
                                 ) : (
                                     this.renderSearchBox()

+ 6 - 4
packages/semi-ui/navigation/Item.tsx

@@ -19,8 +19,7 @@ import NavContext, { NavContextType } from './nav-context';
 import Dropdown from '../dropdown';
 
 const clsPrefix = `${cssClasses.PREFIX}-item`;
-interface NavItemProps extends ItemProps, BaseProps {
-    children?: React.ReactNode;
+interface NavItemProps extends ItemProps, Omit<BaseProps, 'children'> {
     disabled?: boolean;
     forwardRef?: (ele: HTMLLIElement) => void;
     icon?: React.ReactNode;
@@ -57,7 +56,6 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
         onClick: PropTypes.func,
         onMouseEnter: PropTypes.func,
         onMouseLeave: PropTypes.func,
-        children: PropTypes.node,
         icon: PropTypes.oneOfType([PropTypes.node]),
         className: PropTypes.string,
         toggleIcon: PropTypes.string,
@@ -180,7 +178,6 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
     render() {
         const {
             text,
-            children,
             icon,
             toggleIcon,
             className,
@@ -204,6 +201,11 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
 
 
         let itemChildren = null;
+        // Children is not a recommended usage and may cause some bug-like performance, but some users have already used it, so here we only delete the ts definition instead of deleting the actual code
+        // children 并不是我们推荐的用法,可能会导致一些像 bug的表现,但是有些用户已经用了,所以此处仅作删除 ts 定义而非删除实际代码的操作
+        // refer https://github.com/DouyinFE/semi-design/issues/2710
+        // @ts-ignore
+        const children = this.props?.children;
         if (!isNullOrUndefined(children)) {
             itemChildren = children;
         } else {

+ 5 - 1
packages/semi-ui/navigation/SubNav.tsx

@@ -359,6 +359,10 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         }
 
         return (
+            // Children is not a recommended usage and may cause some bug-like performance, but some users have already used it, so here we only delete the ts definition instead of deleting the actual code
+            // children 并不是我们推荐的用法,可能会导致一些像 bug的表现,但是有些用户已经用了,所以此处仅作删除 ts 定义而非删除实际代码的操作
+            // refer https://github.com/DouyinFE/semi-design/issues/2710
+            // @ts-ignore    
             <NavItem
                 style={style}
                 isSubNav={true}
@@ -370,7 +374,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
                 onMouseLeave={onMouseLeave}
                 disabled={disabled}
                 text={text}
-            >
+            >   
                 <NavContext.Provider value={{ ...this.context, isInSubNav: true }}>
                     {titleDiv}
                     {subUl}

+ 39 - 0
packages/semi-ui/navigation/_story/navigation.stories.jsx

@@ -391,4 +391,43 @@ class DisabledSub extends React.Component {
 export const DisabledSubDemo = () => <DisabledSub></DisabledSub>
 DisabledSubDemo.story = {
   name: 'DisabledSubDemo'
+}
+
+
+export const renderWrapperDemo = () => {
+  return (
+    <Nav
+            renderWrapper={({ itemElement, isSubNav, isInSubNav, props }) => {
+                const routerMap = {
+                    Home: "/",
+                    About: "/about",
+                    Dashboard: "/dashboard",
+                    "Nothing Here": "/nothing-here"
+                };
+                return (
+                    <a
+                        style={{ textDecoration: "none" }}
+                        to={routerMap[props.itemKey]}
+                    >
+                      {itemElement}
+                    </a>
+                );
+            }}
+            items={[
+                { itemKey: "Home", text: "Home" },
+                { itemKey: "About", text: "About" },
+                {
+                    text: "Disabled",
+                    itemKey: "Disabled",
+                    disabled: true,
+                    items: ["Dashboard", "Nothing Here"]
+                },
+                {
+                  text: "Sub",
+                  itemKey: "Sub",
+                  items: [{ itemKey: "Dashboard", text: "Dashboard", items: ["Dashboard1", "Nothing Here1"] }, "Nothing Here"]
+              }
+            ]}
+    ></Nav>
+  )
 }

+ 13 - 3
packages/semi-ui/radio/_story/radio.stories.jsx

@@ -2,8 +2,8 @@ import React, { useState } from 'react';
 import Button from '../../button';
 import Space from '../../space';
 
-import { Radio, RadioGroup, Form, Tooltip } from '../../index';
-import { Row, Col } from '../../grid';
+import { Col, Row } from '../../grid';
+import { Form, Radio, RadioGroup, Tooltip } from '../../index';
 import './radio.scss';
 
 export default {
@@ -289,15 +289,25 @@ export const RadioGroupWithOptions = () => {
     { label: 'Orange', value: 'Orange', disabled: false },
   ];
 
+  const optionsWithAddonStyle = [
+    { label: 'Apple', value: 'Apple', addonStyle: { color: 'red' } },
+    { label: 'Pear', value: 'Pear' },
+    { label: 'Orange', value: 'Orange', disabled: true },
+  ];
+
   function onChange(event) {
     console.log(event);
   }
 
   return (
-    <div>
+    <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
       <RadioGroup name="apple" options={plainOptions} onChange={onChange} />
       <RadioGroup name="apple" options={options} onChange={onChange} />
       <RadioGroup name="apple" disabled options={optionsWithDisabled} onChange={onChange} />
+      <span>自定义样式</span>
+      <RadioGroup name="apple" options={optionsWithAddonStyle} onChange={onChange} />
+      <span>PureCard 自定义样式</span>
+      <RadioGroup type='pureCard' name="apple" options={optionsWithAddonStyle} onChange={onChange} />
     </div>
   );
 };

+ 13 - 5
packages/semi-ui/radio/radioGroup.tsx

@@ -1,16 +1,16 @@
-import React from 'react';
-import PropTypes from 'prop-types';
 import classnames from 'classnames';
 import { noop } from 'lodash';
+import PropTypes from 'prop-types';
+import React from 'react';
 
 import { radioGroupClasses as css, strings } from '@douyinfe/semi-foundation/radio/constants';
 import RadioGroupFoundation, { RadioGroupAdapter } from '@douyinfe/semi-foundation/radio/radioGroupFoundation';
 import { RadioChangeEvent } from '@douyinfe/semi-foundation/radio/radioInnerFoundation';
 
-import BaseComponent from '../_base/baseComponent';
 import { ArrayElement } from '../_base/base';
-import Radio, { RadioType } from './radio';
+import BaseComponent from '../_base/baseComponent';
 import Context, { RadioGroupButtonSize, RadioMode } from './context';
+import Radio, { RadioType } from './radio';
 
 export interface OptionItem {
     label?: React.ReactNode;
@@ -18,7 +18,11 @@ export interface OptionItem {
     disabled?: boolean;
     extra?: React.ReactNode;
     style?: React.CSSProperties;
-    className?: string
+    className?: string;
+    addonId?: string;
+    addonStyle?: React.CSSProperties;
+    addonClassName?: string;
+    extraId?: string
 }
 export type Options = string[] | Array<OptionItem>;
 
@@ -191,6 +195,10 @@ class RadioGroup extends BaseComponent<RadioGroupProps, RadioGroupState> {
                             extra={option.extra}
                             className={option.className}
                             style={option.style}
+                            addonId={option.addonId}
+                            addonStyle={option.addonStyle}
+                            addonClassName={option.addonClassName}
+                            extraId={option.extraId}
                         >
                             {option.label}
                         </Radio>

+ 2 - 2
packages/semi-ui/resizable/group/resizeContext.ts

@@ -1,5 +1,5 @@
 import React, { createContext, RefObject } from 'react';
-import { ResizeCallback, ResizeStartCallback } from '@douyinfe/semi-foundation/resizable/types';
+import { ResizeCallback, ResizeEventType, ResizeStartCallback } from '@douyinfe/semi-foundation/resizable/types';
 
 export interface ResizeContextProps {
     direction: 'horizontal' | 'vertical';
@@ -10,7 +10,7 @@ export interface ResizeContextProps {
         onResizeEnd: ResizeCallback
     ) => number;
     registerHandler: (ref: RefObject<HTMLDivElement>) => number;
-    notifyResizeStart: (handlerIndex: number, e: MouseEvent) => void;
+    notifyResizeStart: (handlerIndex: number, e: MouseEvent | Touch, type: ResizeEventType) => void;
     getGroupSize: () => number
 }
 

+ 21 - 9
packages/semi-ui/resizable/group/resizeGroup.tsx

@@ -5,7 +5,7 @@ import { ResizeGroupFoundation, ResizeGroupAdapter } from '@douyinfe/semi-founda
 import { cssClasses } from '@douyinfe/semi-foundation/resizable/constants';
 import BaseComponent from '../../_base/baseComponent';
 import { ResizeContext, ResizeContextProps } from './resizeContext';
-import { ResizeCallback, ResizeStartCallback } from '@douyinfe/semi-foundation/resizable/types';
+import { ResizeCallback, ResizeEventType, ResizeStartCallback } from '@douyinfe/semi-foundation/resizable/types';
 import "@douyinfe/semi-foundation/resizable/resizable.scss";
 
 const prefixCls = cssClasses.PREFIX;
@@ -145,19 +145,31 @@ class ResizeGroup extends BaseComponent<ResizeGroupProps, ResizeGroupState> {
         return this.groupRef.current.ownerDocument.defaultView as Window ?? null;
     }
 
-    registerEvent = () => {
+    registerEvent = (type: ResizeEventType = 'mouse') => {
         if (this.window) {
-            this.window.addEventListener('mousemove', this.foundation.onResizing);
-            this.window.addEventListener('mouseup', this.foundation.onResizeEnd);
-            this.window.addEventListener('mouseleave', this.foundation.onResizeEnd);
+            if (type === 'mouse') {
+                this.window.addEventListener('mousemove', this.foundation.onMouseMove);
+                this.window.addEventListener('mouseup', this.foundation.onResizeEnd);
+                this.window.addEventListener('mouseleave', this.foundation.onResizeEnd);
+            } else {
+                this.window.addEventListener('touchmove', this.foundation.onTouchMove, { passive: false });
+                this.window.addEventListener('touchend', this.foundation.onResizeEnd);
+                this.window.addEventListener('touchcancel', this.foundation.onResizeEnd);
+            } 
         }
     }
 
-    unregisterEvent = () => {
+    unregisterEvent = (type: ResizeEventType = 'mouse') => {
         if (this.window) {
-            this.window.removeEventListener('mousemove', this.foundation.onResizing);
-            this.window.removeEventListener('mouseup', this.foundation.onResizeEnd);
-            this.window.removeEventListener('mouseleave', this.foundation.onResizeEnd);
+            if (type === 'mouse') {
+                this.window.removeEventListener('mousemove', this.foundation.onMouseMove);
+                this.window.removeEventListener('mouseup', this.foundation.onResizeEnd);
+                this.window.removeEventListener('mouseleave', this.foundation.onResizeEnd);
+            } else {
+                this.window.removeEventListener('touchmove', this.foundation.onTouchMove, { passive: false } as any);
+                this.window.removeEventListener('touchend', this.foundation.onResizeEnd);
+                this.window.removeEventListener('touchcancel', this.foundation.onResizeEnd);
+            }
         }
     }
 

+ 8 - 1
packages/semi-ui/resizable/group/resizeHandler.tsx

@@ -62,7 +62,12 @@ class ResizeHandler extends BaseComponent<ResizeHandlerProps, ResizeHandlerState
     foundation: ResizeHandlerFoundation;
     onMouseDown = (e: MouseEvent) => {
         const { notifyResizeStart } = this.context;
-        notifyResizeStart(this.handlerIndex, e);
+        notifyResizeStart(this.handlerIndex, e, 'mouse');
+    }
+
+    onTouchStart = (e: TouchEvent) => {
+        const { notifyResizeStart } = this.context;
+        notifyResizeStart(this.handlerIndex, e.targetTouches[0], 'touch');
     }
     
     get adapter(): ResizeHandlerAdapter<ResizeHandlerProps, ResizeHandlerState> {
@@ -70,9 +75,11 @@ class ResizeHandler extends BaseComponent<ResizeHandlerProps, ResizeHandlerState
             ...super.adapter,
             registerEvents: () => {
                 this.handlerRef.current.addEventListener('mousedown', this.onMouseDown);
+                this.handlerRef.current.addEventListener('touchstart', this.onTouchStart);
             },
             unregisterEvents: () => {
                 this.handlerRef.current.removeEventListener('mousedown', this.onMouseDown);
+                this.handlerRef.current.removeEventListener('touchstart', this.onTouchStart);
             },
         };
     }

+ 20 - 8
packages/semi-ui/resizable/single/resizable.tsx

@@ -185,17 +185,29 @@ class Resizable extends BaseComponent<ResizableProps, ResizableState> {
         return {
             ...super.adapter,
             getResizable: this.getResizable,
-            registerEvent: () => {
+            registerEvent: (type = 'mouse') => {
                 let window = this.foundation.window;
-                window?.addEventListener('mouseup', this.foundation.onMouseUp);
-                window?.addEventListener('mousemove', this.foundation.onMouseMove);
-                window?.addEventListener('mouseleave', this.foundation.onMouseUp);
+                if (type === 'mouse') {
+                    window?.addEventListener('mouseup', this.foundation.onMouseUp);
+                    window?.addEventListener('mousemove', this.foundation.onMouseMove);
+                    window?.addEventListener('mouseleave', this.foundation.onMouseUp);
+                } else {
+                    window?.addEventListener('touchmove', this.foundation.onTouchMove, { passive: false });
+                    window?.addEventListener('touchend', this.foundation.onMouseUp);
+                    window?.addEventListener('touchcancel', this.foundation.onMouseUp);
+                }
             },
-            unregisterEvent: () => {
+            unregisterEvent: (type = 'mouse') => {
                 let window = this.foundation.window;
-                window?.removeEventListener('mouseup', this.foundation.onMouseUp);
-                window?.removeEventListener('mousemove', this.foundation.onMouseMove);
-                window?.removeEventListener('mouseleave', this.foundation.onMouseUp);
+                if (type === 'mouse') {
+                    window?.removeEventListener('mouseup', this.foundation.onMouseUp);
+                    window?.removeEventListener('mousemove', this.foundation.onMouseMove);
+                    window?.removeEventListener('mouseleave', this.foundation.onMouseUp);
+                } else {
+                    window?.removeEventListener('touchmove', this.foundation.onTouchMove, { passive: false } as any);
+                    window?.removeEventListener('touchend', this.foundation.onMouseUp);
+                    window?.removeEventListener('touchcancel', this.foundation.onMouseUp);
+                }
             },
         };
     }

+ 2 - 0
packages/semi-ui/resizable/single/resizableHandler.tsx

@@ -62,9 +62,11 @@ class ResizableHandler extends BaseComponent<ResizableHandlerProps, ResizableHan
             ...super.adapter,
             registerEvent: () => {
                 this.resizeHandlerRef.current.addEventListener('mousedown', this.foundation.onMouseDown);
+                this.resizeHandlerRef.current.addEventListener('touchstart', this.foundation.onTouchStart);
             },
             unregisterEvent: () => {
                 this.resizeHandlerRef.current.removeEventListener('mousedown', this.foundation.onMouseDown);
+                this.resizeHandlerRef.current.removeEventListener('touchstart', this.foundation.onTouchStart);
             },
         };
     }

+ 3 - 1
packages/semi-ui/scrollList/scrollItem.tsx

@@ -446,8 +446,10 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
                     key={prefixKey + index}
                     {...events}
                     className={cls}
+                    // eslint-disable-next-line jsx-a11y/role-has-required-aria-props
                     role="option"
-                    aria-selected={selected}
+                    // 
+                    // aria-selected={selected}
                     aria-disabled={item.disabled}
                 >
                     {text}

+ 10 - 0
packages/semi-ui/select/_story/select.stories.jsx

@@ -402,6 +402,16 @@ export const WithPrefixSuffixInsetLabelShowClearShowArrow = () => (
       prefix={<IconSearch />}
       suffix={<IconGift></IconGift>}
     ></Select>
+    <Select
+      style={{
+        width: '250px',
+      }}
+      motion={false}
+      filter
+      optionList={options}
+      prefix={"Prefix"}
+      suffix={"Suffix"}
+    ></Select>
     <h4>insetLabel</h4>
     <Select
       style={{

+ 1 - 1
packages/semi-ui/treeSelect/_story/treeSelect.stories.jsx

@@ -567,7 +567,7 @@ export const PrefixSuffixInsetLabel = () => (
       dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
       treeData={treeData2}
       filterTreeNode
-      prefix={<span>1234</span>}
+      prefix={'1234'}
       treeNodeFilterProp="value"
       placeholder="Please select"
     />

+ 2 - 5
packages/semi-ui/typography/util.tsx

@@ -78,11 +78,8 @@ const getRenderText = (
     ellipsisContainer.style.textOverflow = 'clip';
     ellipsisContainer.style.webkitLineClamp = 'none';
 
-    // Render fake container
-    ReactDOM.render(
-        <></>,
-        ellipsisContainer
-    );
+    // Clear container content
+    ellipsisContainer.innerHTML = '';
 
     // Check if ellipsis in measure div is enough for content
     function inRange() {