-
{html}
-
{
- this.container = ref;
- }}
- >
-
{
- this.view = ref;
- }}
- />
-
-
-
- {
- addStyle(this.view, {
- 'font-size': '16px',
- color: '#F00'
- });
- this.showView();
- }}
- >
- addStyle
-
-
- {
- removeStyle(this.view, ['font-size', 'color']);
- this.showView();
- }}
- >
- removeStyle
-
-
- {
- console.log(getStyle(this.view));
- alert(getStyle(this.view, 'font-size'));
- }}
- >
- getStyle
-
-
-
- );
- }
-}
-
-ReactDOM.render(
);
-```
-
-
diff --git a/docs/pages/components/dom-helper/fragments/class-helper.md b/docs/pages/components/dom-helper/fragments/class-helper.md
new file mode 100644
index 000000000..821a2dcc8
--- /dev/null
+++ b/docs/pages/components/dom-helper/fragments/class-helper.md
@@ -0,0 +1,60 @@
+
+
+```js
+const App = () => {
+ const [html, setHtml] = React.useState('
');
+ const containerRef = React.useRef();
+ const viewRef = React.useRef();
+ const viewHtmlCode = () => {
+ setHtml(containerRef.current.innerHTML);
+ };
+ return (
+
+
{html}
+
+
+
+ {
+ addClass(viewRef.current, 'custom');
+ viewHtmlCode();
+ }}
+ >
+ addClass
+
+
+ {
+ removeClass(viewRef.current, 'custom');
+ viewHtmlCode();
+ }}
+ >
+ removeClass
+
+
+ {
+ toggleClass(viewRef.current, 'custom');
+ viewHtmlCode();
+ }}
+ >
+ toggleClass
+
+ {
+ alert(hasClass(viewRef.current, 'custom'));
+ }}
+ >
+ hasClass
+
+
+
+ );
+};
+
+ReactDOM.render(
);
+```
+
+
diff --git a/docs/pages/components/dom-helper/fragments/dom-mouse-move-tracker.md b/docs/pages/components/dom-helper/fragments/dom-mouse-move-tracker.md
new file mode 100644
index 000000000..acb7cbf68
--- /dev/null
+++ b/docs/pages/components/dom-helper/fragments/dom-mouse-move-tracker.md
@@ -0,0 +1,47 @@
+
+
+```js
+const App = () => {
+ const [left, setLeft] = React.useState(0);
+ const [top, setTop] = React.useState(0);
+
+ const mouseMoveTracker = React.useRef();
+
+ const onMove = React.useCallback((deltaX, deltaY) => {
+ setLeft(x => x + deltaX);
+ setTop(y => y + deltaY);
+ }, []);
+
+ const onMoveEnd = React.useCallback(() => {
+ if (mouseMoveTracker.current) {
+ mouseMoveTracker.current.releaseMouseMoves();
+ }
+ }, []);
+
+ const getMouseMoveTracker = React.useCallback(() => {
+ return mouseMoveTracker.current || new DOMMouseMoveTracker(onMove, onMoveEnd, document.body);
+ }, []);
+
+ const handleMouseDown = React.useCallback(event => {
+ mouseMoveTracker.current = getMouseMoveTracker();
+ mouseMoveTracker.current.captureMouseMoves(event);
+ }, []);
+
+ return (
+
+ {left}, {top}
+
+ Drag me
+
+
+ );
+};
+
+ReactDOM.render(
);
+```
+
+
diff --git a/docs/pages/components/dom-helper/fragments/event-helper.md b/docs/pages/components/dom-helper/fragments/event-helper.md
new file mode 100644
index 000000000..1865bf687
--- /dev/null
+++ b/docs/pages/components/dom-helper/fragments/event-helper.md
@@ -0,0 +1,39 @@
+
+
+```js
+const App = () => {
+ const btnRef = React.useRef();
+ const listenerRef = React.useRef();
+
+ const handleOnEvent = () => {
+ if (!listenerRef.current) {
+ listenerRef.current = on(btnRef.current, 'click', () => {
+ alert('click');
+ });
+ }
+ };
+
+ const handleOffEvent = () => {
+ if (listenerRef.current) {
+ listenerRef.current.off();
+ listenerRef.current = null;
+ }
+ };
+
+ return (
+
+
+ click me
+
+
+
+ on
+ off
+
+
+ );
+};
+ReactDOM.render(
);
+```
+
+
diff --git a/docs/pages/components/dom-helper/fragments/import.md b/docs/pages/components/dom-helper/fragments/import.md
new file mode 100644
index 000000000..bb4089cfa
--- /dev/null
+++ b/docs/pages/components/dom-helper/fragments/import.md
@@ -0,0 +1,6 @@
+```js
+import { DOMHelper } from 'rsuite';
+
+// or
+import DOMHelper from 'rsuite/lib/DOMHelper';
+```
diff --git a/docs/pages/components/dom-helper/fragments/query.md b/docs/pages/components/dom-helper/fragments/query.md
new file mode 100644
index 000000000..aed1869c0
--- /dev/null
+++ b/docs/pages/components/dom-helper/fragments/query.md
@@ -0,0 +1,41 @@
+
+
+```js
+const App = () => {
+ const nodeRef = React.useRef();
+ return (
+
+
Node
+
+ {
+ alert(JSON.stringify(getOffset(nodeRef.current)));
+ }}
+ >
+ getOffset
+
+
+ {
+ alert(getOffsetParent(nodeRef.current));
+ }}
+ >
+ getOffsetParent
+
+
+ {
+ alert(JSON.stringify(getPosition(nodeRef.current)));
+ }}
+ >
+ getPosition
+
+
+
+ );
+};
+
+ReactDOM.render(
);
+```
+
+
diff --git a/docs/pages/components/dom-helper/fragments/scroll-helper.md b/docs/pages/components/dom-helper/fragments/scroll-helper.md
new file mode 100644
index 000000000..3d40a1b9f
--- /dev/null
+++ b/docs/pages/components/dom-helper/fragments/scroll-helper.md
@@ -0,0 +1,31 @@
+
+
+```js
+const App = () => {
+ return (
+
+
+ {
+ scrollTop(window, 1500);
+ }}
+ >
+ scrollTop 1500
+
+
+ {
+ alert(scrollTop(window));
+ }}
+ >
+ get scrollTop
+
+
+
+ );
+};
+
+ReactDOM.render(
);
+```
+
+
diff --git a/docs/pages/components/dom-helper/fragments/style-helper.md b/docs/pages/components/dom-helper/fragments/style-helper.md
new file mode 100644
index 000000000..5cd1af6f2
--- /dev/null
+++ b/docs/pages/components/dom-helper/fragments/style-helper.md
@@ -0,0 +1,57 @@
+
+
+```js
+const App = () => {
+ const [html, setHtml] = React.useState('
');
+ const containerRef = React.useRef();
+ const viewRef = React.useRef();
+
+ const viewHtmlCode = () => {
+ setHtml(containerRef.current.innerHTML);
+ };
+ return (
+
+
{html}
+
+
+
+ {
+ addStyle(viewRef.current, {
+ 'font-size': '16px',
+ color: '#F00'
+ });
+ viewHtmlCode();
+ }}
+ >
+ addStyle
+
+
+ {
+ removeStyle(viewRef.current, ['font-size', 'color']);
+ viewHtmlCode();
+ }}
+ >
+ removeStyle
+
+
+ {
+ console.log(getStyle(viewRef.current));
+ alert(getStyle(viewRef.current, 'font-size'));
+ }}
+ >
+ getStyle
+
+
+
+ );
+};
+
+ReactDOM.render(
);
+```
+
+
diff --git a/docs/pages/components/dom-helper/index.tsx b/docs/pages/components/dom-helper/index.tsx
index e3dd6cbf0..9a98221fa 100644
--- a/docs/pages/components/dom-helper/index.tsx
+++ b/docs/pages/components/dom-helper/index.tsx
@@ -3,17 +3,5 @@ import { ButtonToolbar, Button, DOMHelper } from 'rsuite';
import DefaultPage from '@/components/Page';
export default function Page() {
- return (
-
- );
+ return
;
}
diff --git a/docs/pages/components/dom-helper/zh-CN/class-helper.md b/docs/pages/components/dom-helper/zh-CN/class-helper.md
deleted file mode 100644
index 6dd2311ed..000000000
--- a/docs/pages/components/dom-helper/zh-CN/class-helper.md
+++ /dev/null
@@ -1,85 +0,0 @@
-### class
-
-```typescript
-hasClass: (node: HTMLElement, className: string) => boolean;
-addClass: (node: HTMLElement, className: string) => HTMLElement;
-removeClass: (node: HTMLElement, className: string) => HTMLElement;
-toggleClass: (node: HTMLElement, className: string) => HTMLElement;
-```
-
-
-
-```js
-class Demo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- html: '
'
- };
- }
- showView() {
- const html = this.container.innerHTML;
- this.setState({ html });
- }
- render() {
- const { html } = this.state;
- return (
-
-
{html}
-
{
- this.container = ref;
- }}
- >
-
{
- this.view = ref;
- }}
- />
-
-
-
- {
- addClass(this.view, 'custom');
- this.showView();
- }}
- >
- addClass
-
-
- {
- removeClass(this.view, 'custom');
- this.showView();
- }}
- >
- removeClass
-
-
- {
- toggleClass(this.view, 'custom');
- this.showView();
- }}
- >
- toggleClass
-
- {
- alert(hasClass(this.view, 'custom'));
- }}
- >
- hasClass
-
-
-
- );
- }
-}
-
-ReactDOM.render(
);
-```
-
-
diff --git a/docs/pages/components/dom-helper/zh-CN/dom-mouse-move-tracker.md b/docs/pages/components/dom-helper/zh-CN/dom-mouse-move-tracker.md
deleted file mode 100644
index 3b288e39c..000000000
--- a/docs/pages/components/dom-helper/zh-CN/dom-mouse-move-tracker.md
+++ /dev/null
@@ -1,76 +0,0 @@
-### DOMMouseMoveTracker
-
-鼠标拖拽跟踪器
-
-```typescript
-new DOMMouseMoveTracker(
- onMove:(deltaX: number, deltaY: number, moveEvent: Object) => void,
- onMoveEnd:() => void,
- node: HTMLElement
-);
-```
-
-
-
-```js
-class Demo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- left: 0,
- top: 0
- };
- this.onMove = this.onMove.bind(this);
- this.onMoveEnd = this.onMoveEnd.bind(this);
- this.handleMouseDown = this.handleMouseDown.bind(this);
- }
- onMove(deltaX: number, deltaY: number) {
- const { left, top } = this.state;
- this.setState({
- left: left + deltaX,
- top: top + deltaY
- });
- }
- onMoveEnd() {
- if (this.mouseMoveTracker) {
- this.mouseMoveTracker.releaseMouseMoves();
- }
- }
- getMouseMoveTracker() {
- return (
- this.mouseMoveTracker || new DOMMouseMoveTracker(this.onMove, this.onMoveEnd, document.body)
- );
- }
- handleMouseDown(event) {
- this.mouseMoveTracker = this.getMouseMoveTracker();
- this.mouseMoveTracker.captureMouseMoves(event);
- }
- render() {
- const { left, top } = this.state;
- return (
-
- {left}, {top}
-
- Drag me
-
-
- );
- }
-}
-
-ReactDOM.render(
);
-```
-
-
diff --git a/docs/pages/components/dom-helper/zh-CN/event-helper.md b/docs/pages/components/dom-helper/zh-CN/event-helper.md
deleted file mode 100644
index 63407c1ff..000000000
--- a/docs/pages/components/dom-helper/zh-CN/event-helper.md
+++ /dev/null
@@ -1,55 +0,0 @@
-### events
-
-```typescript
-on: (target: HTMLElement, eventName: string, listener: Function, capture: boolean = false) => {off: Function};
-off: (target: HTMLElement, eventName: string, listener: Function, capture: boolean = false) => void;
-```
-
-
-
-```js
-class Demo extends React.Component {
- constructor(props) {
- super(props);
- this.handleOnEvent = this.handleOnEvent.bind(this);
- this.handleOffEvent = this.handleOffEvent.bind(this);
- }
- handleOnEvent() {
- if (!this.listener) {
- this.listener = on(this.btn, 'click', () => {
- alert('click');
- });
- }
- }
- handleOffEvent() {
- if (this.listener) {
- this.listener.off();
- this.listener = null;
- }
- }
- render() {
- return (
-
-
- {
- this.btn = ref;
- }}
- >
- click me
-
-
-
-
- on
- off
-
-
- );
- }
-}
-
-ReactDOM.render(
);
-```
-
-
diff --git a/docs/pages/components/dom-helper/zh-CN/index.md b/docs/pages/components/dom-helper/zh-CN/index.md
index d68d83ceb..47d6d98a4 100644
--- a/docs/pages/components/dom-helper/zh-CN/index.md
+++ b/docs/pages/components/dom-helper/zh-CN/index.md
@@ -2,14 +2,89 @@
在 React 项目中,我们不推荐直接操作 DOM , 但是在 RSUITE 组件内部,为了一些考虑不得不直接操作 DOM, 如果您也有类似的需求,可以直接使用这组方法。
-获取方法
+## 获取方法
-```js
-import { DOMHelper } from 'rsuite';
-const { addClass } = DOMHelper;
+
+
+## APIs
+
+### class
+
+```typescript
+hasClass: (node: HTMLElement, className: string) => boolean;
+addClass: (node: HTMLElement, className: string) => HTMLElement;
+removeClass: (node: HTMLElement, className: string) => HTMLElement;
+toggleClass: (node: HTMLElement, className: string) => HTMLElement;
+```
+
+
+
+### style
+
+```typescript
+addStyle: (node: HTMLElement, property: string, value: string) => void;
+addStyle: (node: HTMLElement, style: Object) => void;
+
+removeStyle: (node: HTMLElement, property: string) => void;
+removeStyle: (node: HTMLElement, propertys: Array
) => void;
+
+getStyle: (node: HTMLElement, property: string) => string;
+getStyle: (node: HTMLElement) => Object;
+
+
+translateDOMPositionXY: (style: Object, x: number, y: number) => Object;
+
+```
+
+
+
+### events
+
+```typescript
+on: (target: HTMLElement, eventName: string, listener: Function, capture: boolean = false) => {off: Function};
+off: (target: HTMLElement, eventName: string, listener: Function, capture: boolean = false) => void;
+```
+
+
+
+### scroll
+
+```typescript
+scrollLeft: (node: HTMLElement) => number;
+scrollLeft: (node: HTMLElement, value: number) => void;
+
+scrollTop: (node: HTMLElement) => number;
+scrollTop: (node: HTMLElement, value: number) => void;
+```
+
+
+
+### query
+
+```typescript
+getHeight: (node: HTMLElement, client: HTMLElement) => number;
+getWidth: (node: HTMLElement, client: HTMLElement) => number;
+getOffset: (node: HTMLElement) => Object;
+getOffsetParent: (node: HTMLElement) => HTMLElement;
+getPosition: (node: HTMLElement, offsetParent: HTMLElement) => Object;
+contains: (context: HTMLElement, node: HTMLElement) => boolean;
+```
+
+
+
+### DOMMouseMoveTracker
+
+Mouse drag tracker
+
+```typescript
+new DOMMouseMoveTracker(
+ onMove:(deltaX: number, deltaY: number, moveEvent: Object) => void,
+ onMoveEnd:() => void,
+ node: HTMLElement
+);
```
-
+
### 参考及使用的项目
diff --git a/docs/pages/components/dom-helper/zh-CN/query.md b/docs/pages/components/dom-helper/zh-CN/query.md
deleted file mode 100644
index 24aa4e300..000000000
--- a/docs/pages/components/dom-helper/zh-CN/query.md
+++ /dev/null
@@ -1,53 +0,0 @@
-### query
-
-```typescript
-getHeight: (node: HTMLElement, client: HTMLElement) => number;
-getWidth: (node: HTMLElement, client: HTMLElement) => number;
-getOffset: (node: HTMLElement) => Object;
-getOffsetParent: (node: HTMLElement) => HTMLElement;
-getPosition: (node: HTMLElement, offsetParent: HTMLElement) => Object;
-contains: (context: HTMLElement, node: HTMLElement) => boolean;
-```
-
-
-
-```js
-class Demo extends React.Component {
- render() {
- return (
-
-
(this.node = ref)}>Node
-
- {
- alert(JSON.stringify(getOffset(this.node)));
- }}
- >
- getOffset
-
-
- {
- alert(getOffsetParent(this.node));
- }}
- >
- getOffsetParent
-
-
- {
- alert(JSON.stringify(getPosition(this.node)));
- }}
- >
- getPosition
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/dom-helper/zh-CN/scroll-helper.md b/docs/pages/components/dom-helper/zh-CN/scroll-helper.md
deleted file mode 100644
index 231f9ace2..000000000
--- a/docs/pages/components/dom-helper/zh-CN/scroll-helper.md
+++ /dev/null
@@ -1,43 +0,0 @@
-### scroll
-
-```typescript
-scrollLeft: (node: HTMLElement) => number;
-scrollLeft: (node: HTMLElement, value: number) => void;
-
-scrollTop: (node: HTMLElement) => number;
-scrollTop: (node: HTMLElement, value: number) => void;
-```
-
-
-
-```js
-class Demo extends React.Component {
- render() {
- return (
-
-
- {
- scrollTop(window, 1500);
- }}
- >
- scrollTop 1500
-
-
- {
- alert(scrollTop(window));
- }}
- >
- get scrollTop
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/dom-helper/zh-CN/style-helper.md b/docs/pages/components/dom-helper/zh-CN/style-helper.md
deleted file mode 100644
index 265a2036b..000000000
--- a/docs/pages/components/dom-helper/zh-CN/style-helper.md
+++ /dev/null
@@ -1,89 +0,0 @@
-### style
-
-```typescript
-addStyle: (node: HTMLElement, property: string, value: string) => void;
-addStyle: (node: HTMLElement, style: Object) => void;
-
-removeStyle: (node: HTMLElement, property: string) => void;
-removeStyle: (node: HTMLElement, propertys: Array) => void;
-
-getStyle: (node: HTMLElement, property: string) => string;
-getStyle: (node: HTMLElement) => Object;
-
-
-translateDOMPositionXY: (style: Object, x: number, y: number) => Object;
-
-```
-
-
-
-```js
-class Demo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- html: '
'
- };
- }
- showView() {
- const html = this.container.innerHTML;
- this.setState({ html });
- }
- render() {
- const { html } = this.state;
- return (
-
-
{html}
-
{
- this.container = ref;
- }}
- >
-
{
- this.view = ref;
- }}
- />
-
-
-
- {
- addStyle(this.view, {
- 'font-size': '16px',
- color: '#F00'
- });
- this.showView();
- }}
- >
- addStyle
-
-
- {
- removeStyle(this.view, ['font-size', 'color']);
- this.showView();
- }}
- >
- removeStyle
-
-
- {
- console.log(getStyle(this.view));
- alert(getStyle(this.view, 'font-size'));
- }}
- >
- getStyle
-
-
-
- );
- }
-}
-
-ReactDOM.render(
);
-```
-
-
diff --git a/docs/pages/components/form/en-US/custom-check-trigger.md b/docs/pages/components/form/en-US/custom-check-trigger.md
deleted file mode 100644
index 47c71a7d3..000000000
--- a/docs/pages/components/form/en-US/custom-check-trigger.md
+++ /dev/null
@@ -1,100 +0,0 @@
-### Custom trigger verification
-
-In some cases, there is no need for real-time validation of the form data. You can customize the way the control is validated and configure the `checkTrigger` parameter.
-
-The default value of `checkTrigger` is `'change'`, options includes:
-
-- `'change'` : trigger verification when data change
-- `'blur'` : trigger verification when component blur
-- `'none'` : Only valid when calling the `check()` method of `
` components. You can define the entire form's validation method in ``.
-
-
-
-```js
-const model = Schema.Model({
- name: Schema.Types.StringType()
- .isEmail('Please enter a valid email address.')
- .isRequired('This field is required.')
-});
-class CustomField extends React.PureComponent {
- render() {
- const { name, message, label, accepter, error, ...props } = this.props;
- return (
-
- {label}
-
- {message}
-
- );
- }
-}
-
-class CustomCheckForm extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- checkTrigger: 'change',
- formValue: {},
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
-
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- console.error('Form Error');
- return;
- }
- console.log(formValue, 'Form Value');
- }
-
- render() {
- const { formError, formValue, checkTrigger } = this.state;
- return (
-
-
- checkTrigger:
- {
- this.setState({
- checkTrigger,
- formError: {}
- });
- }}
- >
- blur
- change
- none
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/en-US/custom-form-control.md b/docs/pages/components/form/en-US/custom-form-control.md
deleted file mode 100644
index c67f227ff..000000000
--- a/docs/pages/components/form/en-US/custom-form-control.md
+++ /dev/null
@@ -1,161 +0,0 @@
-### Custom Form.Control
-
-All Data Entry-related components can be used in forms such as `Checkbox`, `SelectPicker`, `Slider`, and so on. But you need to use the `Form.Control` component for data management and data association with the `Form` component.
-
-- `Form.Control` used to bind data fields in a Form, passing the `name` attribute to the `key` of the Schema.Model object.
-- `Form.Control` the default is an `Input` component, which can be set through the ʻaccepter` component.
-
-
-
-```js
-const { ArrayType, StringType, NumberType } = Schema.Types;
-const model = Schema.Model({
- skills: ArrayType()
- .minLength(2, 'Please select at least 2 types of Skills.')
- .isRequired('This field is required.'),
- status: ArrayType()
- .minLength(2, 'Please select at least 2 types of Status.')
- .isRequired('This field is required.'),
- level: NumberType().min(5, 'This field must be greater than 5')
-});
-
-class CustomField extends React.PureComponent {
- render() {
- const { name, message, label, accepter, error, ...props } = this.props;
- return (
-
- {label}
-
- {message}
-
- );
- }
-}
-
-class CustomFieldForm extends React.Component {
- constructor(props) {
- super(props);
- const formValue = {
- number: 10,
- skills: ['Node.js'],
- browser: 'Chrome',
- status: ['open'],
- level: 1,
- level2: 1,
- createDate: new Date()
- };
- this.state = {
- formValue: formValue,
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- Alert.error('Error');
- return;
- }
- Alert.success('Success');
- }
- render() {
- const { formError, formValue } = this.state;
-
- return (
-
-
-
-
- Submit
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-> For example: ` ` , Form.Control renders a `` component and binds to the Schema.Model instance in the Form. The rich text editor in the following example, using [react-quill](https://github.com/zenoamaro/react-quill)
diff --git a/docs/pages/components/form/en-US/custom-third-party-libraries.md b/docs/pages/components/form/en-US/custom-third-party-libraries.md
deleted file mode 100644
index 2f49ace83..000000000
--- a/docs/pages/components/form/en-US/custom-third-party-libraries.md
+++ /dev/null
@@ -1,114 +0,0 @@
-### Third-Party Libraries
-
-Take [text-mask](https://github.com/text-mask/text-mask) as an example:
-
-
-
-```js
-const { ArrayType, StringType } = Schema.Types;
-const model = Schema.Model({
- phone: StringType().isRequired('This field is required.')
-});
-
-const InputMask = ({ onChange, ...rest }) => {
- return (
- {
- onChange(event.target.value);
- }}
- />
- );
-};
-
-class CustomField extends React.PureComponent {
- render() {
- const { name, message, label, accepter, error, ...props } = this.props;
- return (
-
- {label}
-
- {message}
-
- );
- }
-}
-
-class CustomFieldForm extends React.Component {
- constructor(props) {
- super(props);
- const formValue = {
- phone: ''
- };
- this.state = {
- formValue: formValue,
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- Alert.error('Error');
- return;
- }
- Alert.success('Success');
- }
- render() {
- const { formError, formValue } = this.state;
-
- return (
-
-
-
-
- Submit
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/en-US/fluid.md b/docs/pages/components/form/en-US/fluid.md
deleted file mode 100644
index 951d3bed6..000000000
--- a/docs/pages/components/form/en-US/fluid.md
+++ /dev/null
@@ -1,39 +0,0 @@
-### Fluid
-
-The `fluid` property allows the Input 100% of the form to fill the container, valid only in vertical layouts.
-
-
-
-```js
-const instance = (
-
- Username
-
- Required
-
-
- Email
-
- Required
-
-
- Password
-
-
-
- Textarea
-
-
-
-
- Submit
- Cancel
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/form/en-US/form-check-async.md b/docs/pages/components/form/en-US/form-check-async.md
deleted file mode 100644
index cd5472421..000000000
--- a/docs/pages/components/form/en-US/form-check-async.md
+++ /dev/null
@@ -1,89 +0,0 @@
-### Asynchronous check
-
-Under certain conditions, we need to perform asynchronous verification on the data, such as verifying whether the username is duplicated. The following example will illustrate the processing of asynchronous verification.
-
-- Set the `checkAsync` property on `` that requires asynchronous validation.
-- The validation rules for asynchronous validation add an object with a return value of Promise via the `addRule` method of `schema`.
-- The check can be triggered manually by calling `checkAsync` and `checkForFieldAsync` of `
- {label}
-
-
- );
-}
-function CheckForm() {
- return (
-
-
-
-
-
- Submit
-
-
-
- );
-}
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/en-US/form-check.md b/docs/pages/components/form/en-US/form-check.md
deleted file mode 100644
index 7e7e1b95a..000000000
--- a/docs/pages/components/form/en-US/form-check.md
+++ /dev/null
@@ -1,122 +0,0 @@
-### Schema Model
-
-Form Check needs to be used ``, ` ` and `Schema.Model` 。
-
-- `` To define a form, you can set `value` and `model` for the form, and `model` is the data model created by `Schema.Model`.
-- ` ` Define a Filed that corresponds to the `key` of the `Schema.Model` object via the `name` property. For detailed reference: Custom Form Components.
-- `Schema.Model` Define a data model, using the reference [schema](/components/schema).
-- Custom trigger check: `` instance provides `check` and `checkForField` methods, used to trigger form checksum field validation
-
-
-
-```js
-const { StringType, NumberType } = Schema.Types;
-
-const model = Schema.Model({
- name: StringType().isRequired('This field is required.'),
- email: StringType()
- .isEmail('Please enter a valid email address.')
- .isRequired('This field is required.'),
- age: NumberType('Please enter a valid number.').range(
- 18,
- 30,
- 'Please enter a number from 18 to 30'
- ),
- password: StringType().isRequired('This field is required.'),
- verifyPassword: StringType()
- .addRule((value, data) => {
- console.log(data);
-
- if (value !== data.password) {
- return false;
- }
-
- return true;
- }, 'The two passwords do not match')
- .isRequired('This field is required.')
-});
-
-class TextField extends React.PureComponent {
- render() {
- const { name, label, accepter, ...props } = this.props;
- return (
-
- {label}
-
-
- );
- }
-}
-
-class CheckForm extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- formValue: {
- name: '',
- email: '',
- age: '',
- password: '',
- verifyPassword: ''
- },
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- this.handleCheckEmail = this.handleCheckEmail.bind(this);
- }
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- console.error('Form Error');
- return;
- }
- console.log(formValue, 'Form Value');
- }
-
- handleCheckEmail() {
- this.form.checkForField('email', checkResult => {
- console.log(checkResult);
- });
- }
- render() {
- const { formError, formValue } = this.state;
-
- return (
-
-
-
(this.form = ref)}
- onChange={formValue => {
- this.setState({ formValue });
- }}
- onCheck={formError => {
- this.setState({ formError });
- }}
- formValue={formValue}
- model={model}
- >
-
-
-
-
-
-
-
-
-
-
- Submit
-
-
- Check Email
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/en-US/help-block.md b/docs/pages/components/form/en-US/help-block.md
deleted file mode 100644
index a420efdcf..000000000
--- a/docs/pages/components/form/en-US/help-block.md
+++ /dev/null
@@ -1,29 +0,0 @@
-## Status
-
----
-
-### Help Text
-
-`` A help description can be defined below the form component. If the `tooltip` property is set, an icon will be displayed on the form component and the help description information will be displayed as ``.
-
-
-
-```js
-const instance = (
-
-
-
- This field is required
-
-
-
-
- This field is required
-
-
-);
-
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/form/en-US/horizontal.md b/docs/pages/components/form/en-US/horizontal.md
deleted file mode 100644
index 1f9a0f4c6..000000000
--- a/docs/pages/components/form/en-US/horizontal.md
+++ /dev/null
@@ -1,37 +0,0 @@
-### Horizontal layout
-
-
-
-```js
-const instance = (
-
-
- Username
-
- Required
-
-
- Email
-
- Required
-
-
- Password
-
-
-
- Textarea
-
-
-
-
- Submit
- Cancel
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/form/en-US/index.md b/docs/pages/components/form/en-US/index.md
index f0948d553..3a4f42403 100644
--- a/docs/pages/components/form/en-US/index.md
+++ b/docs/pages/components/form/en-US/index.md
@@ -10,14 +10,149 @@ A set of components and models that process form data.
## Import
-```js
-import { Form } from 'rsuite';
+
+
+## Layouts
+
+---
+
+### Default
+
+The default is the vertical layout
+
+
+
+### Fluid
+
+The `fluid` property allows the Input 100% of the form to fill the container, valid only in vertical layouts.
+
+
+
+### Horizontal layout
+
+
+
+### Inline Layout
+
+
+
+### Layout In Modal
+
+
+
+## Status
+
+---
+
+### Help Text
+
+`` A help description can be defined below the form component. If the `tooltip` property is set, an icon will be displayed on the form component and the help description information will be displayed as ``.
+
+
+
+### Error Message
+
+Error message can be set in 2 ways:
+
+- The `` component passes an `errorMessage` property setting error message, and `errorPlacement` sets the location of the error message display.
+- Customize a prompt message.
+
+
+
+### Disabled and read only
+
+
+
+## Validations
+
+---
+
+### Default check
-// or
-import Form from 'rsuite/lib/Form';
+The form will automatically trigger the data check after the `submit` event is triggered.
+
+
+
+### Schema Model
+
+Form Check needs to be used ``, ` ` and `Schema.Model` 。
+
+- `` To define a form, you can set `value` and `model` for the form, and `model` is the data model created by `Schema.Model`.
+- ` ` Define a Filed that corresponds to the `key` of the `Schema.Model` object via the `name` property. For detailed reference: Custom Form Components.
+- `Schema.Model` Define a data model, using the reference [schema](/components/schema).
+- Custom trigger check: `` instance provides `check` and `checkForField` methods, used to trigger form checksum field validation
+
+
+
+### Asynchronous check
+
+Under certain conditions, we need to perform asynchronous verification on the data, such as verifying whether the username is duplicated. The following example will illustrate the processing of asynchronous verification.
+
+- Set the `checkAsync` property on ` ` that requires asynchronous validation.
+- The validation rules for asynchronous validation add an object with a return value of Promise via the `addRule` method of `schema`.
+- The check can be triggered manually by calling `checkAsync` and `checkForFieldAsync` of ``.
+
+
+
+### Custom Form.Control
+
+All Data Entry-related components can be used in forms such as `Checkbox`, `SelectPicker`, `Slider`, and so on. But you need to use the `Form.Control` component for data management and data association with the `Form` component.
+
+- `Form.Control` used to bind data fields in a Form, passing the `name` attribute to the `key` of the Schema.Model object.
+- `Form.Control` the default is an `Input` component, which can be set through the ʻaccepter` component.
+
+
+
+### Third-Party Libraries
+
+Take [text-mask](https://github.com/text-mask/text-mask) as an example:
+
+
+
+### Custom trigger verification
+
+In some cases, there is no need for real-time validation of the form data. You can customize the way the control is validated and configure the `checkTrigger` parameter.
+
+The default value of `checkTrigger` is `'change'`, options includes:
+
+- `'change'` : trigger verification when data change
+- `'blur'` : trigger verification when component blur
+- `'none'` : Only valid when calling the `check()` method of ` `
+
+There are `checkTrigger` properties on the ` ` and ` ` components. You can define the entire form's validation method in ``. If there is a form component that needs to handle the validation independently, you can Set it on ` `.
+
+
+
+## Accessibility
+
+- Through the `controlId` prop of ``, you can set `id` on `` and set `htmlFor` on ``. In addition, `aria-labelledby` and `aria-describeby` will be generated for ``, corresponding to the `id` of `` and ``.
+
+```html
+
+ Username
+
+ Username is required
+
```
-
+HTML:
+
+```html
+
+```
+
+- Click the button of `type='submit'` in the Form, and the submit event of the form will be triggered automatically.
## Props
@@ -29,14 +164,14 @@ import Form from 'rsuite/lib/Form';
| classPrefix | string `('form')` | The prefix of the component CSS class |
| errorFromContext | boolean `(true)` | Error reminders in Form.Control are defaulted from Context |
| fluid | boolean | The fluid property allows the Input 100% of the form to fill the container, valid only in vertical layouts |
-| formDefaultValue | Object | Default value of form |
-| formError | Object | Error message of form |
-| formValue | Object | Value of form (Controlled) |
+| formDefaultValue | object | Default value of form |
+| formError | object | Error message of form |
+| formValue | object | Value of form (Controlled) |
| layout | enum: 'horizontal', 'vertical', 'inline' `('vertical')` | Set the left and right columns of the layout of the elements within the form |
-| model | Schema | SchemaModel Object |
-| onChange | (formValue:Object, event:Object) => void | Callback fired when data changing |
-| onCheck | (formError:Object) => void | Callback fired when data cheking |
-| onError | (formError:Object) => void | Callback fired when error checking |
+| model | Schema | SchemaModel object |
+| onChange | (formValue:object, event:object) => void | Callback fired when data changing |
+| onCheck | (formError:object) => void | Callback fired when data cheking |
+| onError | (formError:object) => void | Callback fired when error checking |
### Form methods
@@ -101,15 +236,15 @@ cleanErrorForField: (fieldName: keyof E, callback?: () => void) => void;
| errorMessage | ReactNode | Show error messages |
| errorPlacement | enum: [Placement8](#types) `('bottomStart')` | The placement of error messages |
| name \* | string | The name of form-control |
-| readOnly | boolean | Make the control readonly |
| plaintext | boolean | Make the control plaintext |
+| readOnly | boolean | Make the control readonly |
### ``
-| Property | Type`(default)` | Description |
-| ----------- | ----------------------- | ------------------------------------- |
-| classPrefix | string `('form-group')` | The prefix of the component CSS class |
-| controlId | string | Sets id for controlled component |
+| Property | Type`(default)` | Description |
+| ----------- | ----------------------- | ------------------------------------------------------------------- |
+| classPrefix | string `('form-group')` | The prefix of the component CSS class |
+| controlId | string | Sets id on `` and `htmlFor` on ``. |
### ``
diff --git a/docs/pages/components/form/en-US/modal-layout.md b/docs/pages/components/form/en-US/modal-layout.md
deleted file mode 100644
index e854114c1..000000000
--- a/docs/pages/components/form/en-US/modal-layout.md
+++ /dev/null
@@ -1,80 +0,0 @@
-### Layout In Modal
-
-
-
-```js
-class ModalDemo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- formValue: {
- name: '',
- email: '',
- password: '',
- textarea: ''
- },
- show: false
- };
- this.close = this.close.bind(this);
- this.open = this.open.bind(this);
- this.handleChange = this.handleChange.bind(this);
- }
- close() {
- this.setState({ show: false });
- }
- open() {
- this.setState({ show: true });
- }
- handleChange(value) {
- this.setState({
- formValue: value
- });
- }
- render() {
- return (
-
-
-
- New User
-
-
-
-
- Username
-
- Required
-
-
- Email
-
- Required
-
-
- Password
-
-
-
- Textarea
-
-
-
-
-
-
- Confirm
-
-
- Cancel
-
-
-
- New User
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/en-US/basic.md b/docs/pages/components/form/fragments/basic.md
similarity index 62%
rename from docs/pages/components/form/en-US/basic.md
rename to docs/pages/components/form/fragments/basic.md
index c1f91ee88..deee9b887 100644
--- a/docs/pages/components/form/en-US/basic.md
+++ b/docs/pages/components/form/fragments/basic.md
@@ -1,33 +1,27 @@
-## Layouts
-
----
-
-### Default
-
-The default is the vertical layout
-
```js
+const Textarea = React.forwardRef((props, ref) => );
+
const instance = (
-
+
Username
- Required
+ Username is required
-
+
Email
- Required
+ Email is required
-
+
Password
-
+
Textarea
-
+
diff --git a/docs/pages/components/form/fragments/custom-check-trigger.md b/docs/pages/components/form/fragments/custom-check-trigger.md
new file mode 100644
index 000000000..183eaee18
--- /dev/null
+++ b/docs/pages/components/form/fragments/custom-check-trigger.md
@@ -0,0 +1,72 @@
+
+
+```js
+const model = Schema.Model({
+ name: Schema.Types.StringType()
+ .isEmail('Please enter a valid email address.')
+ .isRequired('This field is required.')
+});
+
+const Field = React.forwardRef((props, ref) => {
+ const { name, message, label, accepter, error, ...rest } = props;
+ return (
+
+ {label}
+
+ {message}
+
+ );
+});
+
+const App = () => {
+ const formRef = React.useRef();
+ const [formError, setFormError] = React.useState({});
+ const [formValue, setFormValue] = React.useState({});
+ const [checkTrigger, setCheckTrigger] = React.useState('change');
+
+ const handleSubmit = () => {
+ if (!formRef.current.check()) {
+ console.error('Form Error');
+ return;
+ }
+ console.log(formValue, 'Form Value');
+ };
+
+ return (
+
+
+ checkTrigger:
+ {
+ setCheckTrigger(value);
+ setFormError({});
+ }}
+ >
+ blur
+ change
+ none
+
+
+
+
+
+ Submit
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/form/fragments/custom-form-control.md b/docs/pages/components/form/fragments/custom-form-control.md
new file mode 100644
index 000000000..2deb45405
--- /dev/null
+++ b/docs/pages/components/form/fragments/custom-form-control.md
@@ -0,0 +1,131 @@
+
+
+```js
+const { ArrayType, StringType, NumberType } = Schema.Types;
+const model = Schema.Model({
+ skills: ArrayType()
+ .minLength(2, 'Please select at least 2 types of Skills.')
+ .isRequired('This field is required.'),
+ status: ArrayType()
+ .minLength(2, 'Please select at least 2 types of Status.')
+ .isRequired('This field is required.'),
+ level: NumberType().min(5, 'This field must be greater than 5')
+});
+
+const Field = React.forwardRef((props, ref) => {
+ const { name, message, label, accepter, error, ...rest } = props;
+ return (
+
+ {label}
+
+ {message}
+
+ );
+});
+
+const App = () => {
+ const formRef = React.useRef();
+ const [formError, setFormError] = React.useState({});
+ const [formValue, setFormValue] = React.useState({
+ number: 10,
+ skills: ['Node.js'],
+ browser: 'Chrome',
+ status: ['open'],
+ level: 1,
+ level2: 1,
+ createDate: new Date()
+ });
+
+ const handleSubmit = () => {
+ if (!formRef.current.check()) {
+ toaster.push(Error );
+ return;
+ }
+ toaster.push(Success );
+ };
+
+ return (
+
+
+
+
+
+ Node.js
+ CSS3
+ Javascript
+ HTML5
+
+
+
+ Chrome
+ FireFox
+ IE
+
+
+
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
+
+> For example: ` ` , Form.Control renders a `` component and binds to the Schema.Model instance in the Form. The rich text editor in the following example, using [react-quill](https://github.com/zenoamaro/react-quill)
diff --git a/docs/pages/components/form/fragments/custom-third-party-libraries.md b/docs/pages/components/form/fragments/custom-third-party-libraries.md
new file mode 100644
index 000000000..cd57dade6
--- /dev/null
+++ b/docs/pages/components/form/fragments/custom-third-party-libraries.md
@@ -0,0 +1,77 @@
+
+
+```js
+const { ArrayType, StringType } = Schema.Types;
+const model = Schema.Model({
+ phone: StringType().isRequired('This field is required.')
+});
+
+const InputMask = React.forwardRef(({ onChange, ...rest }, ref) => (
+ {
+ onChange(event.target.value);
+ }}
+ />
+));
+
+const Field = React.forwardRef((props, ref) => {
+ const { name, message, label, accepter, error, ...rest } = props;
+ return (
+
+ {label}
+
+ {message}
+
+ );
+});
+
+const App = () => {
+ const formRef = React.useRef();
+ const [formError, setFormError] = React.useState({});
+ const [formValue, setFormValue] = React.useState({
+ phone: ''
+ });
+
+ const handleSubmit = () => {
+ if (!formRef.current.check()) {
+ toaster.push(Error );
+ return;
+ }
+ toaster.push(Success );
+ };
+
+ return (
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/form/en-US/error-message.md b/docs/pages/components/form/fragments/error-message.md
similarity index 88%
rename from docs/pages/components/form/en-US/error-message.md
rename to docs/pages/components/form/fragments/error-message.md
index 5de3587b1..bf4f50702 100644
--- a/docs/pages/components/form/en-US/error-message.md
+++ b/docs/pages/components/form/fragments/error-message.md
@@ -1,10 +1,3 @@
-### Error Message
-
-Error message can be set in 2 ways:
-
-- The `` component passes an `errorMessage` property setting error message, and `errorPlacement` sets the location of the error message display.
-- Customize a prompt message.
-
```js
@@ -31,7 +24,7 @@ const App = () => {
return (
-
+
{
errorPlacement={errorPlacement}
/>
-
+
```js
+const Textarea = React.forwardRef((props, ref) => );
+
const instance = (
-
+
Username
Required
-
+
Email
Required
-
+
Password
-
+
Textarea
-
+
diff --git a/docs/pages/components/form/fragments/form-check-async.md b/docs/pages/components/form/fragments/form-check-async.md
new file mode 100644
index 000000000..8adee349a
--- /dev/null
+++ b/docs/pages/components/form/fragments/form-check-async.md
@@ -0,0 +1,67 @@
+
+
+```js
+const { StringType, NumberType } = Schema.Types;
+
+function asyncCheckUsername(name) {
+ return new Promise(resolve => {
+ setTimeout(() => {
+ if (name === 'abc') {
+ resolve(false);
+ } else {
+ resolve(true);
+ }
+ }, 500);
+ });
+}
+
+const model = Schema.Model({
+ name: StringType()
+ .addRule((value, data) => {
+ return asyncCheckUsername(value);
+ }, 'Duplicate username')
+ .isRequired('This field is required.')
+});
+
+const App = () => {
+ const formRef = React.useRef();
+ const [formError, setFormError] = React.useState({});
+ const [formValue, setFormValue] = React.useState({
+ name: ''
+ });
+
+ const handleSubmit = () => {
+ formRef.current.checkAsync().then(result => {
+ console.log(result);
+ });
+ };
+
+ return (
+
+
+
+
+ Username
+
+
+
+
+
+ Submit
+
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/form/zh-CN/form-check-default.md b/docs/pages/components/form/fragments/form-check-default.md
similarity index 81%
rename from docs/pages/components/form/zh-CN/form-check-default.md
rename to docs/pages/components/form/fragments/form-check-default.md
index bd3a6aa7a..7f9887f7c 100644
--- a/docs/pages/components/form/zh-CN/form-check-default.md
+++ b/docs/pages/components/form/fragments/form-check-default.md
@@ -1,11 +1,3 @@
-## 数据校验
-
----
-
-### 默认校验
-
-在表单触发了 `submit` 事件后,会自动触发数据检查。
-
```js
@@ -19,13 +11,13 @@ const model = Schema.Model({
function TextField(props) {
const { name, label, accepter, ...rest } = props;
return (
-
+
{label}
);
}
-function CheckForm() {
+function App() {
return (
@@ -38,7 +30,7 @@ function CheckForm() {
);
}
-ReactDOM.render( );
+ReactDOM.render( );
```
diff --git a/docs/pages/components/form/fragments/form-check.md b/docs/pages/components/form/fragments/form-check.md
new file mode 100644
index 000000000..5721057e3
--- /dev/null
+++ b/docs/pages/components/form/fragments/form-check.md
@@ -0,0 +1,96 @@
+
+
+```js
+const { StringType, NumberType } = Schema.Types;
+
+const model = Schema.Model({
+ name: StringType().isRequired('This field is required.'),
+ email: StringType()
+ .isEmail('Please enter a valid email address.')
+ .isRequired('This field is required.'),
+ age: NumberType('Please enter a valid number.').range(
+ 18,
+ 30,
+ 'Please enter a number from 18 to 30'
+ ),
+ password: StringType().isRequired('This field is required.'),
+ verifyPassword: StringType()
+ .addRule((value, data) => {
+ console.log(data);
+
+ if (value !== data.password) {
+ return false;
+ }
+
+ return true;
+ }, 'The two passwords do not match')
+ .isRequired('This field is required.')
+});
+
+const TextField = React.forwardRef((props, ref) => {
+ const { name, label, accepter, ...rest } = props;
+ return (
+
+ {label}
+
+
+ );
+});
+
+const App = () => {
+ const formRef = React.useRef();
+ const [formError, setFormError] = React.useState({});
+ const [formValue, setFormValue] = React.useState({
+ name: '',
+ email: '',
+ age: '',
+ password: '',
+ verifyPassword: ''
+ });
+
+ const handleSubmit = () => {
+ if (!formRef.current.check()) {
+ console.error('Form Error');
+ return;
+ }
+ console.log(formValue, 'Form Value');
+ };
+
+ const handleCheckEmail = () => {
+ formRef.current.checkForField('email', checkResult => {
+ console.log(checkResult);
+ });
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ Submit
+
+
+ Check Email
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/form/zh-CN/help-block.md b/docs/pages/components/form/fragments/help-block.md
similarity index 58%
rename from docs/pages/components/form/zh-CN/help-block.md
rename to docs/pages/components/form/fragments/help-block.md
index 70eaf19d3..d014b9603 100644
--- a/docs/pages/components/form/zh-CN/help-block.md
+++ b/docs/pages/components/form/fragments/help-block.md
@@ -1,22 +1,14 @@
-## 状态
-
----
-
-### 帮助说明
-
-`` 可以在表单组件下面定义一个帮助说明信息,如果设置 `tooltip` 属性,就会在表单组件显示一个图标,以 `` 的方式显示帮助说明信息。
-
```js
const instance = (
-
+
This field is required
-
+
This field is required
diff --git a/docs/pages/components/form/zh-CN/horizontal.md b/docs/pages/components/form/fragments/horizontal.md
similarity index 72%
rename from docs/pages/components/form/zh-CN/horizontal.md
rename to docs/pages/components/form/fragments/horizontal.md
index 38f7b64dc..f66a83998 100644
--- a/docs/pages/components/form/zh-CN/horizontal.md
+++ b/docs/pages/components/form/fragments/horizontal.md
@@ -1,27 +1,27 @@
-### 水平排列布局
-
```js
+const Textarea = React.forwardRef((props, ref) => );
+
const instance = (
-
+
Username
Required
-
+
Email
Required
-
+
Password
-
+
Textarea
-
+
diff --git a/docs/pages/components/form/fragments/import.md b/docs/pages/components/form/fragments/import.md
new file mode 100644
index 000000000..bcc7538ab
--- /dev/null
+++ b/docs/pages/components/form/fragments/import.md
@@ -0,0 +1,6 @@
+```js
+import { Form } from 'rsuite';
+
+// or
+import Form from 'rsuite/lib/Form';
+```
\ No newline at end of file
diff --git a/docs/pages/components/form/en-US/inline.md b/docs/pages/components/form/fragments/inline.md
similarity index 84%
rename from docs/pages/components/form/en-US/inline.md
rename to docs/pages/components/form/fragments/inline.md
index bb01002a6..51778d7b4 100644
--- a/docs/pages/components/form/en-US/inline.md
+++ b/docs/pages/components/form/fragments/inline.md
@@ -1,18 +1,16 @@
-### Inline Layout
-
```js
var instance = (
-
+
Username
Required
-
+
Password
@@ -22,12 +20,12 @@ var instance = (
-
+
Username
-
+
Username
diff --git a/docs/pages/components/form/fragments/modal-layout.md b/docs/pages/components/form/fragments/modal-layout.md
new file mode 100644
index 000000000..8684d837f
--- /dev/null
+++ b/docs/pages/components/form/fragments/modal-layout.md
@@ -0,0 +1,66 @@
+
+
+```js
+const Textarea = React.forwardRef((props, ref) => );
+
+const App = () => {
+ const [open, setOpen] = React.useState(false);
+ const [formValue, setFormValue] = React.useState({
+ name: '',
+ email: '',
+ password: '',
+ textarea: ''
+ });
+
+ const handleClose = () => {
+ setOpen(false);
+ };
+ const handleOpen = () => {
+ setOpen(true);
+ };
+ return (
+
+
+
+ New User
+
+
+
+
+ Username
+
+ Required
+
+
+ Email
+
+ Required
+
+
+ Password
+
+
+
+ Textarea
+
+
+
+
+
+
+ Confirm
+
+
+ Cancel
+
+
+
+ New User
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/form/en-US/read-only.md b/docs/pages/components/form/fragments/read-only.md
similarity index 92%
rename from docs/pages/components/form/en-US/read-only.md
rename to docs/pages/components/form/fragments/read-only.md
index f3a25c5a6..03b585947 100644
--- a/docs/pages/components/form/en-US/read-only.md
+++ b/docs/pages/components/form/fragments/read-only.md
@@ -1,9 +1,7 @@
-### Disabled and read only
-
```js
-const Example = () => {
+const App = () => {
const cascaderData = data;
const [formValue, setFormValue] = useState({
input:
@@ -65,13 +63,13 @@ const Example = () => {
plaintext
-
+
Input
This is a tooltip description.
-
+
Checkbox
{
This default description.
-
+
Radio
{
-
+
Slider
{
/>
-
+
DatePicker
{
/>
-
+
DateRangePicker
{
/>
-
+
CheckPicker
{
/>
-
+
SelectPicker
{
/>
-
+
TagPicker
{
/>
-
+
InputPicker
{
/>
-
+
Cascader
{
/>
-
+
MultiCascader
{
);
};
-ReactDOM.render( );
+ReactDOM.render( );
```
diff --git a/docs/pages/components/form/index.tsx b/docs/pages/components/form/index.tsx
index 58579fb3e..cd56d5894 100644
--- a/docs/pages/components/form/index.tsx
+++ b/docs/pages/components/form/index.tsx
@@ -1,4 +1,4 @@
-import * as React from 'react';
+import React from 'react';
import {
Form,
Dropdown,
@@ -27,7 +27,9 @@ import {
TagPicker,
InputPicker,
Cascader,
- MultiCascader
+ MultiCascader,
+ Message,
+ toaster
} from 'rsuite';
import Loadable from 'react-loadable';
import * as dateFns from 'date-fns';
@@ -70,22 +72,6 @@ export default function Page() {
const { response: pickerData } = useFetchData('users-role');
return (
diff --git a/docs/pages/components/form/zh-CN/basic.md b/docs/pages/components/form/zh-CN/basic.md
deleted file mode 100644
index 778f14141..000000000
--- a/docs/pages/components/form/zh-CN/basic.md
+++ /dev/null
@@ -1,41 +0,0 @@
-## 布局
-
-### 默认
-
-默认为垂直布局
-
-
-
-```js
-const instance = (
-
-
- Username
-
- Required
-
-
- Email
-
- Required
-
-
- Password
-
-
-
- Textarea
-
-
-
-
- Submit
- Cancel
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/custom-check-trigger.md b/docs/pages/components/form/zh-CN/custom-check-trigger.md
deleted file mode 100644
index 898db17a9..000000000
--- a/docs/pages/components/form/zh-CN/custom-check-trigger.md
+++ /dev/null
@@ -1,101 +0,0 @@
-### 自定义触发校验
-
-在某些情况下不需要对表单数据进行实时校验,可以自定义控制校验的方式,配置 `checkTrigger` 参数。
-
-`checkTrigger` 默认值是 `'change'`, 选项包括:
-
-- `'change'` : 数据改变 `onChange` 的时候会触发数据校验。
-- `'blur'` : 组件失去焦点触发校验
-- `'none'` : 不触发校验,只会在调用 `` 的 `check()` 方法的时候才会校验
-
-在 ` ` 和 ` ` 组件上都有 `checkTrigger` 属性, 在 `` 中可以定义整个表单的校验方式,如果有个表单组件需要单独处理校验方式,可以在 ` ` 上进行设置。
-
-
-
-```js
-const model = Schema.Model({
- name: Schema.Types.StringType()
- .isEmail('Please enter a valid email address.')
- .isRequired('This field is required.')
-});
-
-class CustomField extends React.PureComponent {
- render() {
- const { name, message, label, accepter, error, ...props } = this.props;
- return (
-
- {label}
-
- {message}
-
- );
- }
-}
-
-class CustomCheckForm extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- checkTrigger: 'change',
- formValue: {},
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
-
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- console.error('Form Error');
- return;
- }
- console.log(formValue, 'Form Value');
- }
-
- render() {
- const { formError, formValue, checkTrigger } = this.state;
- return (
-
-
- checkTrigger:
- {
- this.setState({
- checkTrigger,
- formError: {}
- });
- }}
- >
- blur
- change
- none
-
-
- (this.form = ref)}
- onChange={formValue => {
- this.setState({ formValue });
- }}
- onCheck={formError => {
- this.setState({ formError });
- }}
- formError={formError}
- formDefaultValue={formValue}
- model={model}
- checkTrigger={checkTrigger}
- >
-
-
- 提交
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/custom-form-control.md b/docs/pages/components/form/zh-CN/custom-form-control.md
deleted file mode 100644
index 841eae210..000000000
--- a/docs/pages/components/form/zh-CN/custom-form-control.md
+++ /dev/null
@@ -1,161 +0,0 @@
-### 自定义表单组件
-
-所有的 Data Entry 相关的组件都可以在表单中使用,例如 `Checkbox`,`SelectPicker`,`Slider` 等等。 但是需要通过 `Form.Control` 组件进行数据管理,实现与 `Form` 组件的数据关联。
-
-- Form.Control 用于绑定 Form 中的数据字段,通过 `name` 属性和 Schema.Model 对象的 `key` 对应。
-- Form.Control 默认是个 `Input` 组件,可以通过 `accepter` 设置需要的数据录入组件。
-
-
-
-```js
-const { ArrayType, StringType, NumberType } = Schema.Types;
-const model = Schema.Model({
- skills: ArrayType()
- .minLength(2, 'Please select at least 2 types of Skills.')
- .isRequired('This field is required.'),
- status: ArrayType()
- .minLength(2, 'Please select at least 2 types of Status.')
- .isRequired('This field is required.'),
- level: NumberType().min(5, 'This field must be greater than 5')
-});
-
-class CustomField extends React.PureComponent {
- render() {
- const { name, message, label, accepter, error, ...props } = this.props;
- return (
-
- {label}
-
- {message}
-
- );
- }
-}
-
-class CustomFieldForm extends React.Component {
- constructor(props) {
- super(props);
- const formValue = {
- number: 10,
- skills: ['Node.js'],
- browser: 'Chrome',
- status: ['open'],
- level: 1,
- level2: 1,
- createDate: new Date()
- };
- this.state = {
- formValue: formValue,
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- Alert.error('Error');
- return;
- }
- Alert.success('Success');
- }
- render() {
- const { formError, formValue } = this.state;
-
- return (
-
-
-
(this.form = ref)}
- onChange={formValue => {
- console.log(formValue);
- this.setState({ formValue });
- }}
- onCheck={formError => {
- console.log(formError, 'formError');
- this.setState({ formError });
- }}
- formValue={formValue}
- model={model}
- >
-
-
-
- Node.js
- CSS3
- Javascript
- HTML5
-
-
-
- Chrome
- FireFox
- IE
-
-
-
-
-
-
-
-
-
-
- Submit
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-> 例如: ` ` , Form.Control 会渲染一个 `` 组件, 同时与 Form 中的 Schema.Model 实例绑定。以下示例中的富文本编辑器,用的是 [react-quill](https://github.com/zenoamaro/react-quill)
diff --git a/docs/pages/components/form/zh-CN/custom-third-party-libraries.md b/docs/pages/components/form/zh-CN/custom-third-party-libraries.md
deleted file mode 100644
index 79244f0b7..000000000
--- a/docs/pages/components/form/zh-CN/custom-third-party-libraries.md
+++ /dev/null
@@ -1,114 +0,0 @@
-### 兼容第三方组件
-
-以 [text-mask](https://github.com/text-mask/text-mask) 为例:
-
-
-
-```js
-const { ArrayType, StringType } = Schema.Types;
-const model = Schema.Model({
- phone: StringType().isRequired('This field is required.')
-});
-
-const InputMask = ({ onChange, ...rest }) => {
- return (
- {
- onChange(event.target.value);
- }}
- />
- );
-};
-
-class CustomField extends React.PureComponent {
- render() {
- const { name, message, label, accepter, error, ...props } = this.props;
- return (
-
- {label}
-
- {message}
-
- );
- }
-}
-
-class CustomFieldForm extends React.Component {
- constructor(props) {
- super(props);
- const formValue = {
- phone: ''
- };
- this.state = {
- formValue: formValue,
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- Alert.error('Error');
- return;
- }
- Alert.success('Success');
- }
- render() {
- const { formError, formValue } = this.state;
-
- return (
-
-
-
(this.form = ref)}
- onChange={formValue => {
- console.log(formValue);
- this.setState({ formValue });
- }}
- onCheck={formError => {
- console.log(formError, 'formError');
- this.setState({ formError });
- }}
- formDefaultValue={formValue}
- model={model}
- >
-
-
-
-
- Submit
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/error-message.md b/docs/pages/components/form/zh-CN/error-message.md
deleted file mode 100644
index d8018b96e..000000000
--- a/docs/pages/components/form/zh-CN/error-message.md
+++ /dev/null
@@ -1,83 +0,0 @@
-### 错误消息
-
-错误消息提醒可以通过 2 种方式设定:
-
-- `` 组件上传递一个 `errorMessage` 属性设置错误信息,通过 `errorPlacement`设置错误信息显示的位置 。
-- 自定义一个提示信息。
-
-
-
-```js
-const errorPlacementData = [
- { label: 'bottomStart', value: 'bottomStart' },
- { label: 'bottomEnd', value: 'bottomEnd' },
- { label: 'topStart', value: 'topStart' },
- { label: 'topEnd', value: 'topEnd' },
- { label: 'leftStart', value: 'leftStart' },
- { label: 'rightStart', value: 'rightStart' },
- { label: 'leftEnd', value: 'leftEnd' },
- { label: 'rightEnd', value: 'rightEnd' }
-];
-
-const errorStyles = errorVisible => {
- return { display: errorVisible ? 'block' : 'none', color: 'red', marginTop: 6 };
-};
-
-const App = () => {
- const [errorVisible, setErrorVisible] = React.useState(false);
- const [errorPlacement, setErrorPlacement] = React.useState('bottomStart');
- const errorMessage = errorVisible ? 'This field is required' : null;
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {errorMessage}
-
-
-
-
-
-
- {errorMessage}
-
-
-
- Show Error:
-
-
- );
-};
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/form-check-async.md b/docs/pages/components/form/zh-CN/form-check-async.md
deleted file mode 100644
index a3d525468..000000000
--- a/docs/pages/components/form/zh-CN/form-check-async.md
+++ /dev/null
@@ -1,89 +0,0 @@
-### 异步校验
-
-在某些条件下,我们需对数据进行异步校验,比如校验用户名是否重名,下面一个示例将说明异步校验的处理。
-
-- 在需要异步校验的 `` 上设置 `checkAsync` 属性。
-- 异步校验的验证规则通过 `schema` 的 `addRule` 方法添加一个返回值为 Promise 的对象。
-- 通过调用 `` 的 `checkAsync` 与 `checkForFieldAsync` 的访问,可以手动触发校验。
-
-
-
-```js
-const { StringType, NumberType } = Schema.Types;
-
-function asyncCheckUsername(name) {
- return new Promise(resolve => {
- setTimeout(() => {
- if (name === 'abc') {
- resolve(false);
- } else {
- resolve(true);
- }
- }, 500);
- });
-}
-
-const model = Schema.Model({
- name: StringType()
- .addRule((value, data) => {
- return asyncCheckUsername(value);
- }, 'Duplicate username')
- .isRequired('This field is required.')
-});
-
-class CheckForm extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- formValue: {
- name: ''
- },
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
- handleSubmit() {
- const { formValue } = this.state;
-
- this.form.checkAsync().then(result => {
- console.log(result);
- });
- }
-
- render() {
- const { formError, formValue } = this.state;
-
- return (
-
-
-
(this.form = ref)}
- onChange={formValue => {
- this.setState({ formValue });
- }}
- onCheck={formError => {
- this.setState({ formError });
- }}
- formValue={formValue}
- model={model}
- >
-
- Username
-
-
-
-
-
- Submit
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/form-check.md b/docs/pages/components/form/zh-CN/form-check.md
deleted file mode 100644
index 90f99dc0a..000000000
--- a/docs/pages/components/form/zh-CN/form-check.md
+++ /dev/null
@@ -1,121 +0,0 @@
-### 数据模型
-
-表单校验需要用到 ``, ` ` 组件, 和 `Schema.Model` 。
-
-- `` 定义一个表单,可以给表单设置 `value` 和 `model`,`model` 是由 `Schema.Model` 创建的数据模型。
-- ` ` 定义一个 Filed,通过 `name` 属性和 `Schema.Model` 对象的 `key` 对应, 详细参考: 自定义表单组件。
-- `Schema.Model` 定义一个数据模型,详细使用参考 [schema](/components/schema)。
-- 自定义触发校验: `` 实例提供 [check()](#methods) 与 [checkForField()](#methods) 方法,分别用于触发表单校验和字段校验。
-
-
-
-```js
-const { StringType, NumberType } = Schema.Types;
-
-const model = Schema.Model({
- name: StringType().isRequired('This field is required.'),
- email: StringType()
- .isEmail('Please enter a valid email address.')
- .isRequired('This field is required.'),
- age: NumberType('Please enter a valid number.').range(
- 18,
- 30,
- 'Please enter a number from 18 to 30'
- ),
- password: StringType().isRequired('This field is required.'),
- verifyPassword: StringType()
- .addRule((value, data) => {
- console.log(data);
-
- if (value !== data.password) {
- return false;
- }
-
- return true;
- }, 'The two passwords do not match')
- .isRequired('This field is required.')
-});
-
-class TextField extends React.PureComponent {
- render() {
- const { name, label, accepter, ...props } = this.props;
- return (
-
- {label}
-
-
- );
- }
-}
-
-class CheckForm extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- formValue: {
- name: '',
- email: '',
- age: '',
- password: '',
- verifyPassword: ''
- },
- formError: {}
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- this.handleCheckEmail = this.handleCheckEmail.bind(this);
- }
- handleSubmit() {
- const { formValue } = this.state;
- if (!this.form.check()) {
- console.error('Form Error');
- return;
- }
- console.log(formValue, 'Form Value');
- }
-
- handleCheckEmail() {
- this.form.checkForField('email', checkResult => {
- console.log(checkResult);
- });
- }
- render() {
- const { formError, formValue } = this.state;
-
- return (
-
-
-
(this.form = ref)}
- onChange={formValue => {
- this.setState({ formValue });
- }}
- onCheck={formError => {
- this.setState({ formError });
- }}
- formValue={formValue}
- model={model}
- >
-
-
-
-
-
-
-
-
-
- Submit
-
-
- Check Email
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/index.md b/docs/pages/components/form/zh-CN/index.md
index 950e2447c..6bd7c898e 100644
--- a/docs/pages/components/form/zh-CN/index.md
+++ b/docs/pages/components/form/zh-CN/index.md
@@ -10,14 +10,149 @@
## 获取组件
-```js
-import { Form } from 'rsuite';
+
+
+## 布局
+
+---
+
+### 默认
+
+默认为垂直布局
+
+
+
+### 撑满容器
+
+`fluid` 属性可以让表单中的 Input 100% 撑满容器,只在垂直布局中有效。
+
+
+
+### 水平排列布局
+
+
+
+### 行内排列布局
+
+
+
+### 模态框中布局
+
+
+
+## 状态
+
+---
+
+### 帮助说明
+
+`` 可以在表单组件下面定义一个帮助说明信息,如果设置 `tooltip` 属性,就会在表单组件显示一个图标,以 `` 的方式显示帮助说明信息。
+
+
+
+### 错误消息
+
+错误消息提醒可以通过 2 种方式设定:
+
+- `` 组件上传递一个 `errorMessage` 属性设置错误信息,通过 `errorPlacement`设置错误信息显示的位置 。
+- 自定义一个提示信息。
+
+
+
+### 禁用与只读
+
+
+
+## 数据校验
+
+---
+
+### 默认校验
+
+在表单触发了 `submit` 事件后,会自动触发数据检查。
+
+
+
+### 数据模型
+
+表单校验需要用到 ``, ` ` 组件, 和 `Schema.Model` 。
+
+- `` 定义一个表单,可以给表单设置 `value` 和 `model`,`model` 是由 `Schema.Model` 创建的数据模型。
+- ` ` 定义一个 Filed,通过 `name` 属性和 `Schema.Model` 对象的 `key` 对应, 详细参考: 自定义表单组件。
+- `Schema.Model` 定义一个数据模型,详细使用参考 [schema](/components/schema)。
+- 自定义触发校验: `` 实例提供 [check()](#methods) 与 [checkForField()](#methods) 方法,分别用于触发表单校验和字段校验。
+
+
+
+### 异步校验
+
+在某些条件下,我们需对数据进行异步校验,比如校验用户名是否重名,下面一个示例将说明异步校验的处理。
+
+- 在需要异步校验的 ` ` 上设置 `checkAsync` 属性。
+- 异步校验的验证规则通过 `schema` 的 `addRule` 方法添加一个返回值为 Promise 的对象。
+- 通过调用 `` 的 `checkAsync` 与 `checkForFieldAsync` 的访问,可以手动触发校验。
+
+
+
+### 自定义表单组件
+
+所有的 Data Entry 相关的组件都可以在表单中使用,例如 `Checkbox`,`SelectPicker`,`Slider` 等等。 但是需要通过 `Form.Control` 组件进行数据管理,实现与 `Form` 组件的数据关联。
+
+- Form.Control 用于绑定 Form 中的数据字段,通过 `name` 属性和 Schema.Model 对象的 `key` 对应。
+- Form.Control 默认是个 `Input` 组件,可以通过 `accepter` 设置需要的数据录入组件。
+
+
+
+### 兼容第三方组件
+
+以 [text-mask](https://github.com/text-mask/text-mask) 为例:
+
+
+
+### 自定义触发校验
+
+在某些情况下不需要对表单数据进行实时校验,可以自定义控制校验的方式,配置 `checkTrigger` 参数。
+
+`checkTrigger` 默认值是 `'change'`, 选项包括:
+
+- `'change'` : 数据改变 `onChange` 的时候会触发数据校验。
+- `'blur'` : 组件失去焦点触发校验
+- `'none'` : 不触发校验,只会在调用 ` ` 的 `check()` 方法的时候才会校验
+
+在 ` ` 和 ` ` 组件上都有 `checkTrigger` 属性, 在 `` 中可以定义整个表单的校验方式,如果有个表单组件需要单独处理校验方式,可以在 ` ` 上进行设置。
+
+
+
+## 无障碍设计
+
+- 通过 `` 的 `controlId` 属性,可以在 `` 上设置 `id` 同时在 `` 上设置 `htmlFor`。另外会为 `` 生成`aria-labelledby` 和 `aria- describeby`, 对应到 `` 与 `` 的 `id`。
+
+```html
+
+ Username
+
+ Username is required
+
+```
+
+生成为:
-// or
-import Form from 'rsuite/lib/Form';
+```html
+
```
-
+- 在 Form 内点击 `type='submit'` 的按钮,会自动触发表单的 submit 事件。
## Props
@@ -34,9 +169,9 @@ import Form from 'rsuite/lib/Form';
| formValue | object | 表单的值 `受控组件` |
| layout | enum: 'horizontal', 'vertical', 'inline' `('vertical')` | 设置表单内的元素左右两栏布局 |
| model | Schema | SchemaModel 对象 |
-| onChange | (formValue:Object, event:Object) => void | 数据改变后的回调函数 |
-| onCheck | (formError:Object) => void | 数据校验的回调函数 |
-| onError | (formError:Object) => void | 校验出错的回调函数 |
+| onChange | (formValue:object, event:object) => void | 数据改变后的回调函数 |
+| onCheck | (formError:object) => void | 数据校验的回调函数 |
+| onError | (formError:object) => void | 校验出错的回调函数 |
### Form methods
@@ -94,10 +229,10 @@ cleanErrorForField: (fieldName: keyof E, callback?: () => void) => void;
### ``
-| 属性名称 | 类型`(默认值)` | 描述 |
-| ----------- | ----------------------- | ----------------- |
-| classPrefix | string `('form-group')` | 组件 CSS 类的前缀 |
-| controlId | string | 设置控件的 ID |
+| 属性名称 | 类型`(默认值)` | 描述 |
+| ----------- | ----------------------- | --------------------------------------------------------------------------- |
+| classPrefix | string `('form-group')` | 组件 CSS 类的前缀 |
+| controlId | string | 在 ``上设置 `id`,在 `` 上设置 `htmlFor`。 |
### ``
diff --git a/docs/pages/components/form/zh-CN/inline.md b/docs/pages/components/form/zh-CN/inline.md
deleted file mode 100644
index 852f8a27e..000000000
--- a/docs/pages/components/form/zh-CN/inline.md
+++ /dev/null
@@ -1,42 +0,0 @@
-### 行内排列布局
-
-
-
-```js
-var instance = (
-
-
-
- Username
-
- Required
-
-
-
- Password
-
-
-
- Login
-
-
-
-
-
- Username
-
-
-
-
- Username
-
-
-
- Login
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/modal-layout.md b/docs/pages/components/form/zh-CN/modal-layout.md
deleted file mode 100644
index 3299a9cf3..000000000
--- a/docs/pages/components/form/zh-CN/modal-layout.md
+++ /dev/null
@@ -1,80 +0,0 @@
-### 模态框中布局
-
-
-
-```js
-class ModalDemo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- formValue: {
- name: '',
- email: '',
- password: '',
- textarea: ''
- },
- show: false
- };
- this.close = this.close.bind(this);
- this.open = this.open.bind(this);
- this.handleChange = this.handleChange.bind(this);
- }
- close() {
- this.setState({ show: false });
- }
- open() {
- this.setState({ show: true });
- }
- handleChange(value) {
- this.setState({
- formValue: value
- });
- }
- render() {
- return (
-
-
-
- New User
-
-
-
-
- Username
-
- Required
-
-
- Email
-
- Required
-
-
- Password
-
-
-
- Textarea
-
-
-
-
-
-
- Confirm
-
-
- Cancel
-
-
-
- New User
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/form/zh-CN/read-only.md b/docs/pages/components/form/zh-CN/read-only.md
deleted file mode 100644
index cab69c096..000000000
--- a/docs/pages/components/form/zh-CN/read-only.md
+++ /dev/null
@@ -1,245 +0,0 @@
-### 禁用与只读
-
-
-
-```js
-const Example = () => {
- const cascaderData = data;
- const [formValue, setFormValue] = useState({
- input:
- "React Suite is a set of react component libraries for enterprise system products. Built by HYPERS front-end team and UX team, mainly serving company's big data products. After three major revisions, a large number of components and rich functionality have been accumulated.",
- checkbox: ['Node.js', 'CSS3', 'HTML5'],
- radio: 'HTML5',
- slider: 10,
- datePicker: new Date(),
- dateRangePicker: [new Date(), new Date()],
- checkPicker: [
- 'Eugenia',
- 'Kariane',
- 'Louisa',
- 'Marty',
- 'Kenya',
- 'Hal',
- 'Julius',
- 'Travon',
- 'Vincenza',
- 'Dominic',
- 'Pearlie',
- 'Tyrel',
- 'Jaylen',
- 'Rogelio'
- ],
- selectPicker: 'Louisa',
- tagPicker: [
- 'Eugenia',
- 'Kariane',
- 'Louisa',
- 'Marty',
- 'Kenya',
- 'Hal',
- 'Julius',
- 'Travon',
- 'Vincenza',
- 'Dominic',
- 'Pearlie',
- 'Tyrel',
- 'Jaylen',
- 'Rogelio'
- ],
- inputPicker: 'Rogelio',
- cascader: '1-1-5',
- multiCascader: ['1-1-4', '1-1-5']
- });
- const [mode, setMode] = useState('readonly');
- const disabled = mode === 'disabled';
- const readOnly = mode === 'readonly';
- const plaintext = mode === 'plaintext';
-
- return (
- setFormValue(formValue)}>
- 切换显示模式
- setMode(value)}>
- 正常
- 只读
- 禁用
- 纯文本
-
-
-
- Input
-
- This is a tooltip description.
-
-
-
- Checkbox
-
-
- Node.js
-
-
- Webpack
-
-
- CSS3
-
-
- Javascript
-
-
- HTML5
-
-
- This default description.
-
-
-
- Radio
-
-
- Node.js
-
-
- Webpack
-
-
- CSS3
-
-
- Javascript
-
-
- HTML5
-
-
-
-
-
- Slider
-
-
-
-
- DatePicker
-
-
-
-
- DateRangePicker
-
-
-
-
- CheckPicker
-
-
-
-
- SelectPicker
-
-
-
-
- TagPicker
-
-
-
-
- InputPicker
-
-
-
-
- Cascader
-
-
-
-
- MultiCascader
-
-
-
- );
-};
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/grid/en-US/basic.md b/docs/pages/components/grid/en-US/basic.md
deleted file mode 100644
index 5e999de51..000000000
--- a/docs/pages/components/grid/en-US/basic.md
+++ /dev/null
@@ -1,47 +0,0 @@
-### Default
-
-
-
-```js
-const instance = (
-
-
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
- xs={2}
-
-
-
- xs={4}
- xs={4}
- xs={4}
- xs={4}
- xs={4}
- xs={4}
-
-
-
- xs={8}
- xs={8}
- xs={8}
-
-
-
- xs={12}
- xs={12}
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/grid/en-US/index.md b/docs/pages/components/grid/en-US/index.md
index a3a1e43f4..6f49c51be 100644
--- a/docs/pages/components/grid/en-US/index.md
+++ b/docs/pages/components/grid/en-US/index.md
@@ -17,18 +17,37 @@ Corresponds to the screen width:
## Import
-```js
-import { Grid, Row, Col } from 'rsuite';
-
-//or
-import Grid from 'rsuite/lib/Grid';
-import Row from 'rsuite/lib/Row';
-import Col from 'rsuite/lib/Col';
-```
+
## Examples
-
+### Default
+
+
+
+### Responsive
+
+
+
+### Gutter
+
+
+
+### Offset
+
+
+
+### Push and Pull
+
+
+
+### Hidden
+
+
+
+### Nesting
+
+
## Props
diff --git a/docs/pages/components/grid/en-US/nested.md b/docs/pages/components/grid/en-US/nested.md
deleted file mode 100644
index 31cdf266c..000000000
--- a/docs/pages/components/grid/en-US/nested.md
+++ /dev/null
@@ -1,47 +0,0 @@
-### Nesting
-
-
-
-```js
-const instance = (
-
-
-
-
-
-
- xs={12}
- xs={12}
-
-
-
-
- xs={12}
- xs={12}
-
-
-
-
-
-
-
-
- xs={12}
- xs={12}
-
-
-
-
- xs={12}
- xs={12}
-
-
-
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/grid/en-US/pull-push.md b/docs/pages/components/grid/en-US/pull-push.md
deleted file mode 100644
index 8f9be7b5b..000000000
--- a/docs/pages/components/grid/en-US/pull-push.md
+++ /dev/null
@@ -1,37 +0,0 @@
-### Push and Pull
-
-
-
-```js
-const instance = (
-
-
-
- xs={12} xsPush={12} `left`
-
-
- xs={12} xsPull={12} `right`
-
-
-
-
- xs={6} `left`
-
- xs={6} xsPush={12} `right`
-
-
-
-
-
- xs={6} xsPush={18} `left`
-
-
- xs={6} xsPull={6} `right`
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/grid/en-US/responsive.md b/docs/pages/components/grid/en-US/responsive.md
deleted file mode 100644
index 5afb519ef..000000000
--- a/docs/pages/components/grid/en-US/responsive.md
+++ /dev/null
@@ -1,36 +0,0 @@
-### Responsive
-
-
-
-```js
-const instance = (
-
-
-
- xs={24} sm={24} md={6}
-
-
- xs={24} sm={24} md={6}
-
-
- xs={24} sm={24} md={6}
-
-
-
-
-
- xs={24} sm={12} md={6}
-
-
- xs={24} sm={12} md={6}
-
-
- xs={24} sm={12} md={6}
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/grid/zh-CN/basic.md b/docs/pages/components/grid/fragments/basic.md
similarity index 98%
rename from docs/pages/components/grid/zh-CN/basic.md
rename to docs/pages/components/grid/fragments/basic.md
index 38f5c4b2f..0c11e7cb6 100644
--- a/docs/pages/components/grid/zh-CN/basic.md
+++ b/docs/pages/components/grid/fragments/basic.md
@@ -1,5 +1,3 @@
-### 默认
-
```js
diff --git a/docs/pages/components/grid/en-US/gutter.md b/docs/pages/components/grid/fragments/gutter.md
similarity index 98%
rename from docs/pages/components/grid/en-US/gutter.md
rename to docs/pages/components/grid/fragments/gutter.md
index b44681b7c..75fcbd58f 100644
--- a/docs/pages/components/grid/en-US/gutter.md
+++ b/docs/pages/components/grid/fragments/gutter.md
@@ -1,5 +1,3 @@
-### Gutter
-
```js
diff --git a/docs/pages/components/grid/en-US/hidden.md b/docs/pages/components/grid/fragments/hidden.md
similarity index 96%
rename from docs/pages/components/grid/en-US/hidden.md
rename to docs/pages/components/grid/fragments/hidden.md
index a29f64c7a..ea223c2ef 100644
--- a/docs/pages/components/grid/en-US/hidden.md
+++ b/docs/pages/components/grid/fragments/hidden.md
@@ -1,5 +1,3 @@
-### Hidden
-
```js
diff --git a/docs/pages/components/grid/fragments/import.md b/docs/pages/components/grid/fragments/import.md
new file mode 100644
index 000000000..b253b0239
--- /dev/null
+++ b/docs/pages/components/grid/fragments/import.md
@@ -0,0 +1,8 @@
+```js
+import { Grid, Row, Col } from 'rsuite';
+
+//or
+import Grid from 'rsuite/lib/Grid';
+import Row from 'rsuite/lib/Row';
+import Col from 'rsuite/lib/Col';
+```
diff --git a/docs/pages/components/grid/zh-CN/nested.md b/docs/pages/components/grid/fragments/nested.md
similarity index 98%
rename from docs/pages/components/grid/zh-CN/nested.md
rename to docs/pages/components/grid/fragments/nested.md
index f3f05b449..d92514235 100644
--- a/docs/pages/components/grid/zh-CN/nested.md
+++ b/docs/pages/components/grid/fragments/nested.md
@@ -1,5 +1,3 @@
-### 嵌套
-
```js
diff --git a/docs/pages/components/grid/en-US/offset.md b/docs/pages/components/grid/fragments/offset.md
similarity index 98%
rename from docs/pages/components/grid/en-US/offset.md
rename to docs/pages/components/grid/fragments/offset.md
index 9c90be001..508863355 100644
--- a/docs/pages/components/grid/en-US/offset.md
+++ b/docs/pages/components/grid/fragments/offset.md
@@ -1,5 +1,3 @@
-### Offset
-
```js
diff --git a/docs/pages/components/grid/zh-CN/pull-push.md b/docs/pages/components/grid/fragments/pull-push.md
similarity index 97%
rename from docs/pages/components/grid/zh-CN/pull-push.md
rename to docs/pages/components/grid/fragments/pull-push.md
index 947fa1758..bc56492b8 100644
--- a/docs/pages/components/grid/zh-CN/pull-push.md
+++ b/docs/pages/components/grid/fragments/pull-push.md
@@ -1,5 +1,3 @@
-### 栅格推拉
-
```js
diff --git a/docs/pages/components/grid/zh-CN/responsive.md b/docs/pages/components/grid/fragments/responsive.md
similarity index 97%
rename from docs/pages/components/grid/zh-CN/responsive.md
rename to docs/pages/components/grid/fragments/responsive.md
index 29c88ec00..173cd62dd 100644
--- a/docs/pages/components/grid/zh-CN/responsive.md
+++ b/docs/pages/components/grid/fragments/responsive.md
@@ -1,5 +1,3 @@
-### 响应式
-
```js
diff --git a/docs/pages/components/grid/index.tsx b/docs/pages/components/grid/index.tsx
index 912611ede..aa12ac8d8 100644
--- a/docs/pages/components/grid/index.tsx
+++ b/docs/pages/components/grid/index.tsx
@@ -3,10 +3,5 @@ import { Grid, Button, Icon, Row, Col } from 'rsuite';
import DefaultPage from '@/components/Page';
export default function Page() {
- return (
-
- );
+ return ;
}
diff --git a/docs/pages/components/grid/zh-CN/gutter.md b/docs/pages/components/grid/zh-CN/gutter.md
deleted file mode 100644
index 2b6e2c447..000000000
--- a/docs/pages/components/grid/zh-CN/gutter.md
+++ /dev/null
@@ -1,33 +0,0 @@
-### 栅格间隔
-
-
-
-```js
-const instance = (
-
-
-
- xs={4}
-
-
- xs={4}
-
-
- xs={4}
-
-
- xs={4}
-
-
- xs={4}
-
-
- xs={4}
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/grid/zh-CN/hidden.md b/docs/pages/components/grid/zh-CN/hidden.md
deleted file mode 100644
index aec04a8a0..000000000
--- a/docs/pages/components/grid/zh-CN/hidden.md
+++ /dev/null
@@ -1,21 +0,0 @@
-### 隐藏栅格
-
-
-
-```js
-const instance = (
-
-
-
- xsHidden xs={12}
-
-
- xs={12} xs={12}
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/grid/zh-CN/index.md b/docs/pages/components/grid/zh-CN/index.md
index cfe6c4806..a7edffa51 100644
--- a/docs/pages/components/grid/zh-CN/index.md
+++ b/docs/pages/components/grid/zh-CN/index.md
@@ -17,18 +17,37 @@
## 获取组件
-```js
-import { Grid, Row, Col } from 'rsuite';
-
-//or
-import Grid from 'rsuite/lib/Grid';
-import Row from 'rsuite/lib/Row';
-import Col from 'rsuite/lib/Col';
-```
+
## 演示
-
+### 默认
+
+
+
+### 响应式
+
+
+
+### 栅格间隔
+
+
+
+### 偏移
+
+
+
+### 栅格推拉
+
+
+
+### 隐藏栅格
+
+
+
+### 嵌套
+
+
## Props
diff --git a/docs/pages/components/grid/zh-CN/offset.md b/docs/pages/components/grid/zh-CN/offset.md
deleted file mode 100644
index 34711d125..000000000
--- a/docs/pages/components/grid/zh-CN/offset.md
+++ /dev/null
@@ -1,42 +0,0 @@
-### 偏移
-
-
-
-```js
-const instance = (
-
-
-
- xs={4} xsOffset={20}
-
-
-
-
-
- xs={8} xsOffset={16}
-
-
-
-
-
- xs={12} xsOffset={12}
-
-
-
-
-
- xs={16} xsOffset={8}
-
-
-
-
-
- xs={20} xsOffset={4}
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/en-US/basic.md b/docs/pages/components/input/en-US/basic.md
deleted file mode 100644
index 465176c24..000000000
--- a/docs/pages/components/input/en-US/basic.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### Default
-
-
-
-```js
-const instance = ;
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/en-US/disabled.md b/docs/pages/components/input/en-US/disabled.md
deleted file mode 100644
index 171e1b992..000000000
--- a/docs/pages/components/input/en-US/disabled.md
+++ /dev/null
@@ -1,25 +0,0 @@
-### Disabled
-
-
-
-```js
-const styles = {
- width: 300,
- marginBottom: 10
-};
-
-const instance = (
-
-
-
-
-
-
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/en-US/index.md b/docs/pages/components/input/en-US/index.md
index 4a7087058..1d5d2c640 100644
--- a/docs/pages/components/input/en-US/index.md
+++ b/docs/pages/components/input/en-US/index.md
@@ -9,31 +9,55 @@ Instead of HTML native controls, input, textarea.
## Import
-```js
-import { Input, InputGroup } from 'rsuite';
-
-// or
-import Input from 'rsuite/lib/Input';
-import InputGroup from 'rsuite/lib/InputGroup';
-```
+
## Examples
-
+### Default
+
+
+
+### Size
+
+
+
+### Textarea
+
+
+
+### Disabled
+
+
+
+### Input Group
+
+
+
+### Inside
+
+
+
+### With Button
+
+
+
+### With Tooltip
+
+
## Props
### ` `
-| Property | Type `(Default)` | Description |
-| ------------ | ------------------------------------------------------------------ | ------------------------------------------------ |
-| classPrefix | string `('input')` | The prefix of the component CSS class |
-| defaultValue | string | Default value |
-| disabled | boolean | Disabled component |
-| onChange | (value: any, event: SyntheticInputEvent) => void | The callback function in which value is changed. |
-| size | enum: 'lg', 'md', 'sm', 'xs' `('md')` | An input can have different sizes |
-| type | string `('text' )` | HTML input type |
-| value | string | Value (Controlled) |
+| Property | Type `(Default)` | Description |
+| ------------ | ------------------------------------- | ------------------------------------------------ |
+| classPrefix | string `('input')` | The prefix of the component CSS class |
+| defaultValue | string | Default value |
+| disabled | boolean | Disabled component |
+| onChange | (value: string, event) => void | The callback function in which value is changed. |
+| size | enum: 'lg', 'md', 'sm', 'xs' `('md')` | An input can have different sizes |
+| type | string `('text' )` | HTML input type |
+| value | string | Value (Controlled) |
### ``
diff --git a/docs/pages/components/input/en-US/input-group-button.md b/docs/pages/components/input/en-US/input-group-button.md
deleted file mode 100644
index 10837c3f5..000000000
--- a/docs/pages/components/input/en-US/input-group-button.md
+++ /dev/null
@@ -1,32 +0,0 @@
-### With Button
-
-
-
-```js
-const styles = {
- width: 300,
- marginBottom: 10
-};
-
-const instance = (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
-
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/en-US/input-group-inside.md b/docs/pages/components/input/en-US/input-group-inside.md
deleted file mode 100644
index 59500e51b..000000000
--- a/docs/pages/components/input/en-US/input-group-inside.md
+++ /dev/null
@@ -1,45 +0,0 @@
-### Inside
-
-
-
-```js
-const styles = {
- width: 300,
- marginBottom: 10
-};
-
-const instance = (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $
-
- .00
-
-
-
-
-
-
-
-
-
-);
-
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/zh-CN/basic.md b/docs/pages/components/input/fragments/basic.md
similarity index 92%
rename from docs/pages/components/input/zh-CN/basic.md
rename to docs/pages/components/input/fragments/basic.md
index 1b01c2c07..265e44e49 100644
--- a/docs/pages/components/input/zh-CN/basic.md
+++ b/docs/pages/components/input/fragments/basic.md
@@ -1,5 +1,3 @@
-### 默认
-
```js
diff --git a/docs/pages/components/input/zh-CN/disabled.md b/docs/pages/components/input/fragments/disabled.md
similarity index 96%
rename from docs/pages/components/input/zh-CN/disabled.md
rename to docs/pages/components/input/fragments/disabled.md
index a998da0b2..4c9e38518 100644
--- a/docs/pages/components/input/zh-CN/disabled.md
+++ b/docs/pages/components/input/fragments/disabled.md
@@ -1,5 +1,3 @@
-### 禁用
-
```js
diff --git a/docs/pages/components/input/fragments/import.md b/docs/pages/components/input/fragments/import.md
new file mode 100644
index 000000000..78548e630
--- /dev/null
+++ b/docs/pages/components/input/fragments/import.md
@@ -0,0 +1,7 @@
+```js
+import { Input, InputGroup } from 'rsuite';
+
+// or
+import Input from 'rsuite/lib/Input';
+import InputGroup from 'rsuite/lib/InputGroup';
+```
diff --git a/docs/pages/components/input/zh-CN/input-group-button.md b/docs/pages/components/input/fragments/input-group-button.md
similarity index 97%
rename from docs/pages/components/input/zh-CN/input-group-button.md
rename to docs/pages/components/input/fragments/input-group-button.md
index 1e85f3f90..2bc72205f 100644
--- a/docs/pages/components/input/zh-CN/input-group-button.md
+++ b/docs/pages/components/input/fragments/input-group-button.md
@@ -1,5 +1,3 @@
-### 按钮
-
```js
diff --git a/docs/pages/components/input/zh-CN/input-group-inside.md b/docs/pages/components/input/fragments/input-group-inside.md
similarity index 98%
rename from docs/pages/components/input/zh-CN/input-group-inside.md
rename to docs/pages/components/input/fragments/input-group-inside.md
index 772685fc6..322101ce0 100644
--- a/docs/pages/components/input/zh-CN/input-group-inside.md
+++ b/docs/pages/components/input/fragments/input-group-inside.md
@@ -1,5 +1,3 @@
-### inside
-
```js
diff --git a/docs/pages/components/input/en-US/input-group.md b/docs/pages/components/input/fragments/input-group.md
similarity index 98%
rename from docs/pages/components/input/en-US/input-group.md
rename to docs/pages/components/input/fragments/input-group.md
index a7bdae7e5..b4310022a 100644
--- a/docs/pages/components/input/en-US/input-group.md
+++ b/docs/pages/components/input/fragments/input-group.md
@@ -1,5 +1,3 @@
-### Input Group
-
```js
diff --git a/docs/pages/components/input/en-US/size.md b/docs/pages/components/input/fragments/size.md
similarity index 99%
rename from docs/pages/components/input/en-US/size.md
rename to docs/pages/components/input/fragments/size.md
index 3df36aad2..3161317f4 100644
--- a/docs/pages/components/input/en-US/size.md
+++ b/docs/pages/components/input/fragments/size.md
@@ -1,5 +1,3 @@
-### Size
-
```js
diff --git a/docs/pages/components/input/en-US/textarea.md b/docs/pages/components/input/fragments/textarea.md
similarity index 96%
rename from docs/pages/components/input/en-US/textarea.md
rename to docs/pages/components/input/fragments/textarea.md
index ccfb00fd9..4f4891f5b 100644
--- a/docs/pages/components/input/en-US/textarea.md
+++ b/docs/pages/components/input/fragments/textarea.md
@@ -1,5 +1,3 @@
-### Textarea
-
```js
diff --git a/docs/pages/components/input/en-US/tooltip.md b/docs/pages/components/input/fragments/tooltip.md
similarity index 92%
rename from docs/pages/components/input/en-US/tooltip.md
rename to docs/pages/components/input/fragments/tooltip.md
index 9d9ddab85..3cfdb5ca7 100644
--- a/docs/pages/components/input/en-US/tooltip.md
+++ b/docs/pages/components/input/fragments/tooltip.md
@@ -1,5 +1,3 @@
-### With Tooltip
-
```js
diff --git a/docs/pages/components/input/index.tsx b/docs/pages/components/input/index.tsx
index b29b5f74b..8e363c30e 100644
--- a/docs/pages/components/input/index.tsx
+++ b/docs/pages/components/input/index.tsx
@@ -1,20 +1,10 @@
-import * as React from 'react';
+import React from 'react';
import { Input, InputNumber, InputGroup, Icon, Whisper, Tooltip, Grid, Row, Col } from 'rsuite';
import DefaultPage from '@/components/Page';
export default function Page() {
return (
);
diff --git a/docs/pages/components/input/zh-CN/index.md b/docs/pages/components/input/zh-CN/index.md
index bfd707354..1544bcdde 100644
--- a/docs/pages/components/input/zh-CN/index.md
+++ b/docs/pages/components/input/zh-CN/index.md
@@ -9,31 +9,55 @@
## 获取组件
-```js
-import { Input, InputGroup } from 'rsuite';
-
-// or
-import Input from 'rsuite/lib/Input';
-import InputGroup from 'rsuite/lib/InputGroup';
-```
+
## 演示
-
+### 默认
+
+
+
+### 尺寸
+
+
+
+### Textarea
+
+
+
+### 多行输入框
+
+
+
+### 输入框组合
+
+
+
+### Inside
+
+
+
+### 与按钮组合
+
+
+
+### 帮助提示
+
+
## Props
### ` `
-| 属性名称 | 类型 `(默认值)` | 描述 |
-| ------------ | ------------------------------------------------------------------ | ------------------------ |
-| classPrefix | string `('input')` | 组件 CSS 类的前缀 |
-| defaultValue | string | 设置默认值 |
-| disabled | boolean | 禁用 |
-| onChange | (value: any, event: SyntheticInputEvent) => void | value 发生变化的回调函数 |
-| size | enum: 'lg', 'md', 'sm', 'xs' `('md')` | 设置输入框尺寸 |
-| type | string `('text' )` | HTML input type. |
-| value | string | 设置值 `受控` |
+| 属性名称 | 类型 `(默认值)` | 描述 |
+| ------------ | ------------------------------------- | ------------------------ |
+| classPrefix | string `('input')` | 组件 CSS 类的前缀 |
+| defaultValue | string | 设置默认值 |
+| disabled | boolean | 禁用 |
+| onChange | (value: string, event) => void | value 发生变化的回调函数 |
+| size | enum: 'lg', 'md', 'sm', 'xs' `('md')` | 设置输入框尺寸 |
+| type | string `('text' )` | HTML input type. |
+| value | string | 设置值 `受控` |
### ``
diff --git a/docs/pages/components/input/zh-CN/input-group.md b/docs/pages/components/input/zh-CN/input-group.md
deleted file mode 100644
index 9f928964e..000000000
--- a/docs/pages/components/input/zh-CN/input-group.md
+++ /dev/null
@@ -1,54 +0,0 @@
-### 输入框组合
-
-
-
-```js
-const styles = {
- width: 300,
- marginBottom: 10
-};
-
-const instance = (
-
-
- @
-
-
-
-
-
- .com
-
-
-
- $
-
- .00
-
-
-
-
- to
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
-
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/zh-CN/size.md b/docs/pages/components/input/zh-CN/size.md
deleted file mode 100644
index 1baed8ee4..000000000
--- a/docs/pages/components/input/zh-CN/size.md
+++ /dev/null
@@ -1,57 +0,0 @@
-### 尺寸
-
-
-
-```js
-const styles = {
- marginBottom: 10
-};
-
-const CustomInput = ({ ...props }) => ;
-
-const CustomInputGroup = ({ placeholder, ...props }) => (
-
-
-
-
-
-
-);
-
-const CustomInputGroupWidthButton = ({ placeholder, ...props }) => (
-
-
-
-
-
-
-);
-
-const instance = (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/zh-CN/textarea.md b/docs/pages/components/input/zh-CN/textarea.md
deleted file mode 100644
index 54414eaba..000000000
--- a/docs/pages/components/input/zh-CN/textarea.md
+++ /dev/null
@@ -1,21 +0,0 @@
-### 多行输入框
-
-
-
-```js
-const instance = (
-
-
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/input/zh-CN/tooltip.md b/docs/pages/components/input/zh-CN/tooltip.md
deleted file mode 100644
index b618526cb..000000000
--- a/docs/pages/components/input/zh-CN/tooltip.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### 帮助提示
-
-
-
-```js
-const instance = (
- Required }>
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/modal/en-US/index.md b/docs/pages/components/modal/en-US/index.md
index 4ae69910d..622f296c3 100644
--- a/docs/pages/components/modal/en-US/index.md
+++ b/docs/pages/components/modal/en-US/index.md
@@ -45,6 +45,22 @@ When set to true, the Modal will display the background when it is opened. Click
+## Accessibility
+
+- Modal has role `dialog`.
+- ESC closes `Modal` unless `keyboard` is set to `false`.
+- Modal has `aria-modal` set to `true`. Tells assistive technologies that the windows underneath the current dialog are not available for interaction (inert).
+- Be sure to add `aria-labelledby`, referencing the modal title, to the Modal. Additionally, you may give a description of your modal with the `aria-describedby` prop on the Modal.
+
+```js
+
+
+ My Title
+
+ My Description
+
+```
+
## Props
### ``
diff --git a/docs/pages/components/modal/zh-CN/index.md b/docs/pages/components/modal/zh-CN/index.md
index 08e98b230..a6153ec7a 100644
--- a/docs/pages/components/modal/zh-CN/index.md
+++ b/docs/pages/components/modal/zh-CN/index.md
@@ -45,6 +45,22 @@
+## 无障碍设计
+
+- Modal 拥有一个值为 `dialog` 的 `role` 属性。
+- Modal 将 `aria-modal` 设置为 `true`。 告诉辅助技术当前对话框下方的窗口不可用于交互(惰性)。
+- ESC 可以关闭 `Modal`,同时也可以通过设置 `keyboard:false` 禁用它。
+- 不要忘记用 `aria-labelledby` 属性来指向 Modal 的标题。 使用 `aria-describedby` 属性来为 Modal 组件添加一段描述。
+
+```js
+
+
+ My Title
+
+ My Description
+
+```
+
## Props
### ``
diff --git a/docs/pages/components/multi-cascader/zh-CN/appearance.md b/docs/pages/components/multi-cascader/zh-CN/appearance.md
deleted file mode 100644
index d913e7701..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/appearance.md
+++ /dev/null
@@ -1,21 +0,0 @@
-### 外观
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
-
-
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/async.md b/docs/pages/components/multi-cascader/zh-CN/async.md
deleted file mode 100644
index 10feb287e..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/async.md
+++ /dev/null
@@ -1,79 +0,0 @@
-### 异步
-
-
-
-```js
-function createNode() {
- return {
- label: `Node${(Math.random() * 1e18).toString(36).slice(0, 3).toUpperCase()}`,
- value: Math.random() * 1e18,
- children: Math.random() > 0.5 ? [] : null
- };
-}
-
-function createChildren() {
- const children = [];
- for (let i = 0; i < Math.random() * 10; i++) {
- children.push(createNode());
- }
- return children;
-}
-
-function getChildrenByNode(node, callback) {
- setTimeout(() => {
- callback(createChildren());
- }, 500);
-}
-
-class AsynExample extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: createChildren()
- };
- this.handleSelect = this.handleSelect.bind(this);
- this.handleChange = this.handleChange.bind(this);
- }
- handleSelect(node, activePaths, concat, event) {
- if (node.children && !node.children.length) {
- getChildrenByNode(node, children => {
- this.setState({ data: concat(this.state.data, children) });
- });
- }
- }
-
- handleChange(value, event) {
- console.log(value, 'onChange');
- this.setState({ value });
- }
-
- renderMenu(children, menu, parentNode) {
- if (children.length === 0) {
- return (
-
- 加载中...
-
- );
- }
- return menu;
- }
- render() {
- return (
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/basic.md b/docs/pages/components/multi-cascader/zh-CN/basic.md
deleted file mode 100644
index 67f5f73f9..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/basic.md
+++ /dev/null
@@ -1,23 +0,0 @@
-### 默认
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/block.md b/docs/pages/components/multi-cascader/zh-CN/block.md
deleted file mode 100644
index acc77af54..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/block.md
+++ /dev/null
@@ -1,15 +0,0 @@
-### 撑满
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = ;
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/cascade.md b/docs/pages/components/multi-cascader/zh-CN/cascade.md
deleted file mode 100644
index 9d844bc81..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/cascade.md
+++ /dev/null
@@ -1,47 +0,0 @@
-### 级联选择
-
-
-
-```js
-class Demo extends React.Component {
- constructor() {
- super();
- this.state = {
- cascade: true,
- value: []
- };
- this.handleToggle = this.handleToggle.bind(this);
- this.handleChange = this.handleChange.bind(this);
- }
- handleToggle(checked) {
- this.setState({
- value: [],
- cascade: checked
- });
- }
- handleChange(value) {
- this.setState({
- value
- });
- }
- render() {
- return (
-
- Cascade:
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/container.md b/docs/pages/components/multi-cascader/zh-CN/container.md
deleted file mode 100644
index 5233a53a0..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/container.md
+++ /dev/null
@@ -1,59 +0,0 @@
-### 容器与防止溢出
-
-
-
-```js
-/**
- * PreventOverflowContainer from
- * https://github.com/rsuite/rsuite/blob/master/docs/components/PreventOverflowContainer.tsx
- */
-
-const placements = ['bottomStart', 'topStart', 'autoVerticalStart'];
-
-class Demo extends React.Component {
- constructor() {
- super();
- this.state = {
- placement: 'bottomStart'
- };
- }
- render() {
- const { placement } = this.state;
- return (
-
-
{
- this.setState({ placement });
- }}
- >
- {placements.map(item => (
-
- {item}
-
- ))}
-
-
-
- {getContainer => (
-
- )}
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/controlled.md b/docs/pages/components/multi-cascader/zh-CN/controlled.md
deleted file mode 100644
index 315f28151..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/controlled.md
+++ /dev/null
@@ -1,40 +0,0 @@
-### 受控
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-class Demo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- value: ['1-1', '1-2', '1-3']
- };
- this.handleChange = this.handleChange.bind(this);
- }
- handleChange(value) {
- console.log('handleChange', value);
- this.setState({
- value
- });
- }
- render() {
- return (
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/custom-toggle.md b/docs/pages/components/multi-cascader/zh-CN/custom-toggle.md
deleted file mode 100644
index 1fa5335f3..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/custom-toggle.md
+++ /dev/null
@@ -1,21 +0,0 @@
-### 和按钮组合
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
-
-
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/custom.md b/docs/pages/components/multi-cascader/zh-CN/custom.md
deleted file mode 100644
index 05cd19aa5..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/custom.md
+++ /dev/null
@@ -1,40 +0,0 @@
-### 自定义选项
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
- {
- return (
-
- {label}
-
- );
- }}
- placeholder={
-
- 地区
-
- }
- renderValue={(value, selectedItems, selectedElement) => (
-
-
- 地区 :
- {' '}
- {selectedItems.map(item => item.label).join(' , ')}
-
- )}
- />
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/default-value.md b/docs/pages/components/multi-cascader/zh-CN/default-value.md
deleted file mode 100644
index 6423b11d0..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/default-value.md
+++ /dev/null
@@ -1,28 +0,0 @@
-### 默认值
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/disabled.md b/docs/pages/components/multi-cascader/zh-CN/disabled.md
deleted file mode 100644
index 142e10cf9..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/disabled.md
+++ /dev/null
@@ -1,22 +0,0 @@
-### 禁用
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/index.md b/docs/pages/components/multi-cascader/zh-CN/index.md
index b42919806..6b52f99aa 100644
--- a/docs/pages/components/multi-cascader/zh-CN/index.md
+++ b/docs/pages/components/multi-cascader/zh-CN/index.md
@@ -2,17 +2,67 @@
对有层级关系结构的数据进行多项选择。
-- ``
-
## 获取组件
-```js
-import { MultiCascader } from 'rsuite';
-```
+
## 演示
-
+### 默认
+
+
+
+### 外观
+
+
+
+### 尺寸
+
+
+
+### 级联
+
+
+
+### 默认值
+
+
+
+### 受控
+
+
+
+### 撑满
+
+
+
+### 位置
+
+
+
+### 自定义选项
+
+
+
+### 禁用
+
+
+
+### 不可选状态
+
+
+
+### 异步
+
+
+
+### 容器与防止溢出
+
+
+
+### Inline
+
+
## Props
diff --git a/docs/pages/components/multi-cascader/zh-CN/inline.md b/docs/pages/components/multi-cascader/zh-CN/inline.md
deleted file mode 100644
index 5461307b6..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/inline.md
+++ /dev/null
@@ -1,17 +0,0 @@
-### Inline
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/placement.md b/docs/pages/components/multi-cascader/zh-CN/placement.md
deleted file mode 100644
index 624ca3ce4..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/placement.md
+++ /dev/null
@@ -1,24 +0,0 @@
-### 位置
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const CustomMultiCascader = ({ placement }) => (
-
-);
-
-const instance = (
-
- {' '}
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/size.md b/docs/pages/components/multi-cascader/zh-CN/size.md
deleted file mode 100644
index 8960c4e81..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/size.md
+++ /dev/null
@@ -1,23 +0,0 @@
-### 尺寸
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const styles = { width: 224, display: 'block', marginBottom: 10 };
-const instance = (
-
-
-
-
-
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/multi-cascader/zh-CN/uncheckable.md b/docs/pages/components/multi-cascader/zh-CN/uncheckable.md
deleted file mode 100644
index 22e2bfda5..000000000
--- a/docs/pages/components/multi-cascader/zh-CN/uncheckable.md
+++ /dev/null
@@ -1,24 +0,0 @@
-### 不可选状态
-
-
-
-```js
-/**
- * import data from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/province-simplified.json
- */
-
-const instance = (
-
- selectedItems.map(item => item.label).join(' , ')}
- uncheckableItemValues={['1', '2', '2-1']}
- />
-
-);
-ReactDOM.render(instance);
-```
-
-
diff --git a/docs/pages/components/popover/fragments/container.md b/docs/pages/components/popover/fragments/container.md
index 4fd24fe22..779ad31aa 100644
--- a/docs/pages/components/popover/fragments/container.md
+++ b/docs/pages/components/popover/fragments/container.md
@@ -19,6 +19,7 @@ const App = () => (
(
}
>
{placement}
diff --git a/docs/pages/components/popover/fragments/trigger.md b/docs/pages/components/popover/fragments/trigger.md
index d1c505c12..4a291c9fb 100644
--- a/docs/pages/components/popover/fragments/trigger.md
+++ b/docs/pages/components/popover/fragments/trigger.md
@@ -12,7 +12,7 @@ const speaker = (
);
const TriggerMethod = () => {
- const triggerRef = React.createRef();
+ const triggerRef = React.useRef();
const open = () => triggerRef.current.open();
const close = () => triggerRef.current.close();
@@ -33,19 +33,25 @@ const TriggerMethod = () => {
const App = () => (
-
+
Click
-
+
Focus
-
+
Active
-
+
Hover
-
+
Hover + Enterable
diff --git a/docs/pages/components/popover/fragments/with-dropdown.md b/docs/pages/components/popover/fragments/with-dropdown.md
index e17cfb895..473762add 100644
--- a/docs/pages/components/popover/fragments/with-dropdown.md
+++ b/docs/pages/components/popover/fragments/with-dropdown.md
@@ -24,6 +24,7 @@ const WithDropdown = () => {
return (
}
diff --git a/docs/pages/components/rate/zh-CN/index.md b/docs/pages/components/rate/zh-CN/index.md
index e392b0bc3..6aba77cfa 100644
--- a/docs/pages/components/rate/zh-CN/index.md
+++ b/docs/pages/components/rate/zh-CN/index.md
@@ -48,13 +48,13 @@
### 字符
-你可以使用其他 icon、emoji、数字、中文或是其他自定义的图案
+您可以使用其他 icon、emoji、数字、中文或是其他自定义的图案
### 自定义渲染
-当有多级评价时,你可以自定义每级展现的 character,不过这需要你自己实现
+当有多级评价时,您可以自定义每级展现的 character,不过这需要您自己实现
diff --git a/docs/pages/components/table/en-US/affix-horizontal-scrollbar.md b/docs/pages/components/table/en-US/affix-horizontal-scrollbar.md
deleted file mode 100644
index 295d79876..000000000
--- a/docs/pages/components/table/en-US/affix-horizontal-scrollbar.md
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-function AffixHorizontalScrollbarTable() {
- return (
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Company Name
- |
-
-
- Company Name
- |
-
-
- Company Name
- |
-
-
- Company Name
- |
-
-
- Company Name
- |
-
-
- Company Name
- |
-
-
- Company Name
- |
-
-
- Company Name
- |
-
-
- );
-}
-ReactDOM.render(
);
-```
-
-
diff --git a/docs/pages/components/table/en-US/colspan.md b/docs/pages/components/table/en-US/colspan.md
deleted file mode 100644
index 07f0c3c22..000000000
--- a/docs/pages/components/table/en-US/colspan.md
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-```js
-/**
- * import fakeDataForColSpan from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users-colspan.json
- */
-
-class ColspanTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: fakeDataForColSpan
- };
- }
- render() {
- return (
-
-
{
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
-
- Address
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render(
);
-```
-
-
-
-In some cases, you need to merge the relationships between columns to organize your data, and you can set a `ColSpan` attribute on the `
` component,and set the header grouping through``. for example:
-
-```js
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-```
-
-> When `lastName` corresponds to a column value of `null` or `undefined`, it is merged by the `firstName` column.
diff --git a/docs/pages/components/table/en-US/custom-cell.md b/docs/pages/components/table/en-US/custom-cell.md
deleted file mode 100644
index f10c32db3..000000000
--- a/docs/pages/components/table/en-US/custom-cell.md
+++ /dev/null
@@ -1,270 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const NameCell = ({ rowData, dataKey, ...props }) => {
- const speaker = (
-
-
- Name: {`${rowData.firstName} ${rowData.lastName}`}{' '}
-
-
- Email: {rowData.email}{' '}
-
-
- Company: {rowData.companyName}{' '}
-
-
- Sentence: {rowData.sentence}{' '}
-
-
- );
-
- return (
-
-
- {rowData[dataKey].toLocaleString()}
-
- |
- );
-};
-
-const ImageCell = ({ rowData, dataKey, ...props }) => (
-
-
-
-
- |
-);
-
-const CheckCell = ({ rowData, onChange, checkedKeys, dataKey, ...props }) => (
-
-
- item === rowData[dataKey])}
- />
-
- |
-);
-
-const Menu = ({ onSelect }) => (
-
- Download As...
- Export PDF
- Export HTML
- Settings
- About
-
-);
-
-const MenuPopover = ({ onSelect, ...rest }) => (
-
-
-
-);
-
-let tableBody;
-
-class CustomWhisper extends React.Component {
- constructor(props) {
- super(props);
- this.handleSelectMenu = this.handleSelectMenu.bind(this);
- }
- handleSelectMenu(eventKey, event) {
- console.log(eventKey);
- this.trigger.hide();
- }
- render() {
- return (
- {
- this.trigger = ref;
- }}
- container={() => {
- return tableBody;
- }}
- speaker={ }
- >
- {this.props.children}
-
- );
- }
-}
-
-const ActionCell = ({ rowData, dataKey, ...props }) => {
- function handleAction() {
- alert(`id:${rowData[dataKey]}`);
- }
- return (
-
- } />
-
-
- } />
-
- |
- );
-};
-
-const data = fakeData.filter((v, i) => i < 20);
-class CustomColumnTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- checkedKeys: [],
- data
- };
- this.handleCheckAll = this.handleCheckAll.bind(this);
- this.handleCheck = this.handleCheck.bind(this);
- }
- handleCheckAll(value, checked) {
- const checkedKeys = checked ? data.map(item => item.id) : [];
- this.setState({
- checkedKeys
- });
- }
- handleCheck(value, checked) {
- const { checkedKeys } = this.state;
- const nextCheckedKeys = checked
- ? [...checkedKeys, value]
- : checkedKeys.filter(item => item !== value);
-
- this.setState({
- checkedKeys: nextCheckedKeys
- });
- }
- render() {
- const { data, checkedKeys } = this.state;
-
- let checked = false;
- let indeterminate = false;
-
- if (checkedKeys.length === data.length) {
- checked = true;
- } else if (checkedKeys.length === 0) {
- checked = false;
- } else if (checkedKeys.length > 0 && checkedKeys.length < data.length) {
- indeterminate = true;
- }
-
- return (
-
-
{
- tableBody = ref;
- }}
- >
-
-
-
-
-
-
-
-
-
- Avartar
-
-
-
-
- First Name
-
-
-
-
- Email
- {rowData => {rowData.email} } |
-
-
-
- Action
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-Depending on your business scenario, you can define what you want to display in a cell, such as displaying a picture, like adding a few buttons, or displaying a text box that you can customize, and simply redefining the `Cell` component.
-
-For example, display a picture, define a `Imagecell` component:
-
-```js
-const ImageCell = ({ rowData, dataKey, ...props }) => (
-
-
- |
-);
-```
-
-Use:
-
-```html
-
- Avartar
-
-
-```
-
-The `children` property support function on `` can get `rowData` to return a new `children`.
-
-Use:
-
-```html
-
- Date
- {rowData => rowData.date.toLocaleString()} |
-
-```
-
----
-
-**Custom row height**
-
-If you need to define row heights based on the content of your data in practical applications, you can use the following methods:
-
-```html
- {
- if (rowData.firstName === 'Janis') {
- return 30;
- }
- }}
- >
-...
-
-```
diff --git a/docs/pages/components/table/en-US/default.md b/docs/pages/components/table/en-US/default.md
deleted file mode 100644
index 72fa44152..000000000
--- a/docs/pages/components/table/en-US/default.md
+++ /dev/null
@@ -1,86 +0,0 @@
-### Default
-
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class FixedColumnTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: fakeData
- };
- }
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
- Action
-
-
- {rowData => {
- function handleAction() {
- alert(`id:${rowData.id}`);
- }
- return (
-
- Edit | Remove
-
- );
- }}
- |
-
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/en-US/draggable.md b/docs/pages/components/table/en-US/draggable.md
deleted file mode 100644
index c259762a8..000000000
--- a/docs/pages/components/table/en-US/draggable.md
+++ /dev/null
@@ -1,150 +0,0 @@
-
-
-```js
-const style = {
- border: '1px dashed gray',
- padding: '0.5rem 1rem',
- cursor: 'move'
-};
-
-const ItemTypes = {
- COLUMN: 'column',
- ROW: 'row'
-};
-
-function DraggableHeaderCell({ children, onDrag, id, ...rest }) {
- const ref = React.useRef(null);
-
- const [{ canDrop, isOver }, drop] = useDrop({
- accept: ItemTypes.COLUMN,
- collect: monitor => ({
- isOver: monitor.isOver(),
- canDrop: monitor.canDrop()
- }),
- drop(item, monitor) {
- onDrag(item.id, id);
- }
- });
-
- const [{ isDragging }, drag] = useDrag({
- item: { id, type: ItemTypes.COLUMN },
- collect: monitor => ({
- isDragging: monitor.isDragging()
- })
- });
- const opacity = isDragging ? 0 : 1;
- const isActive = canDrop && isOver;
-
- drag(drop(ref));
-
- const styles = {
- ...style,
- opacity: isDragging ? 0 : 1,
- background: isActive ? '#ddd' : null
- };
-
- return (
-
-
- {children}
-
-
- );
-}
-
-function DraggableCell({ children, onDrag, id, rowData, ...rest }) {
- const ref = React.useRef(null);
-
- const [{ canDrop, isOver }, drop] = useDrop({
- accept: ItemTypes.ROW,
- collect: monitor => ({
- isOver: monitor.isOver(),
- canDrop: monitor.canDrop()
- }),
- drop(item, monitor) {
- onDrag && onDrag(item.id, rowData.id);
- }
- });
-
- const [{ isDragging }, drag] = useDrag({
- item: { id: rowData.id, type: ItemTypes.ROW },
- collect: monitor => ({
- isDragging: monitor.isDragging()
- })
- });
- const opacity = isDragging ? 0 : 1;
- const isActive = canDrop && isOver;
-
- drag(drop(ref));
-
- const styles = {
- ...style,
- opacity: isDragging ? 0.5 : 1,
- background: isActive ? '#ddd' : null
- };
-
- return (
-
-
- {children}
-
- |
- );
-}
-
-function sort(source, sourceId, targetId) {
- const nextData = source.filter(item => item.id !== sourceId);
- const dragItem = source.find(item => item.id === sourceId);
- const index = nextData.findIndex(item => item.id === targetId);
-
- nextData.splice(index + 1, 0, dragItem);
- return nextData;
-}
-
-function DraggableTable() {
- const [data, setData] = React.useState(fakeData.filter((item, index) => index < 7));
- const [columns, setColumns] = React.useState([
- { id: 'id', name: 'Id', width: 80 },
- { id: 'firstName', name: 'First Name', width: 200 },
- { id: 'lastName', name: 'Last Name', width: 200 },
- { id: 'email', name: 'Email', width: 300 },
- { id: 'action', name: 'Action', width: 100 }
- ]);
-
- const handleDragColumn = (sourceId, targetId) => {
- setColumns(sort(columns, sourceId, targetId));
- };
-
- const handleDragRow = (sourceId, targetId) => {
- setData(sort(data, sourceId, targetId));
- };
-
- return (
-
-
-
- {columns.map(column => (
-
-
- {column.name}
-
-
- {column.id === 'action' ? (
-
-
-
- ) : (
- |
- )}
-
- ))}
-
-
-
- );
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/en-US/expanded.md b/docs/pages/components/table/en-US/expanded.md
deleted file mode 100644
index 8809475f0..000000000
--- a/docs/pages/components/table/en-US/expanded.md
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const rowKey = 'id';
-const ExpandCell = ({ rowData, dataKey, expandedRowKeys, onChange, ...props }) => (
-
- {
- onChange(rowData);
- }}
- icon={
- key === rowData[rowKey])
- ? 'minus-square-o'
- : 'plus-square-o'
- }
- />
- }
- />
- |
-);
-
-class ExpandedTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: fakeData,
- expandedRowKeys: []
- };
- this.handleExpanded = this.handleExpanded.bind(this);
- }
- handleExpanded(rowData, dataKey) {
- const { expandedRowKeys } = this.state;
-
- let open = false;
- const nextExpandedRowKeys = [];
-
- expandedRowKeys.forEach(key => {
- if (key === rowData[rowKey]) {
- open = true;
- } else {
- nextExpandedRowKeys.push(key);
- }
- });
-
- if (!open) {
- nextExpandedRowKeys.push(rowData[rowKey]);
- }
- this.setState({
- expandedRowKeys: nextExpandedRowKeys
- });
- }
- render() {
- const { expandedRowKeys, data } = this.state;
- return (
- {
- console.log(data);
- }}
- renderRowExpanded={rowData => {
- return (
-
-
-
-
- {rowData.email}
- {rowData.date}
-
- );
- }}
- >
-
- #
-
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
-
-To implement a Table that can be expanded, a combination of the following attributes is required.
-
-**Step 1: Set properties for Table**
-
-- renderRowExpanded(rowData) => ReactNode: Used to return content that needs to be rendered in the expansion panel
-- rowExpandedHeight: Sets the height of the expandable area. The default is 100
-- expandedRowKeys (controlled) and defaultExpandedRowKeys are used to configure the rows that need to be expanded. Note that the parameters that these two properties receive are an array of Rowkey in the array.。
-- rowKey: Give each row of data to a unique key, corresponding to a unique value in the key.
-
-**Step 2:Custom Cell**
-
-Customize a Cell and put a button inside to manipulate the value in expandedRowKeys.
diff --git a/docs/pages/components/table/en-US/fixed.md b/docs/pages/components/table/en-US/fixed.md
deleted file mode 100644
index 77fd42ebe..000000000
--- a/docs/pages/components/table/en-US/fixed.md
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const ActionCell = ({ rowData, dataKey, ...props }) => {
- function handleAction() {
- alert(`id:${rowData[dataKey]}`);
- }
- return (
-
- } />
- |
- );
-};
-
-class FixedTable extends React.Component {
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Action
-
-
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/en-US/fluid-column.md b/docs/pages/components/table/en-US/fluid-column.md
deleted file mode 100644
index 9f6670f57..000000000
--- a/docs/pages/components/table/en-US/fluid-column.md
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class FluidColumnTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data
- };
- }
-
- render() {
- const { data } = this.state;
- return (
-
- {
- console.log(sortColumn, sortType);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
-
- City flexGrow={1}
-
- |
-
-
-
-
- Company Name flexGrow={2}
-
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-If you need to set a column to automatic width, you need to configure the `flexGrow` property. `flexGrow` is a `number` type. Will fill the `Table` remaining width according to the sum of all `flexGrow`.
-
-> Note: After setting `flexGrow`, you cannot set the `width` and `resizable` properties. You can set a minimum width by `minwidth`.
-
-```html
-
- City flexGrow={1}
- |
-
-
-
- Company Name flexGrow={2}
- |
-
-
-...
-```
diff --git a/docs/pages/components/table/en-US/index.md b/docs/pages/components/table/en-US/index.md
index b44d34ad6..a7855e1c0 100644
--- a/docs/pages/components/table/en-US/index.md
+++ b/docs/pages/components/table/en-US/index.md
@@ -4,21 +4,272 @@ A table displays rows of data.
- `` Table component
- `` Table definition column component
+- `` Used for column header grouping
- `` Column Header cell component
- `` Cell component
- `` Table paging component
-## Usage
+## Import
+
+
+
+## Examples
+
+### Fixed Column
+
+
+
+### Virtualized
+
+Support `virtualized`, effectively render large tabular data.
+
+
+
+### Resizable
+
+
+
+Move the mouse to the column split line, will display a blue move handle, click Not to loosen and drag left and right to adjust the width of the column.
+
+To support this feature, you need to set a `resizable` attribute in `Column`.
+
+### Fluid
+
+
+
+If you need to set a column to automatic width, you need to configure the `flexGrow` property. `flexGrow` is a `number` type. Will fill the `Table` remaining width according to the sum of all `flexGrow`.
+
+> Note: After setting `flexGrow`, you cannot set the `width` and `resizable` properties. You can set a minimum width by `minwidth`.
+
+```html
+
+ City flexGrow={1}
+ |
+
+
+
+ Company Name flexGrow={2}
+ |
+
+
+...
+```
+
+### Custom Cell
+
+
+
+Depending on your business scenario, you can define what you want to display in a cell, such as displaying a picture, like adding a few buttons, or displaying a text box that you can customize, and simply redefining the `Cell` component.
+
+For example, display a picture, define a `Imagecell` component:
```js
-import { Table } from 'rsuite';
+const ImageCell = ({ rowData, dataKey, ...props }) => (
+
+
+ |
+);
+```
+
+Use:
-const { Column, HeaderCell, Cell, Pagination } = Table;
+```html
+
+ Avartar
+
+
```
-## Examples
+The `children` property support function on `` can get `rowData` to return a new `children`.
+
+Use:
+
+```html
+
+ Date
+ {rowData => rowData.date.toLocaleString()} |
+
+```
+
+---
+
+**Custom row height**
+
+If you need to define row heights based on the content of your data in practical applications, you can use the following methods:
+
+```js
+ {
+ if (rowData.firstName === 'Janis') {
+ return 30;
+ }
+ }}
+>
+ ...
+
+```
+
+### Sort
+
+
+
+Set a `sortable` attribute in the column `` that you want to sort.
+
+While the `` defines a `onSortColumn` callback function, clicking the column header to sort the icon triggers the method and returns `sortColumn` and `sortType`.
+
+```html
+ { console.log(sortColumn, sortType); }} >
+
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+...
+```
+
+### Pagination
+
+
+
+### Tree
+
+
+
+A tree table, primarily to show structured data, requires a `isTree` attribute to be set on the `Table` component, while the `data` is used to define the relational structure through `children`.
+
+```js
+const data = [
+ {
+ id: '1',
+ labelName: 'Car',
+ status: 'ENABLED',
+ children: [
+ {
+ id: '1-1',
+ labelName: 'Mercedes Benz',
+ status: 'ENABLED',
+ count: 460
+ }
+ ]
+ }
+];
+;
+```
+
+**Dealing with related properties for a tree table**
+
+- `defaultExpandAllRows:boolean` :Expand all nodes By default
+- `expandedRowKeys` (controlled) and `defaultExpandedRowKeys` are used to configure the rows that need to be expanded. Note that the parameters that these two properties receive are an array of Rowkey in the array.。
+- `rowKey`: Give each row of data to a unique key, corresponding to a unique value in the key. (You can set the rowKey in ``, the default value is `key`)
+- `renderTreeToggle:() => ReactNode` : Custom Toggle
+- `onExpandChange:(expanded:boolean,rowData:object) => void`: To open/close a node's callback function
+
+### Expandable
+
+
+
+To implement a Table that can be expanded, a combination of the following attributes is required.
+
+**Step 1: Set properties for Table**
+
+- `renderRowExpanded(rowData) => ReactNode`: Used to return content that needs to be rendered in the expansion panel
+- `rowExpandedHeight`: Sets the height of the expandable area. The default is 100
+- `expandedRowKeys` (controlled) and `defaultExpandedRowKeys` are used to configure the rows that need to be expanded. Note that the parameters that these two properties receive are an array of Rowkey in the array.。
+- `rowKey`: Give each row of data to a unique key, corresponding to a unique value in the key.
+
+**Step 2:Custom Cell**
+
+Customize a `Cell` and put a button inside to manipulate the value in `expandedRowKeys`.
+
+### Editable
+
+
+
+> Editable tables, just customize a `Cell` on the line
+
+```js
+export const EditCell = ({ rowData, dataKey, onChange, ...props }) => {
+ return (
+
+ {rowData.status === 'EDIT' ? (
+ {
+ onChange && onChange(rowData.id, dataKey, event.target.value);
+ }}
+ />
+ ) : (
+ rowData[dataKey]
+ )}
+ |
+ );
+};
+```
+
+### Loading
+
+
+
+When the data is in an asynchronous fetch, you need to display a `loading` state, just set the `loading` property on the ``.
+
+### Colspan
+
+
+
+In some cases, you need to merge the relationships between columns to organize your data, and you can set a `ColSpan` attribute on the `` component,and set the header grouping through``. for example:
+
+```js
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+```
+
+> When `lastName` corresponds to a column value of `null` or `undefined`, it is merged by the `firstName` column.
+
+### Summary
+
+
+
+### Word Wrap
+
+
+
+If you want the cell to wrap, you just need to set `wordWrap`
+
+### Affix header & scrollbar
+
+- `autoHeight`: Table will expand the height according to the content.
+- `affixHeader`: Affix the table header to the specified location on the page.
+- `affixHorizontalScrollbar`: Affix the table horizontal scrollbar to the specified position on the page.
+
+
+
+### Draggable(with react-dnd)
+
+https://codesandbox.io/s/rsuite-table-with-react-dnd-m06cm
+
+## Accessibility
-
+- `` has role `grid`.
+- `` has role `treegrid`, when `` is set with `isTree`.
+- `` has role `columnheader`.
+- `` has role `gridcell`.
+- Rows dynamically generated from data in the `` has role `row`.
## Props
@@ -32,7 +283,7 @@ const { Column, HeaderCell, Cell, Pagination } = Table;
| bodyRef | Ref | A ref attached to the table body element |
| bordered | boolean | Show border |
| cellBordered | boolean | Show cell border |
-| data \* | Array<Object> | Table data |
+| data \* | object[] | Table data |
| defaultExpandAllRows | boolean | Expand all nodes By default |
| defaultExpandedRowKeys | string[] | Specify the default expanded row by `rowkey` |
| defaultSortType | enum: 'desc', 'asc' | Sort type |
@@ -68,7 +319,7 @@ const { Column, HeaderCell, Cell, Pagination } = Table;
- scrollTop
-垂直滚动条滚动到指定位置
+The vertical scroll bar scrolls to the specified position
```ts
scrollTop: (top: number) => void;
@@ -76,7 +327,7 @@ scrollTop: (top: number) => void;
- scrollLeft
-横向滚动条滚动到指定位置
+The horizontal scroll bar scrolls to the specified position
```ts
scrollLeft: (left: number) => void;
@@ -127,7 +378,7 @@ scrollLeft: (left: number) => void;
| displayLength | number `(30)` | Configure how many lines of entries per page to display, corresponding to `lengthMenu` |
| first | boolean `(true)` | Show first page button |
| last | boolean `(true)` | Show last Page button |
-| lengthMenu | Array<number> | Paging display row number configuration, defaults to 30, 50, 100 |
+| lengthMenu | number[] | Paging display row number configuration, defaults to 30, 50, 100 |
| maxButtons | number `(5)` | Configure the maximum number of display buttons |
| next | boolean `(true)` | Show Next Page button |
| onChangeLength | (eventKey: number) => void | The callback function that triggers when the `lengthmenu` value changes |
diff --git a/docs/pages/components/table/en-US/large.md b/docs/pages/components/table/en-US/large.md
deleted file mode 100644
index 27fb5b653..000000000
--- a/docs/pages/components/table/en-US/large.md
+++ /dev/null
@@ -1,57 +0,0 @@
-### Virtualized large table
-
-Support `virtualized`, effectively render large tabular data.
-
-
-
-```js
-class LargeTable extends React.Component {
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/en-US/loading.md b/docs/pages/components/table/en-US/loading.md
deleted file mode 100644
index 1f2b49719..000000000
--- a/docs/pages/components/table/en-US/loading.md
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class LoadingTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data,
- loading: true
- };
- this.handleToggle = this.handleToggle.bind(this);
- }
- handleToggle(loading) {
- this.setState({ loading });
- }
- render() {
- const { loading } = this.state;
- return (
-
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
-
- Loading:
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-When the data is in an asynchronous fetch, you need to display a `loading` state, just set the `loading` property on the ``.
diff --git a/docs/pages/components/table/en-US/pagination.md b/docs/pages/components/table/en-US/pagination.md
deleted file mode 100644
index 5d76ad053..000000000
--- a/docs/pages/components/table/en-US/pagination.md
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class PaginationTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- displayLength: 10,
- loading: false,
- page: 1
- };
- this.handleChangePage = this.handleChangePage.bind(this);
- this.handleChangeLength = this.handleChangeLength.bind(this);
- }
- handleChangePage(dataKey) {
- this.setState({
- page: dataKey
- });
- }
- handleChangeLength(dataKey) {
- this.setState({
- page: 1,
- displayLength: dataKey
- });
- }
- getData() {
- const { displayLength, page } = this.state;
-
- return fakeData.filter((v, i) => {
- const start = displayLength * (page - 1);
- const end = start + displayLength;
- return i >= start && i < end;
- });
- }
- render() {
- const data = this.getData();
- const { loading, displayLength, page } = this.state;
-
- return (
-
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
- Company Name
- |
-
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/en-US/resizable.md b/docs/pages/components/table/en-US/resizable.md
deleted file mode 100644
index eb6f0a8d3..000000000
--- a/docs/pages/components/table/en-US/resizable.md
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class ResizableColumnTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data
- };
- }
- render() {
- const { data } = this.state;
- return (
-
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-Move the mouse to the column split line, will display a blue move handle, click Not to loosen and drag left and right to adjust the width of the column.
-
-To support this feature, you need to set a `resizable` attribute in `Column`.
diff --git a/docs/pages/components/table/en-US/sort.md b/docs/pages/components/table/en-US/sort.md
deleted file mode 100644
index 86a483307..000000000
--- a/docs/pages/components/table/en-US/sort.md
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class SortTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- addColumn: false,
- data
- };
- this.handleSortColumn = this.handleSortColumn.bind(this);
- }
-
- getData() {
- const { data, sortColumn, sortType } = this.state;
-
- if (sortColumn && sortType) {
- return data.sort((a, b) => {
- let x = a[sortColumn];
- let y = b[sortColumn];
- if (typeof x === 'string') {
- x = x.charCodeAt();
- }
- if (typeof y === 'string') {
- y = y.charCodeAt();
- }
- if (sortType === 'asc') {
- return x - y;
- } else {
- return y - x;
- }
- });
- }
- return data;
- }
-
- handleSortColumn(sortColumn, sortType) {
- this.setState({
- loading: true
- });
-
- setTimeout(() => {
- this.setState({
- sortColumn,
- sortType,
- loading: false
- });
- }, 500);
- }
-
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-Set a `sortable` attribute in the column `` that you want to sort.
-
-While the `` defines a `onSortColumn` callback function, clicking the column header to sort the icon triggers the method and returns `sortColumn` and `sortType`.
-
-```html
- { console.log(sortColumn, sortType); }} >
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-...
-```
diff --git a/docs/pages/components/table/en-US/summary.md b/docs/pages/components/table/en-US/summary.md
deleted file mode 100644
index c6dfe8538..000000000
--- a/docs/pages/components/table/en-US/summary.md
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const thousands = value => `${value}`.replace(/(?=(?!(\b))(\d{3})+$)/g, '$1,');
-
-const NumberCell = ({ rowData, dataKey, ...props }) => (
- {thousands(rowData[dataKey])} |
-);
-
-const HeaderSummary = ({ title, summary }) => (
-
- {title}
-
- {thousands(summary)}
-
-
-);
-
-const data = fakeData.filter((v, i) => i < 10);
-class CustomColumnTable extends React.Component {
- render() {
- let stars = 0;
- let followers = 0;
- data.forEach(item => {
- stars += item.stars;
- followers += item.followers;
- });
-
- return (
-
-
-
- First Name
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/en-US/tree.md b/docs/pages/components/table/en-US/tree.md
deleted file mode 100644
index cc4ef0f9e..000000000
--- a/docs/pages/components/table/en-US/tree.md
+++ /dev/null
@@ -1,88 +0,0 @@
-
-
-```js
-/**
- * import fakeTreeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/tree-data.json
- */
-
-class TreeTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: fakeTreeData
- };
- }
- render() {
- const { data } = this.state;
- return (
-
- {
- console.log(isOpen, rowData);
- }}
- renderTreeToggle={(icon, rowData) => {
- if (rowData.children && rowData.children.length === 0) {
- return ;
- }
- return icon;
- }}
- >
-
- Label
- |
-
-
-
- Status
- |
-
-
-
- Count
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-A tree table, primarily to show structured data, requires a `isTree` attribute to be set on the `Table` component, while the `data` is used to define the relational structure through `children`.
-
-```js
-const data = [
- {
- id: '1',
- labelName: 'Car',
- status: 'ENABLED',
- children: [
- {
- id: '1-1',
- labelName: 'Mercedes Benz',
- status: 'ENABLED',
- count: 460
- }
- ]
- }
-];
-;
-```
-
-**Dealing with related properties for a tree table**
-
-- defaultExpandAllRows:boolean :Expand all nodes By default
-- expandedRowKeys (controlled) and defaultExpandedRowKeys are used to configure the rows that need to be expanded. Note that the parameters that these two properties receive are an array of Rowkey in the array.。
-- rowKey : Give each row of data to a unique key, corresponding to a unique value in the key. (You can set the rowKey in ``, the default value is 'key')
-- renderTreeToggle:() => ReactNode : Custom Toggle
-- onExpandChange:(expanded:boolean,rowData:object) => void: To open/close a node's callback function
diff --git a/docs/pages/components/table/en-US/word-wrap.md b/docs/pages/components/table/en-US/word-wrap.md
deleted file mode 100644
index 524a9cc85..000000000
--- a/docs/pages/components/table/en-US/word-wrap.md
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class WordWrapTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data
- };
- }
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
-
-If you want the cell to wrap, you just need to set `wordWrap`
diff --git a/docs/pages/components/table/zh-CN/affix-header.md b/docs/pages/components/table/fragments/affix-header.md
similarity index 84%
rename from docs/pages/components/table/zh-CN/affix-header.md
rename to docs/pages/components/table/fragments/affix-header.md
index cf4c2f084..0b9d91e59 100644
--- a/docs/pages/components/table/zh-CN/affix-header.md
+++ b/docs/pages/components/table/fragments/affix-header.md
@@ -6,9 +6,10 @@
* https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
*/
-function AffixHeaderTable() {
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 10);
return (
-
+
Id
|
@@ -35,8 +36,8 @@ function AffixHeaderTable() {
);
-}
-ReactDOM.render( );
+};
+ReactDOM.render( );
```
diff --git a/docs/pages/components/table/zh-CN/affix-horizontal-scrollbar.md b/docs/pages/components/table/fragments/affix-horizontal-scrollbar.md
similarity index 87%
rename from docs/pages/components/table/zh-CN/affix-horizontal-scrollbar.md
rename to docs/pages/components/table/fragments/affix-horizontal-scrollbar.md
index 295d79876..09e58e3b5 100644
--- a/docs/pages/components/table/zh-CN/affix-horizontal-scrollbar.md
+++ b/docs/pages/components/table/fragments/affix-horizontal-scrollbar.md
@@ -6,11 +6,12 @@
* https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
*/
-function AffixHorizontalScrollbarTable() {
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 10);
return (
Company Name
|
-
- Company Name
- |
-
);
-}
-ReactDOM.render( );
+};
+ReactDOM.render( );
```
diff --git a/docs/pages/components/table/en-US/auto-height.md b/docs/pages/components/table/fragments/auto-height.md
similarity index 85%
rename from docs/pages/components/table/en-US/auto-height.md
rename to docs/pages/components/table/fragments/auto-height.md
index b51ff1a84..cce49199b 100644
--- a/docs/pages/components/table/en-US/auto-height.md
+++ b/docs/pages/components/table/fragments/auto-height.md
@@ -6,9 +6,11 @@
* https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
*/
-function AutoHeigthTable() {
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 12);
+
return (
-
+
Id
|
@@ -35,8 +37,8 @@ function AutoHeigthTable() {
);
-}
-ReactDOM.render( );
+};
+ReactDOM.render( );
```
diff --git a/docs/pages/components/table/fragments/colspan.md b/docs/pages/components/table/fragments/colspan.md
new file mode 100644
index 000000000..c85b1505a
--- /dev/null
+++ b/docs/pages/components/table/fragments/colspan.md
@@ -0,0 +1,53 @@
+
+
+```js
+/**
+ * import fakeDataForColSpan from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users-colspan.json
+ */
+
+const App = () => {
+ return (
+ {
+ console.log(data);
+ }}
+ >
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+
+ Address
+ |
+
+
+
+ Company Name
+ |
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/custom-cell.md b/docs/pages/components/table/fragments/custom-cell.md
new file mode 100644
index 000000000..a5d5683ad
--- /dev/null
+++ b/docs/pages/components/table/fragments/custom-cell.md
@@ -0,0 +1,196 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const NameCell = ({ rowData, dataKey, ...props }) => {
+ const speaker = (
+
+
+ Name: {`${rowData.firstName} ${rowData.lastName}`}{' '}
+
+
+ Email: {rowData.email}{' '}
+
+
+ Company: {rowData.companyName}{' '}
+
+
+ Sentence: {rowData.sentence}{' '}
+
+
+ );
+
+ return (
+
+
+ {rowData[dataKey].toLocaleString()}
+
+ |
+ );
+};
+
+const ImageCell = ({ rowData, dataKey, ...props }) => (
+
+
+
+
+ |
+);
+
+const CheckCell = ({ rowData, onChange, checkedKeys, dataKey, ...props }) => (
+
+
+ item === rowData[dataKey])}
+ />
+
+ |
+);
+
+const Menu = ({ onSelect }) => (
+
+ Download As...
+ Export PDF
+ Export HTML
+ Settings
+ About
+
+);
+
+const MenuPopover = React.forwardRef(({ onSelect, ...rest }, ref) => (
+
+
+
+));
+
+const CustomWhisper = ({ container, children }) => {
+ const ref = React.useRef();
+ const handleSelectMenu = (eventKey, event) => {
+ ref.current.close();
+ console.log(eventKey);
+ };
+ return (
+ }
+ >
+ {children}
+
+ );
+};
+
+const ActionCell = ({ rowData, dataKey, container, ...props }) => {
+ function handleAction() {
+ alert(`id:${rowData[dataKey]}`);
+ }
+ return (
+
+ } />
+
+
+ } />
+
+ |
+ );
+};
+
+const data = fakeData.filter((v, i) => i < 5);
+
+const App = () => {
+ const [checkedKeys, setCheckedKeys] = React.useState([]);
+ let checked = false;
+ let indeterminate = false;
+
+ if (checkedKeys.length === data.length) {
+ checked = true;
+ } else if (checkedKeys.length === 0) {
+ checked = false;
+ } else if (checkedKeys.length > 0 && checkedKeys.length < data.length) {
+ indeterminate = true;
+ }
+
+ const tableBodyRef = React.useRef();
+
+ const handleCheckAll = (value, checked) => {
+ const keys = checked ? data.map(item => item.id) : [];
+ setCheckedKeys(keys);
+ };
+ const handleCheck = (value, checked) => {
+ const keys = checked ? [...checkedKeys, value] : checkedKeys.filter(item => item !== value);
+ setCheckedKeys(keys);
+ };
+
+ return (
+ {
+ tableBodyRef.current = node;
+ }}
+ >
+
+
+
+
+
+
+
+
+
+ Avartar
+
+
+
+
+ First Name
+
+
+
+
+ Email
+ {rowData => {rowData.email} } |
+
+
+
+ Action
+ {
+ tableBodyRef.current;
+ }}
+ />
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/default.md b/docs/pages/components/table/fragments/default.md
new file mode 100644
index 000000000..e7d512508
--- /dev/null
+++ b/docs/pages/components/table/fragments/default.md
@@ -0,0 +1,75 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const App = () => {
+ return (
+ {
+ console.log(data);
+ }}
+ >
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+ City
+ |
+
+
+
+ Street
+ |
+
+
+
+ Company Name
+ |
+
+
+
+ Email
+ |
+
+
+ Action
+
+
+ {rowData => {
+ function handleAction() {
+ alert(`id:${rowData.id}`);
+ }
+ return (
+
+ Edit | Remove
+
+ );
+ }}
+ |
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/zh-CN/draggable.md b/docs/pages/components/table/fragments/draggable.md
similarity index 98%
rename from docs/pages/components/table/zh-CN/draggable.md
rename to docs/pages/components/table/fragments/draggable.md
index c259762a8..9542199e4 100644
--- a/docs/pages/components/table/zh-CN/draggable.md
+++ b/docs/pages/components/table/fragments/draggable.md
@@ -101,7 +101,7 @@ function sort(source, sourceId, targetId) {
return nextData;
}
-function DraggableTable() {
+function App() {
const [data, setData] = React.useState(fakeData.filter((item, index) => index < 7));
const [columns, setColumns] = React.useState([
{ id: 'id', name: 'Id', width: 80 },
@@ -144,7 +144,7 @@ function DraggableTable() {
);
}
-ReactDOM.render( );
+ReactDOM.render( );
```
diff --git a/docs/pages/components/table/en-US/edit.md b/docs/pages/components/table/fragments/edit.md
similarity index 80%
rename from docs/pages/components/table/en-US/edit.md
rename to docs/pages/components/table/fragments/edit.md
index eae7da1b9..500289fea 100644
--- a/docs/pages/components/table/en-US/edit.md
+++ b/docs/pages/components/table/fragments/edit.md
@@ -39,7 +39,7 @@ const ActionCell = ({ rowData, dataKey, onClick, ...props }) => {
);
};
-const EditTable = () => {
+const App = () => {
const [data, setData] = React.useState(fakeData.filter((v, i) => i < 8));
const handleChange = (id, key, value) => {
const nextData = Object.assign([], data);
@@ -78,29 +78,7 @@ const EditTable = () => {
);
};
-ReactDOM.render( );
+ReactDOM.render( );
```
-
-> Editable tables, just customize a `Cell` on the line
-
-```js
-export const EditCell = ({ rowData, dataKey, onChange, ...props }) => {
- return (
-
- {rowData.status === 'EDIT' ? (
- {
- onChange && onChange(rowData.id, dataKey, event.target.value);
- }}
- />
- ) : (
- rowData[dataKey]
- )}
- |
- );
-};
-```
diff --git a/docs/pages/components/table/fragments/expanded.md b/docs/pages/components/table/fragments/expanded.md
new file mode 100644
index 000000000..f4c4f94c1
--- /dev/null
+++ b/docs/pages/components/table/fragments/expanded.md
@@ -0,0 +1,116 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const rowKey = 'id';
+const ExpandCell = ({ rowData, dataKey, expandedRowKeys, onChange, ...props }) => (
+
+ {
+ onChange(rowData);
+ }}
+ icon={
+ key === rowData[rowKey])
+ ? 'minus-square-o'
+ : 'plus-square-o'
+ }
+ />
+ }
+ />
+ |
+);
+
+const renderRowExpanded = rowData => {
+ return (
+
+
+
+
+ {rowData.email}
+ {rowData.date}
+
+ );
+};
+
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 5);
+ const [expandedRowKeys, setExpandedRowKeys] = React.useState([]);
+
+ const handleExpanded = (rowData, dataKey) => {
+ let open = false;
+ const nextExpandedRowKeys = [];
+
+ expandedRowKeys.forEach(key => {
+ if (key === rowData[rowKey]) {
+ open = true;
+ } else {
+ nextExpandedRowKeys.push(key);
+ }
+ });
+
+ if (!open) {
+ nextExpandedRowKeys.push(rowData[rowKey]);
+ }
+
+ setExpandedRowKeys(nextExpandedRowKeys);
+ };
+
+ return (
+ {
+ console.log(data);
+ }}
+ renderRowExpanded={renderRowExpanded}
+ >
+
+ #
+
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+ City
+ |
+
+
+
+ Street
+ |
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/fixed.md b/docs/pages/components/table/fragments/fixed.md
new file mode 100644
index 000000000..82402f4af
--- /dev/null
+++ b/docs/pages/components/table/fragments/fixed.md
@@ -0,0 +1,74 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const ActionCell = ({ rowData, dataKey, ...props }) => {
+ function handleAction() {
+ alert(`id:${rowData[dataKey]}`);
+ }
+ return (
+
+ } />
+ |
+ );
+};
+
+const App = () => {
+ return (
+ {
+ console.log(data);
+ }}
+ >
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+ City
+ |
+
+
+
+ Street
+ |
+
+
+
+ Company Name
+ |
+
+
+
+ Email
+ |
+
+
+
+ Action
+
+
+
+ );
+};
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/fluid-column.md b/docs/pages/components/table/fragments/fluid-column.md
new file mode 100644
index 000000000..12c3386f3
--- /dev/null
+++ b/docs/pages/components/table/fragments/fluid-column.md
@@ -0,0 +1,49 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 8);
+ return (
+ {
+ console.log(sortColumn, sortType);
+ }}
+ >
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+
+ City flexGrow={1}
+
+ |
+
+
+
+
+ Company Name flexGrow={2}
+
+ |
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/import.md b/docs/pages/components/table/fragments/import.md
new file mode 100644
index 000000000..26a9e2743
--- /dev/null
+++ b/docs/pages/components/table/fragments/import.md
@@ -0,0 +1,6 @@
+```js
+import { Table } from 'rsuite';
+
+// or
+import Table from 'rsuite/lib/Table';
+```
diff --git a/docs/pages/components/table/fragments/loading.md b/docs/pages/components/table/fragments/loading.md
new file mode 100644
index 000000000..ce89c3ac2
--- /dev/null
+++ b/docs/pages/components/table/fragments/loading.md
@@ -0,0 +1,56 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 5);
+ const [loading, setLoading] = React.useState(true);
+ return (
+
+
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+ City
+ |
+
+
+
+ Street
+ |
+
+
+
+
+ Loading:
+
+
+
+ );
+};
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/pagination.md b/docs/pages/components/table/fragments/pagination.md
new file mode 100644
index 000000000..74178861f
--- /dev/null
+++ b/docs/pages/components/table/fragments/pagination.md
@@ -0,0 +1,77 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const App = () => {
+ const [loading, setLoading] = React.useState(false);
+ const [displayLength, setDisplayLength] = React.useState(10);
+ const [page, setPage] = React.useState(1);
+
+ const handleChangeLength = dataKey => {
+ setPage(1);
+ setDisplayLength(dataKey);
+ };
+
+ const data = fakeData.filter((v, i) => {
+ const start = displayLength * (page - 1);
+ const end = start + displayLength;
+ return i >= start && i < end;
+ });
+
+ return (
+
+
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+ City
+ |
+
+
+ Company Name
+ |
+
+
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/resizable.md b/docs/pages/components/table/fragments/resizable.md
new file mode 100644
index 000000000..4dfd78de4
--- /dev/null
+++ b/docs/pages/components/table/fragments/resizable.md
@@ -0,0 +1,46 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 8);
+ return (
+
+
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+ City
+ |
+
+
+
+ Company Name
+ |
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/sort.md b/docs/pages/components/table/fragments/sort.md
new file mode 100644
index 000000000..e477088af
--- /dev/null
+++ b/docs/pages/components/table/fragments/sort.md
@@ -0,0 +1,88 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const data = fakeData.filter((v, i) => i < 8);
+const App = () => {
+ const [sortColumn, setSortColumn] = React.useState();
+ const [sortType, setSortType] = React.useState();
+ const [loading, setLoading] = React.useState(false);
+
+ const getData = () => {
+ if (sortColumn && sortType) {
+ return data.sort((a, b) => {
+ let x = a[sortColumn];
+ let y = b[sortColumn];
+ if (typeof x === 'string') {
+ x = x.charCodeAt();
+ }
+ if (typeof y === 'string') {
+ y = y.charCodeAt();
+ }
+ if (sortType === 'asc') {
+ return x - y;
+ } else {
+ return y - x;
+ }
+ });
+ }
+ return data;
+ };
+
+ const handleSortColumn = (sortColumn, sortType) => {
+ setLoading(true);
+ setTimeout(() => {
+ setLoading(false);
+ setSortColumn(sortColumn);
+ setSortType(sortType);
+ }, 500);
+ };
+
+ return (
+ {
+ console.log(data);
+ }}
+ >
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+
+ City
+ |
+
+
+
+ Company Name
+ |
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/summary.md b/docs/pages/components/table/fragments/summary.md
new file mode 100644
index 000000000..356d7f11a
--- /dev/null
+++ b/docs/pages/components/table/fragments/summary.md
@@ -0,0 +1,66 @@
+
+
+```js
+/**
+ * import fakeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
+ */
+
+const thousands = value => `${value}`.replace(/(?=(?!(\b))(\d{3})+$)/g, '$1,');
+
+const NumberCell = ({ rowData, dataKey, ...props }) => (
+ {thousands(rowData[dataKey])} |
+);
+
+const HeaderSummary = ({ title, summary }) => (
+
+ {title}
+
+ {thousands(summary)}
+
+
+);
+
+const data = fakeData.filter((v, i) => i < 5);
+
+const App = () => {
+ let stars = 0;
+ let followers = 0;
+ data.forEach(item => {
+ stars += item.stars;
+ followers += item.followers;
+ });
+
+ return (
+
+
+ First Name
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/fragments/tree.md b/docs/pages/components/table/fragments/tree.md
new file mode 100644
index 000000000..7b2d303b6
--- /dev/null
+++ b/docs/pages/components/table/fragments/tree.md
@@ -0,0 +1,50 @@
+
+
+```js
+/**
+ * import fakeTreeData from
+ * https://github.com/rsuite/rsuite/blob/master/docs/public/data/tree-data.json
+ */
+
+const App = () => {
+ return (
+ {
+ console.log(isOpen, rowData);
+ }}
+ renderTreeToggle={(icon, rowData) => {
+ if (rowData.children && rowData.children.length === 0) {
+ return ;
+ }
+ return icon;
+ }}
+ >
+
+ Label
+ |
+
+
+
+ Status
+ |
+
+
+
+ Count
+ |
+
+
+ );
+};
+
+ReactDOM.render( );
+```
+
+
diff --git a/docs/pages/components/table/zh-CN/auto-height.md b/docs/pages/components/table/fragments/virtualized.md
similarity index 53%
rename from docs/pages/components/table/zh-CN/auto-height.md
rename to docs/pages/components/table/fragments/virtualized.md
index b51ff1a84..1cee6b98a 100644
--- a/docs/pages/components/table/zh-CN/auto-height.md
+++ b/docs/pages/components/table/fragments/virtualized.md
@@ -1,42 +1,49 @@
```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-function AutoHeigthTable() {
+const App = () => {
return (
-
-
+ {
+ console.log(data);
+ }}
+ >
+
Id
|
-
+
First Name
|
-
+
Last Name
|
-
+
City
|
-
+
+ Street
+ |
+
+
+
Company Name
|
);
-}
-ReactDOM.render( );
+};
+ReactDOM.render( );
```
diff --git a/docs/pages/components/table/en-US/affix-header.md b/docs/pages/components/table/fragments/word-wrap.md
similarity index 54%
rename from docs/pages/components/table/en-US/affix-header.md
rename to docs/pages/components/table/fragments/word-wrap.md
index cf4c2f084..f305a5e64 100644
--- a/docs/pages/components/table/en-US/affix-header.md
+++ b/docs/pages/components/table/fragments/word-wrap.md
@@ -6,37 +6,46 @@
* https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
*/
-function AffixHeaderTable() {
+const App = () => {
+ const data = fakeData.filter((v, i) => i < 4);
return (
-
-
+ {
+ console.log(data);
+ }}
+ >
+
Id
|
-
+
First Name
|
-
+
Last Name
|
-
+
City
|
-
- Company Name
- |
+
+ Street
+ |
);
-}
-ReactDOM.render( );
+};
+
+ReactDOM.render( );
```
diff --git a/docs/pages/components/table/index.tsx b/docs/pages/components/table/index.tsx
index ba45551e2..0fb780ffc 100644
--- a/docs/pages/components/table/index.tsx
+++ b/docs/pages/components/table/index.tsx
@@ -1,4 +1,4 @@
-import * as React from 'react';
+import React from 'react';
import {
Table,
Toggle,
@@ -16,11 +16,8 @@ import {
import DefaultPage from '@/components/Page';
import AppContext from '@/components/AppContext';
import useFetchData from '@/utils/useFetchData';
-import { useDrag, useDrop, DndProvider } from 'react-dnd';
-import Backend from 'react-dnd-html5-backend';
-const { HeaderCell, Pagination, Cell, Column, ColumnGroup } = Table;
-const TablePagination = Pagination;
+const { HeaderCell, Cell, Column, ColumnGroup } = Table;
export default function Page() {
const { messages, localePath } = React.useContext(AppContext);
@@ -29,6 +26,7 @@ export default function Page() {
const { response: fakeLargeData } = useFetchData('large-data');
const { response: fakeDataForColSpan } = useFetchData('users-colspan');
+ /*
const tabExamples = [
'resizable',
'fluid-column',
@@ -51,10 +49,9 @@ export default function Page() {
title: messages?.table[`tab.${item}`],
source: require(`.${localePath}/${item}.md`)
}));
-
+*/
return (
);
}
diff --git a/docs/pages/components/table/zh-CN/colspan.md b/docs/pages/components/table/zh-CN/colspan.md
deleted file mode 100644
index eb588c406..000000000
--- a/docs/pages/components/table/zh-CN/colspan.md
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-```js
-/**
- * import fakeDataForColSpan from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users-colspan.json
- */
-
-class ColspanTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: fakeDataForColSpan
- };
- }
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
-
- Address
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-在某些情况下,需要合并列来组织数据之间的关系,可以在 `` 组件上设置一个 `colSpan` 属性,同时通过 `` 设置表头分组。
-例如:
-
-```js
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-```
-
-> 当 `lastName` 对应列的值为 `null` 或者 `undefined` 的时候,则会被 `firstName` 列合并。
diff --git a/docs/pages/components/table/zh-CN/custom-cell.md b/docs/pages/components/table/zh-CN/custom-cell.md
deleted file mode 100644
index e880e545c..000000000
--- a/docs/pages/components/table/zh-CN/custom-cell.md
+++ /dev/null
@@ -1,268 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const NameCell = ({ rowData, dataKey, ...props }) => {
- const speaker = (
-
-
- Name: {`${rowData.firstName} ${rowData.lastName}`}{' '}
-
-
- Email: {rowData.email}{' '}
-
-
- Company: {rowData.companyName}{' '}
-
-
- Sentence: {rowData.sentence}{' '}
-
-
- );
-
- return (
-
-
- {rowData[dataKey].toLocaleString()}
-
- |
- );
-};
-
-const ImageCell = ({ rowData, dataKey, ...props }) => (
-
-
-
-
- |
-);
-
-const CheckCell = ({ rowData, onChange, checkedKeys, dataKey, ...props }) => (
-
-
- item === rowData[dataKey])}
- />
-
- |
-);
-
-const Menu = ({ onSelect }) => (
-
- Download As...
- Export PDF
- Export HTML
- Settings
- About
-
-);
-
-const MenuPopover = ({ onSelect, ...rest }) => (
-
-
-
-);
-
-let tableBody;
-
-class CustomWhisper extends React.Component {
- constructor(props) {
- super(props);
- this.handleSelectMenu = this.handleSelectMenu.bind(this);
- }
- handleSelectMenu(eventKey, event) {
- console.log(eventKey);
- this.trigger.hide();
- }
- render() {
- return (
- {
- this.trigger = ref;
- }}
- container={() => {
- return tableBody;
- }}
- speaker={ }
- >
- {this.props.children}
-
- );
- }
-}
-
-const ActionCell = ({ rowData, dataKey, ...props }) => {
- function handleAction() {
- alert(`id:${rowData[dataKey]}`);
- }
- return (
-
- } />
-
-
- } />
-
- |
- );
-};
-
-const data = fakeData.filter((v, i) => i < 20);
-class CustomColumnTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- checkedKeys: [],
- data
- };
- this.handleCheckAll = this.handleCheckAll.bind(this);
- this.handleCheck = this.handleCheck.bind(this);
- }
- handleCheckAll(value, checked) {
- const checkedKeys = checked ? data.map(item => item.id) : [];
- this.setState({
- checkedKeys
- });
- }
- handleCheck(value, checked) {
- const { checkedKeys } = this.state;
- const nextCheckedKeys = checked
- ? [...checkedKeys, value]
- : checkedKeys.filter(item => item !== value);
-
- this.setState({
- checkedKeys: nextCheckedKeys
- });
- }
- render() {
- const { data, checkedKeys } = this.state;
-
- let checked = false;
- let indeterminate = false;
-
- if (checkedKeys.length === data.length) {
- checked = true;
- } else if (checkedKeys.length === 0) {
- checked = false;
- } else if (checkedKeys.length > 0 && checkedKeys.length < data.length) {
- indeterminate = true;
- }
-
- return (
-
- {
- tableBody = ref;
- }}
- >
-
-
-
-
-
-
-
-
-
- Avartar
-
-
-
-
- First Name
-
-
-
-
- Email
- {rowData => {rowData.email} } |
-
-
-
- Action
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-根据不同的业务场景,单元格中可以自己定义显示的内容,比如显示一张图片,比如您要添加一个几个按钮,或者显示一个文本框,都是可以自定义的,只需要把 `Cell` 组件重新自定义一下就行。
-
-比如,显示一个图片,定义一个 `ImageCell` 组件:
-
-```js
-const ImageCell = ({ rowData, dataKey, ...props }) => (
-
-
- |
-);
-```
-
-```html
-
- Avartar
-
-
-```
-
-`` 的 `children` 支持函数,可以获取到 `rowData` 返回一个新的 `children`
-
-示例:
-
-```html
-
- Date
- {rowData => rowData.date.toLocaleString()} |
-
-```
-
----
-
-**自定义行高**
-
-如果在实际应用中需要根据数据内容来定义行高,可以使用以下方式
-
-```html
- {
- if (rowData.firstName === 'Janis') {
- return 30;
- }
- }}
- >
-...
-
-```
diff --git a/docs/pages/components/table/zh-CN/default.md b/docs/pages/components/table/zh-CN/default.md
deleted file mode 100644
index 3c31ff374..000000000
--- a/docs/pages/components/table/zh-CN/default.md
+++ /dev/null
@@ -1,77 +0,0 @@
-### 默认
-
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-function MyTable() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
- Action
-
-
- {rowData => {
- function handleAction() {
- alert(`id:${rowData.id}`);
- }
- return (
-
- Edit | Remove
-
- );
- }}
- |
-
-
-
- );
-}
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/zh-CN/edit.md b/docs/pages/components/table/zh-CN/edit.md
deleted file mode 100644
index 28617f862..000000000
--- a/docs/pages/components/table/zh-CN/edit.md
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-export const EditCell = ({ rowData, dataKey, onChange, ...props }) => {
- const editing = rowData.status === 'EDIT';
- return (
-
- {editing ? (
- {
- onChange && onChange(rowData.id, dataKey, event.target.value);
- }}
- />
- ) : (
- {rowData[dataKey]}
- )}
- |
- );
-};
-
-const ActionCell = ({ rowData, dataKey, onClick, ...props }) => {
- return (
-
- {
- onClick && onClick(rowData.id);
- }}
- >
- {rowData.status === 'EDIT' ? 'Save' : 'Edit'}
-
- |
- );
-};
-
-const EditTable = () => {
- const [data, setData] = React.useState(fakeData.filter((v, i) => i < 8));
- const handleChange = (id, key, value) => {
- const nextData = Object.assign([], data);
- nextData.find(item => item.id === id)[key] = value;
- setData(nextData);
- };
- const handleEditState = id => {
- const nextData = Object.assign([], data);
- const activeItem = nextData.find(item => item.id === id);
- activeItem.status = activeItem.status ? null : 'EDIT';
- setData(nextData);
- };
-
- return (
-
-
- First Name
-
-
-
-
- Last Name
-
-
-
-
- Email
-
-
-
-
- Action
-
-
-
- );
-};
-
-ReactDOM.render( );
-```
-
-
-
-> 可编辑的表格,只需要自定义一个 `Cell` 就行了
-
-```js
-export const EditCell = ({ rowData, dataKey, onChange, ...props }) => {
- return (
-
- {rowData.status === 'EDIT' ? (
- {
- onChange && onChange(rowData.id, dataKey, event.target.value);
- }}
- />
- ) : (
- rowData[dataKey]
- )}
- |
- );
-};
-```
diff --git a/docs/pages/components/table/zh-CN/expanded.md b/docs/pages/components/table/zh-CN/expanded.md
deleted file mode 100644
index d3ec8c15a..000000000
--- a/docs/pages/components/table/zh-CN/expanded.md
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const rowKey = 'id';
-const ExpandCell = ({ rowData, dataKey, expandedRowKeys, onChange, ...props }) => (
-
- {
- onChange(rowData);
- }}
- icon={
- key === rowData[rowKey])
- ? 'minus-square-o'
- : 'plus-square-o'
- }
- />
- }
- />
- |
-);
-
-class ExpandedTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: fakeData,
- expandedRowKeys: []
- };
- this.handleExpanded = this.handleExpanded.bind(this);
- }
- handleExpanded(rowData, dataKey) {
- const { expandedRowKeys } = this.state;
-
- let open = false;
- const nextExpandedRowKeys = [];
-
- expandedRowKeys.forEach(key => {
- if (key === rowData[rowKey]) {
- open = true;
- } else {
- nextExpandedRowKeys.push(key);
- }
- });
-
- if (!open) {
- nextExpandedRowKeys.push(rowData[rowKey]);
- }
- this.setState({
- expandedRowKeys: nextExpandedRowKeys
- });
- }
- render() {
- const { expandedRowKeys, data } = this.state;
- return (
- {
- console.log(data);
- }}
- renderRowExpanded={rowData => {
- return (
-
-
-
-
- {rowData.email}
- {rowData.date}
-
- );
- }}
- >
-
- #
-
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
-
-要实现一个可以展开的 Table ,需要以下几个属性的组合完成。
-
-**第一步:给 Table 设置属性**
-
-- renderRowExpanded(rowData) => ReactNode 用来返回需要在展开面板中渲染的内容
-- rowExpandedHeight 设置可展开区域的高度, 默认是 100
-- expandedRowKeys(受控) 和 defaultExpandedRowKeys 用来配置需要展开的行。需要注意的是这两个属性接收的参数是一个的数组,数组中是 rowKey。
-- rowKey 给每一行数据对一个唯一 key , 对应 data 中的一个唯一值的 key。
-
-**第二步:自定义 Cell**
-
-自定义一个 Cell, 在内部放一个可以操作按钮,用于操作 expandedRowKeys 中的值。
diff --git a/docs/pages/components/table/zh-CN/fixed.md b/docs/pages/components/table/zh-CN/fixed.md
deleted file mode 100644
index 77fd42ebe..000000000
--- a/docs/pages/components/table/zh-CN/fixed.md
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const ActionCell = ({ rowData, dataKey, ...props }) => {
- function handleAction() {
- alert(`id:${rowData[dataKey]}`);
- }
- return (
-
- } />
- |
- );
-};
-
-class FixedTable extends React.Component {
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Action
-
-
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/zh-CN/fluid-column.md b/docs/pages/components/table/zh-CN/fluid-column.md
deleted file mode 100644
index bad773ef2..000000000
--- a/docs/pages/components/table/zh-CN/fluid-column.md
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class FluidColumnTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data
- };
- }
-
- render() {
- const { data } = this.state;
- return (
-
- {
- console.log(sortColumn, sortType);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
-
- City flexGrow={1}
-
- |
-
-
-
-
- Company Name flexGrow={2}
-
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-如果需要把某列设置为自动宽度,需要配置 `flexGrow` 属性。 `flexGrow` 是 `number` 类型。会按照所有 `flexGrow` 总和比例撑满 `` 剩下的宽度。
-
-> 注意: 设置 `flexGrow` 以后,就不能设置 `width` 和 `resizable` 属性。 可以通过 `minWidth` 设置一个最小宽度
-
-```html
-
- City flexGrow={1}
- |
-
-
-
- Company Name flexGrow={2}
- |
-
-
-...
-```
diff --git a/docs/pages/components/table/zh-CN/index.md b/docs/pages/components/table/zh-CN/index.md
index 2e1eb443e..a75f332e7 100644
--- a/docs/pages/components/table/zh-CN/index.md
+++ b/docs/pages/components/table/zh-CN/index.md
@@ -4,21 +4,269 @@
- `` 表格组件
- `` 表格定义列组件
+- `` 用于列头分组
- `` 列头单元格组件
- `` 单元格组件
- `` 表格分页组件
## 获取组件
+
+
+## 演示
+
+### 锁定列
+
+
+
+### 虚拟化的大表格
+
+支持 `virtualized`, 有效地呈现大表格数据。
+
+
+
+### 可调整列宽
+
+
+
+把鼠标移动到列分割线的时候,会显示出一个蓝色的移动手柄,点击不松开并左右拖动就可以调整列的宽度。
+
+要支持该功能,需要在 `Column` 设置一个 `resizable` 属性。
+
+### 流体列宽
+
+
+
+如果需要把某列设置为自动宽度,需要配置 `flexGrow` 属性。 `flexGrow` 是 `number` 类型。会按照所有 `flexGrow` 总和比例撑满 `` 剩下的宽度。
+
+> 注意: 设置 `flexGrow` 以后,就不能设置 `width` 和 `resizable` 属性。 可以通过 `minWidth` 设置一个最小宽度
+
+```html
+
+ City flexGrow={1}
+ |
+
+
+
+ Company Name flexGrow={2}
+ |
+
+
+...
+```
+
+### 自动换行
+
+
+
+如果想让单元格自动换行,只需要设置 `wordWrap`。
+
+### 自定义列
+
+
+
+根据不同的业务场景,单元格中可以自己定义显示的内容,比如显示一张图片,比如您要添加一个几个按钮,或者显示一个文本框,都是可以自定义的,只需要把 `Cell` 组件重新自定义一下就行。
+
+比如,显示一个图片,定义一个 `ImageCell` 组件:
+
```js
-import { Table } from 'rsuite';
+const ImageCell = ({ rowData, dataKey, ...props }) => (
+
+
+ |
+);
+```
-const { Column, HeaderCell, Cell, Pagination } = Table;
+```html
+
+ Avartar
+
+
```
-## 演示
+`` 的 `children` 支持函数,可以获取到 `rowData` 返回一个新的 `children`
+
+示例:
+
+```html
+
+ Date
+ {rowData => rowData.date.toLocaleString()} |
+
+```
+
+---
+
+**自定义行高**
+
+如果在实际应用中需要根据数据内容来定义行高,可以使用以下方式
+
+```html
+ {
+ if (rowData.firstName === 'Janis') {
+ return 30;
+ }
+ }}
+ >
+...
+
+```
+
+### 排序
+
+
+
+在需要排序的列 `` 设置一个 `sortable` 属性。同时在 `` 定义一个 `onSortColumn` 回调函数,点击列头排序图标的时候,会触发该方法,并返回 `sortColumn` 和 `sortType`。
+
+```html
+ { console.log(sortColumn, sortType); }} >
+
+
+ Id
+ |
+
+
+
+ First Name
+ |
+
+
+...
+```
+
+### 分页
+
+
+
+### 树形展示
+
+
+
+树形表格,主要为了展示有结构关系的数据,需要在 `Table` 组件上设置一个 `isTree` 属性,同时 `data` 中的数据需要通过 `children` 来定义关系结构。
+
+```js
+const data = [
+ {
+ id: '1',
+ labelName: 'Car',
+ status: 'ENABLED',
+ children: [
+ {
+ id: '1-1',
+ labelName: 'Mercedes Benz',
+ status: 'ENABLED',
+ count: 460
+ }
+ ]
+ }
+];
+;
+```
+
+**处理树形表格用的的相关属性**
+
+- `defaultExpandAllRows:boolean` 默认展开所有节点
+- `expandedRowKeys`(受控) 和 `defaultExpandedRowKeys` 用来配置需要展开的行。需要注意的是这两个属性接收的参数是一个的数组,数组中是 rowKey。
+- `rowKey` 给每一行数据对一个唯一 key , 对应 `data` 中的一个唯一值的 `key`。 (可以在 `` 设置 `rowKey` 进行修改,默认值: 'key' )
+- `renderTreeToggle:() => ReactNode` 自定义 Toggle
+- `onExpandChange:(expanded:boolean,rowData:object) => void` 展开/关闭节点的回调函数
+
+### 可展开
+
+
+
+要实现一个可以展开的 Table ,需要以下几个属性的组合完成。
+
+**第一步:给 Table 设置属性**
+
+- `renderRowExpanded(rowData) => ReactNode` 用来返回需要在展开面板中渲染的内容
+- `rowExpandedHeight` 设置可展开区域的高度, 默认是 100
+- `expandedRowKeys`(受控) 和 `defaultExpandedRowKeys` 用来配置需要展开的行。需要注意的是这两个属性接收的参数是一个的数组,数组中是 rowKey。
+- `rowKey` 给每一行数据对一个唯一 key , 对应 data 中的一个唯一值的 `key`。
+
+**第二步:自定义 Cell**
+
+自定义一个 `Cell`, 在内部放一个可以操作按钮,用于操作 `expandedRowKeys` 中的值。
+
+### 可编辑
+
+
+
+> 可编辑的表格,只需要自定义一个 `Cell` 就行了
+
+```js
+export const EditCell = ({ rowData, dataKey, onChange, ...props }) => {
+ return (
+
+ {rowData.status === 'EDIT' ? (
+ {
+ onChange && onChange(rowData.id, dataKey, event.target.value);
+ }}
+ />
+ ) : (
+ rowData[dataKey]
+ )}
+ |
+ );
+};
+```
+
+### 加载中
+
+
+
+当数据在异步获取中,需要在显示一个 `loading` 状态, 只需要在 `` 上设置 `loading` 属性就行
+
+### 合并单元格
+
+
+
+在某些情况下,需要合并列来组织数据之间的关系,可以在 `` 组件上设置一个 `colSpan` 属性,同时通过 `` 设置表头分组。
+例如:
+
+```js
+
+
+ First Name
+ |
+
+
+
+ Last Name
+ |
+
+
+```
+
+> 当 `lastName` 对应列的值为 `null` 或者 `undefined` 的时候,则会被 `firstName` 列合并。
+
+### 汇总
+
+
+
+### 随页面滚动
+
+- `autoHeight`: 表格的高度根据数据内容自动展开,不显示纵向滚动条。
+- `affixHeader`: 将表格列头估计到页面上的指定位置。
+- `affixHorizontalScrollbar`:将表格的横向滚动条固定在页面的底部。
+
+
+
+### 可拖拽(与 react-dnd 组合)
+
+https://codesandbox.io/s/rsuite-table-with-react-dnd-m06cm
+
+## 无障碍设计
-
+- `` 有一个 `grid` role。
+- 当 `` 设置了 `isTree`, 则有一个 `treegrid` role。
+- `` 有一个 `columnheader` role。
+- `` 有一个 `gridcell` role。
+- 在 `
-
-```js
-class LargeTable extends React.Component {
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/zh-CN/loading.md b/docs/pages/components/table/zh-CN/loading.md
deleted file mode 100644
index 05ab9d867..000000000
--- a/docs/pages/components/table/zh-CN/loading.md
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class LoadingTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data,
- loading: true
- };
- this.handleToggle = this.handleToggle.bind(this);
- }
- handleToggle(loading) {
- this.setState({ loading });
- }
- render() {
- const { loading } = this.state;
- return (
-
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
-
- 加载状态:
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-当数据在异步获取中,需要在显示一个 `loading` 状态, 只需要在 `` 上设置 `loading` 属性就行
diff --git a/docs/pages/components/table/zh-CN/pagination.md b/docs/pages/components/table/zh-CN/pagination.md
deleted file mode 100644
index 5d76ad053..000000000
--- a/docs/pages/components/table/zh-CN/pagination.md
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class PaginationTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- displayLength: 10,
- loading: false,
- page: 1
- };
- this.handleChangePage = this.handleChangePage.bind(this);
- this.handleChangeLength = this.handleChangeLength.bind(this);
- }
- handleChangePage(dataKey) {
- this.setState({
- page: dataKey
- });
- }
- handleChangeLength(dataKey) {
- this.setState({
- page: 1,
- displayLength: dataKey
- });
- }
- getData() {
- const { displayLength, page } = this.state;
-
- return fakeData.filter((v, i) => {
- const start = displayLength * (page - 1);
- const end = start + displayLength;
- return i >= start && i < end;
- });
- }
- render() {
- const data = this.getData();
- const { loading, displayLength, page } = this.state;
-
- return (
-
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
- Company Name
- |
-
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/zh-CN/resizable.md b/docs/pages/components/table/zh-CN/resizable.md
deleted file mode 100644
index 84ddd88bf..000000000
--- a/docs/pages/components/table/zh-CN/resizable.md
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class ResizableColumnTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data
- };
- }
- render() {
- const { data } = this.state;
- return (
-
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-把鼠标移动到列分割线的时候,会显示出一个蓝色的移动手柄,点击不松开并左右拖动就可以调整列的宽度。
-
-要支持该功能,需要在 `Column` 设置一个 `resizable` 属性。
diff --git a/docs/pages/components/table/zh-CN/sort.md b/docs/pages/components/table/zh-CN/sort.md
deleted file mode 100644
index f852800d5..000000000
--- a/docs/pages/components/table/zh-CN/sort.md
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class SortTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- addColumn: false,
- data
- };
- this.handleSortColumn = this.handleSortColumn.bind(this);
- }
-
- getData() {
- const { data, sortColumn, sortType } = this.state;
-
- if (sortColumn && sortType) {
- return data.sort((a, b) => {
- let x = a[sortColumn];
- let y = b[sortColumn];
- if (typeof x === 'string') {
- x = x.charCodeAt();
- }
- if (typeof y === 'string') {
- y = y.charCodeAt();
- }
- if (sortType === 'asc') {
- return x - y;
- } else {
- return y - x;
- }
- });
- }
- return data;
- }
-
- handleSortColumn(sortColumn, sortType) {
- this.setState({
- loading: true
- });
-
- setTimeout(() => {
- this.setState({
- sortColumn,
- sortType,
- loading: false
- });
- }, 500);
- }
-
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Company Name
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-在需要排序的列 `` 设置一个 `sortable` 属性。同时在 `` 定义一个 `onSortColumn` 回调函数,点击列头排序图标的时候,会触发该方法,并返回 `sortColumn` 和 `sortType`。
-
-```html
- { console.log(sortColumn, sortType); }} >
-
-
- Id
- |
-
-
-
- First Name
- |
-
-
-...
-```
diff --git a/docs/pages/components/table/zh-CN/summary.md b/docs/pages/components/table/zh-CN/summary.md
deleted file mode 100644
index c6dfe8538..000000000
--- a/docs/pages/components/table/zh-CN/summary.md
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-const thousands = value => `${value}`.replace(/(?=(?!(\b))(\d{3})+$)/g, '$1,');
-
-const NumberCell = ({ rowData, dataKey, ...props }) => (
- {thousands(rowData[dataKey])} |
-);
-
-const HeaderSummary = ({ title, summary }) => (
-
- {title}
-
- {thousands(summary)}
-
-
-);
-
-const data = fakeData.filter((v, i) => i < 10);
-class CustomColumnTable extends React.Component {
- render() {
- let stars = 0;
- let followers = 0;
- data.forEach(item => {
- stars += item.stars;
- followers += item.followers;
- });
-
- return (
-
-
-
- First Name
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
diff --git a/docs/pages/components/table/zh-CN/tree.md b/docs/pages/components/table/zh-CN/tree.md
deleted file mode 100644
index a2741e70a..000000000
--- a/docs/pages/components/table/zh-CN/tree.md
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-```js
-/**
- * import fakeTreeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/tree-data.json
- */
-
-class TreeTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- data: fakeTreeData
- };
- }
- render() {
- const { data } = this.state;
- return (
-
- {
- console.log(isOpen, rowData);
- }}
- renderTreeToggle={(icon, rowData) => {
- if (rowData.children && rowData.children.length === 0) {
- return ;
- }
- return icon;
- }}
- >
-
- Label
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Status
- |
-
-
-
- Count
- |
-
-
-
- );
- }
-}
-
-ReactDOM.render( );
-```
-
-
-
-树形表格,主要为了展示有结构关系的数据,需要在 `Table` 组件上设置一个 `isTree` 属性,同时 `data` 中的数据需要通过 `children` 来定义关系结构。
-
-```js
-const data = [
- {
- id: '1',
- labelName: 'Car',
- status: 'ENABLED',
- children: [
- {
- id: '1-1',
- labelName: 'Mercedes Benz',
- status: 'ENABLED',
- count: 460
- }
- ]
- }
-];
-;
-```
-
-**处理树形表格用的的相关属性**
-
-- defaultExpandAllRows:boolean 默认展开所有节点
-- expandedRowKeys(受控) 和 defaultExpandedRowKeys 用来配置需要展开的行。需要注意的是这两个属性接收的参数是一个的数组,数组中是 rowKey。
-- rowKey 给每一行数据对一个唯一 key , 对应 data 中的一个唯一值的 key。 (可以在 设置 rowKey 进行修改,默认值: 'key' )
-- renderTreeToggle:() => ReactNode 自定义 Toggle
-- onExpandChange:(expanded:boolean,rowData:object) => void 展开/关闭节点的回调函数
diff --git a/docs/pages/components/table/zh-CN/word-wrap.md b/docs/pages/components/table/zh-CN/word-wrap.md
deleted file mode 100644
index aa4ec43d5..000000000
--- a/docs/pages/components/table/zh-CN/word-wrap.md
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-```js
-/**
- * import fakeData from
- * https://github.com/rsuite/rsuite/blob/master/docs/public/data/users.json
- */
-
-class WordWrapTable extends React.Component {
- constructor(props) {
- super(props);
- const data = fakeData.filter((v, i) => i < 8);
- this.state = {
- data
- };
- }
- render() {
- return (
-
- {
- console.log(data);
- }}
- >
-
- Id
- |
-
-
-
- First Name
- |
-
-
-
- Last Name
- |
-
-
-
- City
- |
-
-
-
- Street
- |
-
-
-
- Company Name
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- Email
- |
-
-
-
- );
- }
-}
-ReactDOM.render( );
-```
-
-
-
-如果想让单元格自动换行,只需要设置 `wordWrap`
diff --git a/docs/pages/components/tooltip/fragments/container.md b/docs/pages/components/tooltip/fragments/container.md
index 55967be69..e2fa4ec5a 100644
--- a/docs/pages/components/tooltip/fragments/container.md
+++ b/docs/pages/components/tooltip/fragments/container.md
@@ -18,6 +18,7 @@ class Demo extends React.Component {
{getContainer => (
(
This is a ToolTip for simple text hints. It can replace the title property
}
diff --git a/docs/pages/components/tooltip/fragments/trigger.md b/docs/pages/components/tooltip/fragments/trigger.md
index 46eafa205..6004960fd 100644
--- a/docs/pages/components/tooltip/fragments/trigger.md
+++ b/docs/pages/components/tooltip/fragments/trigger.md
@@ -8,16 +8,16 @@ const tooltip = (
);
const instance = (
-
+
Click
-
+
Focus
-
+
Hover
-
+
Active
diff --git a/docs/pages/components/whisper/en-US/props.md b/docs/pages/components/whisper/en-US/props.md
index baea76d0f..5e07e01a2 100644
--- a/docs/pages/components/whisper/en-US/props.md
+++ b/docs/pages/components/whisper/en-US/props.md
@@ -13,6 +13,7 @@ type Trigger =
| Property | Type `(Default)` | Description |
| --------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| container | HTMLElement | (() => HTMLElement) | Sets the rendering container |
+| controlId | string | Set the `id` on `` and `aria-describedby` on `` |
| delay | number | Delay time (ms) Time |
| delayClose | number | Delay close time (ms) Time |
| delayOpen | number | Delay open time (ms) Time |
diff --git a/docs/pages/components/whisper/zh-CN/props.md b/docs/pages/components/whisper/zh-CN/props.md
index a343f2f22..7b9963cc9 100644
--- a/docs/pages/components/whisper/zh-CN/props.md
+++ b/docs/pages/components/whisper/zh-CN/props.md
@@ -10,29 +10,30 @@ type Trigger =
| 'none';
```
-| 属性名称 | 类型 `(默认值)` | 描述 |
-| --------------- | ----------------------------------------- | --------------------------------------------------------- |
-| container | HTMLElement | (() => HTMLElement) | 设置渲染的容器 |
-| delay | number | 延迟时间 (ms) |
-| delayClose | number | 延迟关闭时间 (ms) |
-| delayOpen | number | 延迟打开时间 (ms) |
-| enterable | boolean | 当 `trigger` 值为 `hover`时候,鼠标是否可进入提示框浮层中 |
-| full | boolean | 撑满容器 |
-| onBlur | () => void | 失去焦点回调函数 |
-| onClick | () => void | 点击的回调函数 |
-| onClose | () => void | 关闭回调函数 |
-| onEnter | () => void | 显示前动画过渡的回调函数 |
-| onEntered | () => void | 显示后动画过渡的回调函数 |
-| onEntering | () => void | 显示中动画过渡的回调函数 |
-| onExit | () => void | 退出前动画过渡的回调函数 |
-| onExited | () => void | 退出后动画过渡的回调函数 |
-| onExiting | () => void | 退出中动画过渡的回调函数 |
-| onFocus | () => void | 获取焦点的回调函数 |
-| onOpen | () => void | 打开回调函数 |
-| placement | Placement `('right')` | 显示位置 |
-| preventOverflow | boolean | 防止浮动元素溢出 |
-| speaker \* | Tooltip |Popover | ReactElement | 展示的元素 |
-| trigger | Trigger `(['hover','focus'])` | 触发事件,可以通过数组配置多事件 |
+| 属性名称 | 类型 `(默认值)` | 描述 |
+| --------------- | ----------------------------------------- | ------------------------------------------------------------------------- |
+| container | HTMLElement | (() => HTMLElement) | 设置渲染的容器 |
+| controlId | string | 设置 `id` 到 ``上,并且设置 `aria-describedby` 到 `` 上 |
+| delay | number | 延迟时间 (ms) |
+| delayClose | number | 延迟关闭时间 (ms) |
+| delayOpen | number | 延迟打开时间 (ms) |
+| enterable | boolean | 当 `trigger` 值为 `hover`时候,鼠标是否可进入提示框浮层中 |
+| full | boolean | 撑满容器 |
+| onBlur | () => void | 失去焦点回调函数 |
+| onClick | () => void | 点击的回调函数 |
+| onClose | () => void | 关闭回调函数 |
+| onEnter | () => void | 显示前动画过渡的回调函数 |
+| onEntered | () => void | 显示后动画过渡的回调函数 |
+| onEntering | () => void | 显示中动画过渡的回调函数 |
+| onExit | () => void | 退出前动画过渡的回调函数 |
+| onExited | () => void | 退出后动画过渡的回调函数 |
+| onExiting | () => void | 退出中动画过渡的回调函数 |
+| onFocus | () => void | 获取焦点的回调函数 |
+| onOpen | () => void | 打开回调函数 |
+| placement | Placement `('right')` | 显示位置 |
+| preventOverflow | boolean | 防止浮动元素溢出 |
+| speaker \* | Tooltip |Popover | ReactElement | 展示的元素 |
+| trigger | Trigger `(['hover','focus'])` | 触发事件,可以通过数组配置多事件 |
### Whisper methods
diff --git a/docs/public/data/en/users-colspan.json b/docs/public/data/en/users-colspan.json
index cd85f66fd..fc958838a 100644
--- a/docs/public/data/en/users-colspan.json
+++ b/docs/public/data/en/users-colspan.json
@@ -144,59 +144,5 @@
"sentence": "Non adipisci hic laboriosam et qui laudantium aspernatur.",
"stars": 330,
"followers": 590
- },
- {
- "id": 10,
- "avartar": "https://s3.amazonaws.com/uifaces/faces/twitter/mwarkentin/128.jpg",
- "city": "Felicitychester",
- "email": "Eileen48@gmail.com",
- "firstName": "Eldridge",
- "lastName": "Bins",
- "street": "Casper Squares",
- "zipCode": "80025-1552",
- "date": "2016-07-20T05:59:45.630Z",
- "bs": "cutting-edge expedite partnerships",
- "catchPhrase": "Organic user-facing functionalities",
- "companyName": "Leffler, Cummerata and Price",
- "words": "sed exercitationem quas",
- "sentence": "Voluptas dolorem quasi aspernatur.",
- "stars": 923,
- "followers": 704
- },
- {
- "id": 11,
- "avartar": "https://s3.amazonaws.com/uifaces/faces/twitter/gipsy_raf/128.jpg",
- "city": "Caleighhaven",
- "email": "Rico_Nolan@hotmail.com",
- "firstName": "Claude",
- "lastName": "Hermiston",
- "street": "Bode Pine",
- "zipCode": "76773",
- "date": "2017-03-13T08:02:41.211Z",
- "bs": "back-end innovate infomediaries",
- "catchPhrase": "Stand-alone global customer loyalty",
- "companyName": "Heller, Rosenbaum and Lockman",
- "words": "ut quia ut",
- "sentence": "Eos consequatur magni incidunt.",
- "stars": 421,
- "followers": 403
- },
- {
- "id": 12,
- "avartar": "https://s3.amazonaws.com/uifaces/faces/twitter/knilob/128.jpg",
- "city": "Herzogmouth",
- "email": "Dawn_Metz@yahoo.com",
- "firstName": "Clarabelle",
- "lastName": "Ankunding",
- "street": "Nolan Summit",
- "zipCode": "04355",
- "date": "2016-07-09T09:07:34.744Z",
- "bs": "granular deliver relationships",
- "catchPhrase": "Multi-lateral zero defect analyzer",
- "companyName": "Mante, Oberbrunner and Collins",
- "words": "eos fuga repellat",
- "sentence": "Cum corporis molestias quia.",
- "stars": 8203,
- "followers": 704
}
]
diff --git a/docs/public/data/users-colspan.json b/docs/public/data/users-colspan.json
index cd85f66fd..fc958838a 100644
--- a/docs/public/data/users-colspan.json
+++ b/docs/public/data/users-colspan.json
@@ -144,59 +144,5 @@
"sentence": "Non adipisci hic laboriosam et qui laudantium aspernatur.",
"stars": 330,
"followers": 590
- },
- {
- "id": 10,
- "avartar": "https://s3.amazonaws.com/uifaces/faces/twitter/mwarkentin/128.jpg",
- "city": "Felicitychester",
- "email": "Eileen48@gmail.com",
- "firstName": "Eldridge",
- "lastName": "Bins",
- "street": "Casper Squares",
- "zipCode": "80025-1552",
- "date": "2016-07-20T05:59:45.630Z",
- "bs": "cutting-edge expedite partnerships",
- "catchPhrase": "Organic user-facing functionalities",
- "companyName": "Leffler, Cummerata and Price",
- "words": "sed exercitationem quas",
- "sentence": "Voluptas dolorem quasi aspernatur.",
- "stars": 923,
- "followers": 704
- },
- {
- "id": 11,
- "avartar": "https://s3.amazonaws.com/uifaces/faces/twitter/gipsy_raf/128.jpg",
- "city": "Caleighhaven",
- "email": "Rico_Nolan@hotmail.com",
- "firstName": "Claude",
- "lastName": "Hermiston",
- "street": "Bode Pine",
- "zipCode": "76773",
- "date": "2017-03-13T08:02:41.211Z",
- "bs": "back-end innovate infomediaries",
- "catchPhrase": "Stand-alone global customer loyalty",
- "companyName": "Heller, Rosenbaum and Lockman",
- "words": "ut quia ut",
- "sentence": "Eos consequatur magni incidunt.",
- "stars": 421,
- "followers": 403
- },
- {
- "id": 12,
- "avartar": "https://s3.amazonaws.com/uifaces/faces/twitter/knilob/128.jpg",
- "city": "Herzogmouth",
- "email": "Dawn_Metz@yahoo.com",
- "firstName": "Clarabelle",
- "lastName": "Ankunding",
- "street": "Nolan Summit",
- "zipCode": "04355",
- "date": "2016-07-09T09:07:34.744Z",
- "bs": "granular deliver relationships",
- "catchPhrase": "Multi-lateral zero defect analyzer",
- "companyName": "Mante, Oberbrunner and Collins",
- "words": "eos fuga repellat",
- "sentence": "Cum corporis molestias quia.",
- "stars": 8203,
- "followers": 704
}
]
diff --git a/package-lock.json b/package-lock.json
index 1b1170caa..346585c34 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15945,9 +15945,9 @@
}
},
"rsuite-table": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/rsuite-table/-/rsuite-table-3.13.1.tgz",
- "integrity": "sha512-wQJ1wtMMq5fVOYSR8mY7F1ZmjJ4MDYbb7HRCFPIgUxweov/kC5MF5qTUDwkMovxoz7Lla7jLAmGiPAYGj9TAUQ==",
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/rsuite-table/-/rsuite-table-3.14.0.tgz",
+ "integrity": "sha512-60/0D+RegiY4dK1tYgd2tUy4vXedDNEjRdC8hq2rhwzM81PYkbvJ4kZQkIysQGKww98i2MPCNT1w3+Ly6YeT/A==",
"requires": {
"@babel/runtime": "^7.8.4",
"classnames": "^2.2.5",
diff --git a/package.json b/package.json
index 131cc3e12..3ca8d1111 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,7 @@
"react-lifecycles-compat": "^3.0.4",
"react-virtualized": "^9.21.0",
"recompose": "^0.30.0",
- "rsuite-table": "^3.13.1",
+ "rsuite-table": "^3.14.0",
"schema-typed": "^1.5.1"
},
"peerDependencies": {
diff --git a/src/@types/common.ts b/src/@types/common.ts
index 981bf8e53..94ab09890 100644
--- a/src/@types/common.ts
+++ b/src/@types/common.ts
@@ -57,6 +57,8 @@ export interface AnimationEventProps {
export type PickerAppearance = 'default' | 'subtle';
export interface PickerBaseProps extends WithAsProps, AnimationEventProps {
+ id?: string;
+
/** locale */
locale?: LocaleType;
diff --git a/src/Affix/Affix.tsx b/src/Affix/Affix.tsx
index 48e6b99ce..0fc437211 100644
--- a/src/Affix/Affix.tsx
+++ b/src/Affix/Affix.tsx
@@ -124,7 +124,7 @@ const Affix: RsRefForwardingComponent<'div', AffixProps> = React.forwardRef(
{children}
- {fixed && }
+ {fixed && }
);
}
diff --git a/src/AutoComplete/AutoComplete.tsx b/src/AutoComplete/AutoComplete.tsx
index 0fe550717..4061998f5 100644
--- a/src/AutoComplete/AutoComplete.tsx
+++ b/src/AutoComplete/AutoComplete.tsx
@@ -101,6 +101,7 @@ const AutoComplete: PickerComponent = React.forwardRef(
open,
style,
menuClassName,
+ id,
renderMenu,
renderMenuItem,
onSelect,
@@ -234,6 +235,7 @@ const AutoComplete: PickerComponent = React.forwardRef(
const menu = (
= React.forwardRef(
{
assert.ok(instance.querySelector('input'));
});
- it('Should render 2 `menuitemradio` when set `open` and `defaultValue`', () => {
+ it('Should render 2 `option` when set `open` and `defaultValue`', () => {
const instance = getInstance( );
- assert.equal(instance.menu.querySelectorAll('[role="menuitemradio"]').length, 2);
+ assert.equal(instance.menu.querySelectorAll('[role="option"]').length, 2);
});
it('Should be a `top-end` for placement', () => {
@@ -217,7 +217,7 @@ describe('AutoComplete', () => {
const instance = getInstance(
);
- assert.include(instance.menu.querySelector('[role="menu"]').className, 'custom');
+ assert.include(instance.menu.querySelector('[role="listbox"]').className, 'custom');
});
it('Should have a custom style', () => {
@@ -236,13 +236,13 @@ describe('AutoComplete', () => {
true} />
);
- assert.equal(instance1.menu.querySelectorAll('[role="menuitemradio"]').length, 3);
+ assert.equal(instance1.menu.querySelectorAll('[role="option"]').length, 3);
const instance2 = getInstance(
false} />
);
- assert.equal(instance2.menu.querySelectorAll('[role="menuitemradio"]').length, 0);
+ assert.equal(instance2.menu.querySelectorAll('[role="option"]').length, 0);
const instance3 = getInstance(
{
/>
);
- assert.equal(instance3.menu.querySelectorAll('[role="menuitemradio"]').length, 3);
+ assert.equal(instance3.menu.querySelectorAll('[role="option"]').length, 3);
const instance4 = getInstance(
{
/>
);
- assert.equal(instance4.menu.querySelectorAll('[role="menuitemradio"]').length, 1);
+ assert.equal(instance4.menu.querySelectorAll('[role="option"]').length, 1);
});
});
diff --git a/src/Cascader/Cascader.tsx b/src/Cascader/Cascader.tsx
index f536b2fd5..2bf7fa84c 100644
--- a/src/Cascader/Cascader.tsx
+++ b/src/Cascader/Cascader.tsx
@@ -24,6 +24,7 @@ import {
PickerToggleTrigger,
usePickerClassName,
usePublicMethods,
+ useToggleKeyDownEvent,
pickerToggleTriggerProps,
OverlayTriggerInstance,
PositionChildProps,
@@ -121,6 +122,7 @@ const Cascader: PickerComponent = React.forwardRef((props: Cascad
searchable,
parentSelectable,
placement,
+ id,
renderMenuItem,
renderValue,
renderMenu,
@@ -213,6 +215,14 @@ const Cascader: PickerComponent = React.forwardRef((props: Cascad
[data, disabled, onChange, setSelectedPaths, setColumnData, setValueToPaths, setValue]
);
+ const onPickerKeyDown = useToggleKeyDownEvent({
+ triggerRef,
+ toggleRef,
+ active,
+ onExit: handleClean,
+ ...rest
+ });
+
const handleSelect = (
node: ItemDataType,
cascadeData: ItemDataType[][],
@@ -405,6 +415,7 @@ const Cascader: PickerComponent = React.forwardRef((props: Cascad
{renderSearchResultPanel()}
{searchKeyword === '' && (
= React.forwardRef((props: Cascad
= React.f
const cascadeNodes = cascadeData.map((children, layer) => {
const onlyKey = `${layer}_${children.length}`;
const menu = (
-
+
{children.map((item, index) =>
renderCascadeNode(
item,
diff --git a/src/CheckPicker/CheckPicker.tsx b/src/CheckPicker/CheckPicker.tsx
index ef61455a5..b4bd7519f 100644
--- a/src/CheckPicker/CheckPicker.tsx
+++ b/src/CheckPicker/CheckPicker.tsx
@@ -15,7 +15,6 @@ import {
shallowEqual,
useCustom,
useControlled,
- KEY_CODE,
mergeRefs
} from '../utils';
@@ -32,6 +31,7 @@ import {
usePickerClassName,
useSearch,
usePublicMethods,
+ useToggleKeyDownEvent,
pickerToggleTriggerProps,
OverlayTriggerInstance,
PositionChildProps,
@@ -60,7 +60,6 @@ const defaultProps: Partial = {
classPrefix: 'picker',
countable: true,
searchable: true,
- virtualized: true,
cleanable: true,
data: [],
disabledItemValues: [],
@@ -99,8 +98,15 @@ const CheckPicker: PickerComponent = React.forwardRef(
defaultValue,
groupBy,
listProps,
+ id,
+ sort,
+ searchBy,
renderMenuItem,
renderMenuGroup,
+ renderValue,
+ renderExtraFooter,
+ renderMenu,
+ onGroupTitleClick,
onSearch,
onEnter,
onEntered,
@@ -110,12 +116,6 @@ const CheckPicker: PickerComponent = React.forwardRef(
onSelect,
onClose,
onOpen,
- onGroupTitleClick,
- renderValue,
- renderExtraFooter,
- renderMenu,
- sort,
- searchBy,
...rest
} = props;
@@ -182,18 +182,6 @@ const CheckPicker: PickerComponent = React.forwardRef(
setFocusItemValue(value ? value[0] : undefined);
}, [triggerRef, setFocusItemValue, value]);
- const handleOpen = useCallback(() => {
- triggerRef.current?.open();
- }, [triggerRef]);
-
- const handleToggleDropdown = () => {
- if (active) {
- handleClose();
- return;
- }
- handleOpen();
- };
-
const handleChangeValue = useCallback(
(value: any, event: React.SyntheticEvent) => {
onChange?.(value, event);
@@ -231,26 +219,25 @@ const CheckPicker: PickerComponent = React.forwardRef(
handleChangeValue(nextValue, event);
};
- const handleKeyDown = (event: React.KeyboardEvent) => {
- // enter
- if ((!focusItemValue || !active) && event.keyCode === KEY_CODE.ENTER) {
- handleToggleDropdown();
- }
-
- // delete
- if (event.keyCode === KEY_CODE.BACKSPACE && event.target === toggleRef?.current) {
- handleClean(event);
- }
-
- if (!menuRef.current) {
- return;
- }
- onKeyDown(event);
- onMenuKeyDown(event, {
- enter: selectFocusMenuItem,
- esc: handleClose
- });
- };
+ const onPickerKeyDown = useToggleKeyDownEvent({
+ toggle: !focusItemValue || !active,
+ triggerRef,
+ toggleRef,
+ menuRef,
+ active,
+ onExit: handleClean,
+ onClose: () => {
+ setFocusItemValue(value ? value[0] : undefined);
+ },
+ onMenuKeyDown: event => {
+ onKeyDown(event);
+ onMenuKeyDown(event, {
+ enter: selectFocusMenuItem,
+ esc: handleClose
+ });
+ },
+ ...rest
+ });
const handleSelect = useCallback(
(nextItemValue: any, item: ItemDataType, event: React.SyntheticEvent) => {
@@ -278,6 +265,11 @@ const CheckPicker: PickerComponent = React.forwardRef(
[value, setValue, handleSelect, handleChangeValue, setFocusItemValue]
);
+ const handleEntered = useCallback(() => {
+ setActive(true);
+ onOpen?.();
+ }, [onOpen]);
+
const handleExited = useCallback(() => {
setSearchKeyword('');
setFocusItemValue(null);
@@ -285,11 +277,6 @@ const CheckPicker: PickerComponent = React.forwardRef(
onClose?.();
}, [onClose, setFocusItemValue, setSearchKeyword]);
- const handleEntered = useCallback(() => {
- setActive(true);
- onOpen?.();
- }, [onOpen]);
-
usePublicMethods(ref, { triggerRef, menuRef, toggleRef });
const selectedItems =
@@ -349,6 +336,7 @@ const CheckPicker: PickerComponent = React.forwardRef(
const menu =
items.length || filteredStickyItems.length ? (
= React.forwardRef(
autoWidth={menuAutoWidth}
className={classes}
style={styles}
- onKeyDown={handleKeyDown}
+ onKeyDown={onPickerKeyDown}
target={triggerRef}
>
{searchable && (
@@ -407,10 +395,11 @@ const CheckPicker: PickerComponent = React.forwardRef(
= React.forwardRef(
);
CheckPicker.displayName = 'CheckPicker';
+CheckPicker.defaultProps = defaultProps;
CheckPicker.propTypes = {
...listPickerPropTypes,
locale: PropTypes.any,
@@ -446,6 +436,4 @@ CheckPicker.propTypes = {
searchBy: PropTypes.func
};
-CheckPicker.defaultProps = defaultProps;
-
export default CheckPicker;
diff --git a/src/CheckTreePicker/CheckTreeNode.tsx b/src/CheckTreePicker/CheckTreeNode.tsx
index 79183a6aa..cc4880111 100644
--- a/src/CheckTreePicker/CheckTreeNode.tsx
+++ b/src/CheckTreePicker/CheckTreeNode.tsx
@@ -1,16 +1,16 @@
import React, { forwardRef, useCallback } from 'react';
import PropTypes from 'prop-types';
+import DropdownMenuCheckItem from '../Picker/DropdownMenuCheckItem';
+import { RsRefForwardingComponent, WithAsProps } from '../@types/common';
+import Icon from '../Icon';
import {
useClassNames,
CHECK_STATE,
CheckStateType,
TREE_NODE_PADDING,
- TREE_NODE_ROOT_PADDING
+ TREE_NODE_ROOT_PADDING,
+ reactToString
} from '../utils';
-import reactToString from '../utils/reactToString';
-import DropdownMenuCheckItem from '../Picker/DropdownMenuCheckItem';
-import { RsRefForwardingComponent, WithAsProps } from '../@types/common';
-import Icon from '../Icon';
export interface CheckTreeNodeProps extends WithAsProps {
rtl?: boolean;
@@ -62,7 +62,8 @@ const CheckTreeNode: RsRefForwardingComponent<'div', CheckTreeNodeProps> = forwa
onExpand,
onSelect,
onRenderTreeIcon,
- onRenderTreeNode
+ onRenderTreeNode,
+ ...rest
},
ref
) => {
@@ -180,21 +181,19 @@ const CheckTreeNode: RsRefForwardingComponent<'div', CheckTreeNodeProps> = forwa
);
const padding = layer * TREE_NODE_PADDING + TREE_NODE_ROOT_PADDING;
- const styles = {
- ...style,
- [rtl ? 'paddingRight' : 'paddingLeft']: padding
- };
+ const styles = { ...style, [rtl ? 'paddingRight' : 'paddingLeft']: padding };
return visible ? (
{renderIcon()}
{renderLabel()}
diff --git a/src/CheckTreePicker/CheckTreePicker.tsx b/src/CheckTreePicker/CheckTreePicker.tsx
index 60f3b20dc..35dbfaacf 100644
--- a/src/CheckTreePicker/CheckTreePicker.tsx
+++ b/src/CheckTreePicker/CheckTreePicker.tsx
@@ -103,7 +103,6 @@ const defaultProps: Partial = {
cascade: true,
countable: true,
searchable: true,
- virtualized: true,
menuAutoWidth: true,
defaultValue: [],
appearance: 'default',
@@ -152,6 +151,7 @@ const CheckTreePicker: PickerComponent = React.forwardRef(
menuClassName,
menuAutoWidth,
uncheckableItemValues,
+ id,
renderMenu,
getChildren,
renderExtraFooter,
@@ -220,13 +220,7 @@ const CheckTreePicker: PickerComponent = React.forwardRef(
uncheckableItemValues,
callback: nodes => {
// after flattenData, always unSerialize check property value
- unSerializeList({
- nodes,
- key: 'check',
- value,
- cascade,
- uncheckableItemValues
- });
+ unSerializeList({ nodes, key: 'check', value, cascade, uncheckableItemValues });
forceUpdate();
}
});
@@ -714,6 +708,7 @@ const CheckTreePicker: PickerComponent = React.forwardRef(
const styles = inline ? { height, ...style } : {};
return (
= React.forwardRef(
= React.forwardRe
{...htmlInputProps}
{...inputProps}
name={name}
+ value={value}
type="checkbox"
ref={inputRef}
tabIndex={tabIndex}
disabled={disabled}
aria-disabled={disabled}
- aria-checked={checked}
+ aria-checked={indeterminate ? 'mixed' : checked}
onClick={event => event.stopPropagation()}
onChange={handleChange}
/>
-
+
);
diff --git a/src/CloseButton/CloseButton.tsx b/src/CloseButton/CloseButton.tsx
index 08b49baa7..937627f6b 100644
--- a/src/CloseButton/CloseButton.tsx
+++ b/src/CloseButton/CloseButton.tsx
@@ -36,7 +36,7 @@ const CloseButton: RsRefForwardingComponent<'button', CloseButtonProps> = React.
title={locale?.closeLabel}
aria-label={locale?.closeLabel}
>
- ×
+ ×
);
}
diff --git a/src/DatePicker/DatePicker.tsx b/src/DatePicker/DatePicker.tsx
index e88923248..2d1ac2eff 100644
--- a/src/DatePicker/DatePicker.tsx
+++ b/src/DatePicker/DatePicker.tsx
@@ -24,6 +24,7 @@ import {
PickerToggleTrigger,
usePickerClassName,
usePublicMethods,
+ useToggleKeyDownEvent,
pickerToggleTriggerProps,
OverlayTriggerInstance,
PositionChildProps,
@@ -339,13 +340,21 @@ const DatePicker: RsRefForwardingComponent<'div', DatePickerProps> = React.forwa
}, [calendarState, onToggleTimeDropdown, openTime, reset]);
const handleClean = useCallback(
- (event: React.MouseEvent) => {
+ (event: React.SyntheticEvent) => {
setPageDate(TimeZone.toTimeZone(new Date(), timeZone));
updateValue(event, null);
},
[updateValue, timeZone]
);
+ const onPickerKeyDown = useToggleKeyDownEvent({
+ triggerRef,
+ toggleRef,
+ active,
+ onExit: handleClean,
+ ...rest
+ });
+
const handleSelect = useCallback(
(nextValue: Date, event: React.SyntheticEvent) => {
setPageDate(
@@ -500,6 +509,7 @@ const DatePicker: RsRefForwardingComponent<'div', DatePickerProps> = React.forwa
])}
as={toggleAs}
ref={toggleRef}
+ onKeyDown={onPickerKeyDown}
onClean={createChainedFunction(handleClean, onClean)}
cleanable={cleanable && !disabled}
hasValue={hasValue}
diff --git a/src/DateRangePicker/DateRangePicker.tsx b/src/DateRangePicker/DateRangePicker.tsx
index 7ade34464..665b1a59d 100644
--- a/src/DateRangePicker/DateRangePicker.tsx
+++ b/src/DateRangePicker/DateRangePicker.tsx
@@ -25,6 +25,7 @@ import {
usePickerClassName,
OverlayTriggerInstance,
usePublicMethods,
+ useToggleKeyDownEvent,
pickerToggleTriggerProps,
PickerToggle,
PickerToggleTrigger,
@@ -543,13 +544,21 @@ const DateRangePicker: DateRangePicker = React.forwardRef((props: DateRangePicke
}, [onClose]);
const handleClean = useCallback(
- (event: React.MouseEvent) => {
+ (event: React.SyntheticEvent) => {
setCalendarDate(getCalendarDate({ timeZone }));
updateValue(event, []);
},
[timeZone, updateValue]
);
+ const onPickerKeyDown = useToggleKeyDownEvent({
+ triggerRef,
+ toggleRef,
+ active,
+ onExit: handleClean,
+ ...rest
+ });
+
const renderDropdownMenu = (positionProps: PositionChildProps, speakerRef) => {
const { left, top, className } = positionProps;
const classes = merge(className, menuClassName, prefix('daterange-menu'));
@@ -626,6 +635,7 @@ const DateRangePicker: DateRangePicker = React.forwardRef((props: DateRangePicke
])}
as={toggleAs}
ref={toggleRef}
+ onKeyDown={onPickerKeyDown}
onClean={createChainedFunction(handleClean, onClean)}
cleanable={cleanable && !disabled}
hasValue={hasValue}
diff --git a/src/FormControl/FormControl.tsx b/src/FormControl/FormControl.tsx
index 67148cdd3..3d8fd31d4 100644
--- a/src/FormControl/FormControl.tsx
+++ b/src/FormControl/FormControl.tsx
@@ -159,9 +159,10 @@ const FormControl: RsRefForwardingComponent<'div', FormControlProps> = React.for
return (
...rest
} = props;
- const { controlId } = useContext(FormGroupContext) || {};
+ const { controlId } = useContext(FormGroupContext);
const { withClassPrefix, merge } = useClassNames(classPrefix);
const classes = merge(className, withClassPrefix());
- return ;
+ return (
+
+ );
}
);
diff --git a/src/FormGroup/FormGroup.tsx b/src/FormGroup/FormGroup.tsx
index 908896b06..7203e4d07 100644
--- a/src/FormGroup/FormGroup.tsx
+++ b/src/FormGroup/FormGroup.tsx
@@ -4,11 +4,14 @@ import { createContext, useClassNames } from '../utils';
import { WithAsProps, RsRefForwardingComponent } from '../@types/common';
export interface FormGroupProps extends WithAsProps {
- /** Sets id for controlled component */
+ /**
+ * Sets id on `` and `htmlFor` on ``.
+ * And generate ʻaria-labelledby` and ʻaria-describedby` for ``.
+ */
controlId?: string;
}
-export const FormGroupContext = createContext(null);
+export const FormGroupContext = createContext({});
const FormGroup: RsRefForwardingComponent<'div', FormGroupProps> = React.forwardRef(
(props: FormGroupProps, ref) => {
diff --git a/src/FormHelpText/FormHelpText.tsx b/src/FormHelpText/FormHelpText.tsx
index 8ad96dbe9..c5d77fed7 100644
--- a/src/FormHelpText/FormHelpText.tsx
+++ b/src/FormHelpText/FormHelpText.tsx
@@ -1,10 +1,11 @@
-import React from 'react';
+import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import Tooltip from '../Tooltip';
import Whisper from '../Whisper';
import Icon from '../Icon';
import { useClassNames } from '../utils';
import { WithAsProps, RsRefForwardingComponent } from '../@types/common';
+import { FormGroupContext } from '../FormGroup/FormGroup';
export interface FormHelpTextProps extends WithAsProps {
/** Whether to show through the Tooltip component */
@@ -22,6 +23,7 @@ const FormHelpText: RsRefForwardingComponent<'span', FormHelpTextProps> = React.
...rest
} = props;
+ const { controlId } = useContext(FormGroupContext);
const { withClassPrefix, merge } = useClassNames(classPrefix);
const classes = merge(className, withClassPrefix({ tooltip }));
@@ -36,7 +38,12 @@ const FormHelpText: RsRefForwardingComponent<'span', FormHelpTextProps> = React.
}
return (
-
+
{children}
);
diff --git a/src/Input/Input.tsx b/src/Input/Input.tsx
index 9912ccb32..a826a0fa2 100644
--- a/src/Input/Input.tsx
+++ b/src/Input/Input.tsx
@@ -48,7 +48,7 @@ export interface InputProps
const defaultProps: Partial = {
as: 'input',
classPrefix: 'input',
- type: 'type'
+ type: 'text'
};
const Input: RsRefForwardingComponent<'input', InputProps> = React.forwardRef(
@@ -58,7 +58,7 @@ const Input: RsRefForwardingComponent<'input', InputProps> = React.forwardRef(
classPrefix,
as: Component,
locale: overrideLocale,
- type = 'text',
+ type,
disabled,
value,
defaultValue,
diff --git a/src/InputPicker/InputPicker.tsx b/src/InputPicker/InputPicker.tsx
index 440c36b2f..db3243f9b 100644
--- a/src/InputPicker/InputPicker.tsx
+++ b/src/InputPicker/InputPicker.tsx
@@ -33,6 +33,7 @@ import {
usePickerClassName,
useSearch,
usePublicMethods,
+ useToggleKeyDownEvent,
pickerToggleTriggerProps,
OverlayTriggerInstance,
PositionChildProps,
@@ -90,7 +91,6 @@ const defaultProps: Partial = {
labelKey: 'label',
placement: 'bottomStart',
searchable: true,
- virtualized: true,
menuAutoWidth: true,
menuMaxHeight: 320,
tagProps: {}
@@ -127,6 +127,7 @@ const InputPicker: PickerComponent = React.forwardRef(
virtualized,
labelKey,
listProps,
+ id,
sort,
renderMenu,
renderExtraFooter,
@@ -164,6 +165,8 @@ const InputPicker: PickerComponent = React.forwardRef(
const [maxWidth, setMaxWidth] = useState(100);
const [newData, setNewData] = useState([]);
const [uncontrolledOpen, setOpen] = useState(defaultOpen);
+ // Use component active state to support keyboard events.
+ const [active, setActive] = useState(false);
const open = isUndefined(controlledOpen) ? uncontrolledOpen : controlledOpen;
const getAllData = useCallback(() => [].concat(uncontrolledData, newData), [
@@ -490,12 +493,11 @@ const InputPicker: PickerComponent = React.forwardRef(
]
);
- const handleKeyDown = useCallback(
- (event: React.KeyboardEvent) => {
- if (!menuRef.current) {
- return;
- }
-
+ const onPickerKeyDown = useToggleKeyDownEvent({
+ triggerRef,
+ toggleRef,
+ menuRef,
+ onMenuKeyDown: event => {
onKeyDown(event);
onMenuKeyDown(event, {
enter: multi ? selectFocusMenuCheckItem : selectFocusMenuItem,
@@ -503,17 +505,8 @@ const InputPicker: PickerComponent = React.forwardRef(
del: multi ? removeLastItem : handleClean
});
},
- [
- onKeyDown,
- handleClose,
- handleClean,
- removeLastItem,
- selectFocusMenuCheckItem,
- selectFocusMenuItem,
- multi,
- menuRef
- ]
- );
+ ...rest
+ });
const handleExited = useCallback(() => {
setFocusItemValue(multi ? value?.[0] : value);
@@ -527,6 +520,14 @@ const InputPicker: PickerComponent = React.forwardRef(
onClose?.();
}, [setFocusItemValue, setSearchKeyword, onClose, value, multi]);
+ const handleFocus = useCallback(() => {
+ setActive(true);
+ }, []);
+
+ const handleBlur = useCallback(() => {
+ setActive(false);
+ }, []);
+
const handleEnter = useCallback(() => {
focusInput();
setOpen(true);
@@ -625,6 +626,7 @@ const InputPicker: PickerComponent = React.forwardRef(
const menu = items.length ? (
| | | | | |