It’s been nearly two years since the first version of V4, with more than 30 iterations and many new features in that time. More and more developers are using React Suite and getting involved in feature development and improvements. Thanks again to the developers who have been giving us valuable advice. We hope React Suite will continue to grow as your products continue to grow, and we hope it will serve more developers.

React Suite 5 improves component accessibility and provides richer and more customizable components. The following details the new features and how to upgrade from 4.x to 5.0.

Main Functions ✨

Improve Accessibility

Our hope is to make React Suite products accessible to as many users as possible. We’ll improve each of the React Suite components in multiple scenarios, from keyboard manipulation to screen readers.

Barrier-free design

React Suite follows the WAI-ARIA standard, refactoring all components with appropriate properties and keyboard interaction out of the box.

Added a set of high contrast themes

In React Suite V4, we’ve made major improvements to the components that satisfy most users by referring to the Web Content Accessibility Guidelines (WCAG) for color contrast. We want to build on that and take care of the small number of people who are visually impaired. React Suite currently offers three themes (light, Dark, and high-Contrast).

Use SVG Icon instead of Icon font

There are some rendering issues with Icon font, resulting in blurred ICONS, font files that need to be loaded, blinking content areas, etc. For better Accessibility, we decided to preferentially use the SVG Icon. And friendly compatibility with third-party icon resources.

import GearIcon from "@rsuite/icons/Gear";

render(<GearIcon />);

// output
<svg>
  <path d="M11.967..."></path>
  <path d="M8 10a2 2 0 10.001-3.999A2 2 0 008 10zm0 1a3 3 0 110-6 3 3 3 0 010 6z"></path>
</svg>;
Copy the code

Support CSS variables

The current mainstream browsers have supported CSS variables, we plan to provide a set of component CSS variable configuration, which can be more convenient to do theme customization, theme switch.

Refactoring with functional components

We refactored most of the components with functional components, using new features from React Hooks to improve the development experience.

According to the need to load

When importing components in V4, you need to distinguish between CJS and ESM. This is automatic in V5.

// v4: cjs
import Button from "rsuite/lib/Button";
// v4: esm
import Button from "rsuite/es/Button";

// v5
import Button from "rsuite/Button";
Copy the code

Improvements to the Form Form

  • Improved the effect of Forms in plain text views.
  • Rename the component.
'FormGroup' renamed to 'form. Group' FormControl 'renamed to' form. Control ' 'ControlLabel' renamed to 'form. ControlLabel' 'ErrorMessage' Rename 'form. ErrorMessage' and 'HelpBlock' to 'form. HelpText'Copy the code
  • Form validation supports object structures.
const model = SchemaModel({
  username: StringType().isRequired("Username required"),
  tags: ArrayType().of(StringType("The tag should be a string").isRequired()),
  role: ObjectType.shape({
    name: StringType().isRequired("Name required"),
    permissions: ArrayType().isRequired("Permissions required"),})});const checkResult = model.check({
  username: "foobar".tags: ["Sports"."Games".10].role: { name: "administrator"}});console.log(checkResult);
Copy the code

Output data structure:

{
  username: { hasError: false },
  tags: {
    hasError: true.array: [{hasError: false },
      { hasError: false },
      { hasError: true.errorMessage: 'The tag should be a string'}},role: {
    hasError: true.object: {
      name: { hasError: false },
      permissions: { hasError: true.errorMessage: 'Permissions required'}}}};Copy the code

For a detailed tutorial, see Form Validation and Schema

Avatar added support for srcSet, Sizes, and imgProps

  • srcSet: <img>Elements of thesrcSetProperties. Use this property for reactive image display.
  • sizes: <img>Elements of thesizesProperties.
  • ImgProps: Applied to if this component is used to display images<img>Attribute of the element.

Slider and RangeSlider supportonChangeCommitted

Onchangecomadmitted. The difference between onChangecomadmitted and onChange is that onChange was admitted every time a value changed. Onchangecomadmitted is a callback triggered after the Mouseup event was fired and the value changed.

DatePicker and DateRangePicker functions improved

  • DatePicker and DateRangePicker support keyboard input.

  • DateRangePicker previously could only select a date, in V5 you can select a time.

<DateRangePicker format="yyyy-MM-dd HH:mm:ss" />
Copy the code

The Badge supportcolorattribute

The color property sets the style of the logo prompt point

<Badge color="red">Red</Badge>
<Badge color="orange">Orange</Badge>
<Badge color="yellow">Yellow</Badge>
<Badge color="green">Green</Badge>
<Badge color="cyan">Cyan</Badge>
<Badge color="blue">Blue</Badge>
<Badge color="violet">Violet</Badge>
<Badge color="red" />
<Badge color="orange" />
<Badge color="yellow" />
<Badge color="green" />
<Badge color="cyan" />
<Badge color="blue" />
<Badge color="violet" />
<Badge color="blue" content="99 +" />
<Badge color="violet" content="NEW" />
Copy the code

Improvements to Table

  • Reconstruction of the Table

Refactored tables using React hooks and improved Table scrolling performance. Deprecated onDataUpdated and bodyRef properties.

For components that will be rendered inside the table, you can previously get the body container of the table through bodyRef. Now we can get the container directly from Table ref.

// v4
const bodyRef = useRef();
return (
  <>
    <Table
      bodyRef={(body)= >{ bodyRef.current = body; }} / ><CheckPicker container={()= > bodyRef.current} />
  </>
);

// v5
const ref = useRef();
return (
  <>
    <Table ref={ref} />
    <CheckPicker container={()= > ref.current.body} />
  </>
);
Copy the code
  • RowSpan merging rows is supported

const data = [
  {
    city: "New Gust".name: "Janis".rowspan: 2}, {city: "New Gust".name: "Ernest Schuppe Anderson"}, {city: "Maria Junctions".name: "Alessandra".rowspan: 3}, {city: "Maria Junctions".name: "Margret"}, {city: "Maria Junctions".name: "Emiliano",},];return (
  <Table data={data}>
    <Column
      width={100}
      verticalAlign="middle"
      rowSpan={(rowData)= > {
        return rowData.rowspan;
      }}
    >
      <HeaderCell>Name</HeaderCell>
      <Cell dataKey="city" />
    </Column>
    <Column width={100}>
      <HeaderCell />
      <Cell dataKey="name" />
    </Column>
  </Table>
);
Copy the code

Added the TagInput component

Input enhancements, support for Input labels, management labels.

import TagInput from "rsuite/TagInput";

return (
  <TagInput
    defaultValue={["HTML","CSS"]}
    trigger={["Enter","Space","Comma]} "/ >
);
Copy the code

Improvements to Carousel

OnSelect, onSlideEnd, onSlideStart properties are supported on

components.

  • onSelect: Callback triggered when an activity item changes
  • onSlideEnd: a callback triggered when the slide transition ends
  • onSlideStart: the callback triggered when the slide transition begins

Upgrade from V4 to V5 🚀

Here’s how you can quickly upgrade from V4 to V5.

The preparatory work

  • React Upgrade to version 16.8 or later.
  • Make sure your currentrsuiteVersion is4. *, otherwise,Migrate to V4 first.

Run codemods

The process of upgrading components is often painful for large projects, and we’ve prepared Codemods to simplify your migration experience.

Directions for use

npx rsuite-codemod <transform> <path> [...options]
Copy the code
  • transform – Name of the transformation.
  • path– The file or directory to be converted.
  • use--dryOptions for trial run and use--printPrint the output for comparison.

Incompatible changes

Compatibility support for IE 10 is no longer available

We will no longer support IE 10 in version V5. If you need to continue using IE 10, please continue using VERSION V4.

- last 2 versions or > 1% or ie >= 10
+ last 2 versions or > 1% and not ie <11
Copy the code

Use SVG Icon instead of Icon font

To use SVG ICONS, you need to install @rsuite/ ICONS before using them.

npm i @rsuite/icons
Copy the code
// for rsuite v4
import { Icon } from "rsuite";

return <Icon icon="gear" />;

// for rsuite v5
import GearIcon from "@rsuite/icons/Gear";

return <GearIcon />;
Copy the code

Remove the size attribute and use fontSize instead.

// for rsuite v4
return <Icon icon="gear" size="3x" />;

// for rsuite v5
return <GearIcon style={{ fontSize: "3em}} "/ >;
Copy the code

The size attribute value and its corresponding fontSize value relationship are as follows:

  • lg : 1.3333 em
  • 2x : 2em
  • 3x : 3em
  • 4x : 4em
  • 5x : 5em

The date – FNS upgrade v2

The React Suite uses the date-fNS tool for date formatting, calculation, and more. Based on the Unicode standard, there are changes to the new format string used for formatting functionality.

// for rsuite v4

return (
  <>
    <DatePicker format="YYYY-MM-DD" />
    <DateRangePicker format="YYYY-MM-DD" />
  </>
);

// for rsuite v5

return (
  <>
    <DatePicker format="yyyy-MM-dd" />
    <DateRangePicker format="yyyy-MM-dd" />
  </>
);
Copy the code

Discard the Alert component with thetoaster.push(<Message>)Instead of

All pop-up notification messages are managed using the new API Toaster. The Alert component will be deprecated, and toaster will be used in combination with Message instead. Such as:

// for rsuite v4
Alert.info("description");

// for rsutie v5
toaster.push(
  <Message type="info" closable>
    description
  </Message>
);
Copy the code

Deletes a message or clears a message

// Remove message
const key = toaster.push(
  <Message type="info" closable>
    description
  </Message>
);
toaster.remove(key);

// Clear all messages
toaster.clear();
Copy the code

Example Modify the usage mode of Notification

// for rsuite v4
Notification.info({
  title: "info".description: "description".duration: 4500.placement: "topStart"});// for rsuite v5
toaster.push(
  <Notification type="info" header="info" duration={4500}>
    description
  </Notification>,
  { placement: "topStart"});Copy the code

Rename the Form related component

  • FormGrouprenameForm.Group
  • FormControlrenameForm.Control
  • ControlLabelrenameForm.ControlLabel
  • ErrorMessagerenameForm.ErrorMessage
  • HelpBlockrenameForm.HelpText

Rename the componentClass property for all components to AS

// for rsuite v4
return <Button componentClass="span" />;

// for rsuite v5
return <Button as="span" />;
Copy the code

On All Pickers Virtualized by default

The default mode on all Pickers is False. Set to true if you want to continue using it in your project.

<SelectPicker virtualized />
Copy the code

Improved the way to update children asynchronously

To facilitate asynchronous updating of child nodes, a getChildren property has been added. Affected components:

  • Cascader
  • MutilCascader
  • TreePicker
  • CheckTreePicker
getChildren:(node: ItemDataType) = > Promise<ItemDataType[]>
Copy the code
function fetchNodes(id) {
  return new Promise((resolve) = > {
    // fetch the child node data async
    resolve(childrenNodes);
  });
}

return (
  <>
    <Cascader getChildren={(node)= > fetchNodes(node.id)} />
  </>
);
Copy the code

Delete table. Pagination and enhance Pagination

The table. Pagination component is deleted in this update, please use Pagination instead, and the layout property is added for custom layout.

// for rsuite v4
return (
  <Table.Pagination
    lengthMenu={[
      { value: 50.label: 50 },
      { value: 100.label: 100]}},activePage={1}
    displayLength={20}
    total={100}
    onChangePage={handleChangePage}
    onChangeLength={handleChangeLength}
  />
);

// for rsuite v5
return (
  <Pagination
    limit={50}
    limitOptions={[50, 100]}
    layout={["total","-","limit", "|","pager","skip"]}
    total={100}
    activePage={1}
    onChangePage={handleChangePage}
    onChangeLimit={handleChangeLimit}
  />
);
Copy the code

useCustomProviderreplaceIntlProvider

// for rsuite v4
import { IntlProvider } from "rsuite";
import zhCN from "rsuite/lib/IntlProvider/locales/zh_CN";

return (
  <IntlProvider locale={zhCN}>
    <App />
  </IntlProvider>
);

// for rsuite v5
import { CustomProvider } from "rsuite";
import zhCN from "rsuite/locales/zh_CN";

return (
  <CustomProvider locale={zhCN}>
    <App />
  </CustomProvider>
);
Copy the code

abandoned<Sidenav>The component’sactiveKey å’Œ onSelectattribute

The

component is always used with the

// for rsuite v4

return (
  <Sidenav activeKey={activeKey} onSelect={setActiveKey}>
    <Sidenav.Body>
      <Nav>
        <Nav.Item>Nav item</Nav.Item>
        <Dropdown title="Dropdown">
          <Dropdown.Item>Dropdown item</Dropdown.Item>
        </Dropdown>
      </Nav>
    </Sidenav.Body>
  </Sidenav>
);

// for rsuite v5

return (
  <Sidenav>
    <Sidenav.Body>
      <Nav activeKey={activeKey} onSelect={setActiveKey}>
        <Nav.Item>Nav item</Nav.Item>
        <Dropdown title="Dropdown">
          <Dropdown.Item>Dropdown item</Dropdown.Item>
        </Dropdown>
      </Nav>
    </Sidenav.Body>
  </Sidenav>
);
Copy the code

According to the need to load

Imported components

// v4
import Button from "rsuite/lib/Button";
import "rsuite/lib/Button/styles/index.less";

// v5
import Button from "rsuite/Button";
import "rsuite/Button/styles/index.less";
Copy the code

Import the localization language pack

// v4
import ruRU from "rsuite/lib/IntlProvider/locales/ru_RU";

// v5
import ruRU from "rsuite/locales/ru_RU";
Copy the code

Global import style

// v4
import "rsuite/lib/styles/index.less"; // less
import "rsuite/dist/styles/rsuite-default.css"; // css

// v5
import "rsuite/styles/index.less"; // less
import "rsuite/dist/rsuite.min.css"; // or css
import "rsuite/dist/rsuite-rtl.min.css"; // or rtl css
Copy the code

abandoned<Dropdown>The component’srenderTitleattribute

Discard renderTitle and replace it with renderToggle.

//v4
return (
  <Dropdown
    renderTitle={()= > (
      <IconButton appearance="primary" icon={<Icon icon="plus" />} circle />
    )}
  >
    ...
  </Dropdown>
);

//v5
return (
  <Dropdown
    renderToggle={(props, ref) = > (
      <IconButton
        {. props}
        ref={ref}
        icon={<PlusIcon />}
        circle
        appearance="primary"
      />
    )}
  >
    ...
  </Dropdown>
);
Copy the code

withopen/closeInstead ofshow/hide.

In v4, component property names are used in both open/close and show/hide. The naming is unified in V5.

// v4

<Modal show="{true}" onShow="{... }" onHide="{... }" />
<Drawer show="{true}" onShow="{... }" onHide="{... }" />
<Whisper delayHide="{1000}" delayShow="{1000}" />

// v5
<Modal open="{true}" onOpen="{... }" onClose="{... }" />
<Drawer open="{true}" onOpen="{... }" onClose="{... }" />
<Whisper delayClose="{1000}" delayOpen="{1000}" />
Copy the code

Support the React Suite

If you like React Suite, you can support us by:

  • Star project.
  • If you use React Suite in your projects, please leave a comment here
  • Sponsor us on OpenCollective.