Skip to main content

Prerequisites

Before beginning the migration, ensure you have:
  • A working 4.7.x implementation
  • Node.js 18.x or higher installed
  • TypeScript 5.0.x or higher
  • Reviewed the breaking changes documentation
  • Created a backup or feature branch for your migration work
This is a major version upgrade with breaking changes. We recommend thorough testing before deploying to production.

Migration process

1

Update package dependencies

Update your package.json to use the latest 5.x version of the UI Toolkit.
2

Remove redundant peer dependencies

Remove peer dependencies that are now bundled with version 5.x.
3

Update Select component implementations

Refactor all Select component usage to match the new render props API.
4

Update form control implementations

Update form-related components that have been restructured.
5

Update icon imports

Adjust icon imports to match the new icon system structure.
6

Test all components

Thoroughly test your application, paying special attention to forms and interactive components.

Update package dependencies

React UI Toolkit

Before (4.7.11)

package.json
{
  "dependencies": {
    "@flowx/react-ui-toolkit": "4.7.11",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-hook-form": "^7.53.0",
    "air-datepicker": "^3.5.0",
    "ag-grid-react": "^32.2.0"
  }
}

After (5.5.0)

package.json
{
  "dependencies": {
    "@flowx/react-ui-toolkit": "5.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }
}
Version 5.x bundles air-datepicker and ag-grid-react as direct dependencies. You can remove these from your package.json if they’re only used by the UI Toolkit.

Angular UI Toolkit

Before (4.7.11)

package.json
{
  "dependencies": {
    "@flowx/angular-ui-toolkit": "4.7.11",
    "@angular/core": "^17.0.0",
    "@angular/common": "^17.0.0",
    "@angular/forms": "^17.0.0"
  }
}

After (5.5.0)

package.json
{
  "dependencies": {
    "@flowx/angular-ui-toolkit": "5.5.0",
    "@angular/core": "^17.0.0",
    "@angular/common": "^17.0.0",
    "@angular/forms": "^17.0.0"
  }
}

Install dependencies

After updating your package.json, install the new dependencies:
npm install

Update Select component

The Select component has undergone significant API changes. All Select implementations must be updated.

Key changes

  • onChange now receives Option<T> objects instead of raw values
  • value prop now expects Option<T> objects instead of raw values
  • New children render prop for custom option rendering
  • error prop changed from FieldError to boolean
  • Removed react-hook-form direct dependency
  • New FlxSelectContainer component for wrapper functionality

Single select migration

Before (4.7.x)

import { FlxSelect } from '@flowx/react-ui-toolkit';

function MyComponent() {
  const [value, setValue] = useState('option1');
  
  const options = [
    { value: 'option1', label: 'Option 1' },
    { value: 'option2', label: 'Option 2' },
    { value: 'option3', label: 'Option 3' }
  ];
  
  return (
    <FlxSelect
      options={options}
      value={value}
      onChange={(newValue) => setValue(newValue)}
      placeholder="Select an option"
    />
  );
}

After (5.x)

import { FlxSelect, FlxSelectContainer } from '@flowx/react-ui-toolkit';
import { SelectOption } from '@flowx/react-ui-toolkit';

function MyComponent() {
  const [value, setValue] = useState<Option<string> | null>({
    value: 'option1',
    label: 'Option 1'
  });
  
  const options = [
    { value: 'option1', label: 'Option 1' },
    { value: 'option2', label: 'Option 2' },
    { value: 'option3', label: 'Option 3' }
  ];
  
  return (
    <FlxSelectContainer>
      <FlxSelect
        options={options}
        value={value}
        onChange={(newValue) => setValue(newValue as Option<string>)}
        placeholder="Select an option"
      >
        {(option, onClick, isSelected) => (
          <SelectOption
            option={option}
            onClick={onClick}
            isSelected={isSelected}
          />
        )}
      </FlxSelect>
    </FlxSelectContainer>
  );
}

Multi-select migration

Multi-select functionality is significantly enhanced in v5.x with better customization options.

Before (4.7.x)

Multi-select was limited in 4.7.x with minimal customization options.
// Limited multi-select support in 4.7.x
import { FlxSelect } from '@flowx/react-ui-toolkit';

function MyComponent() {
  const [values, setValues] = useState<string[]>(['option1']);
  
  // Multi-select required workarounds in 4.7.x
  return (
    <FlxSelect
      options={options}
      value={values[0]}
      onChange={(value) => {
        // Custom multi-select logic
      }}
    />
  );
}

After (5.x)

import { FlxSelect, FlxSelectContainer } from '@flowx/react-ui-toolkit';
import { MultiSelectOption, MultiSelectSearch, MultiSelectSelections } from '@flowx/react-ui-toolkit';
import { MultiSelectOptionsDisplayModeType } from '@flowx/core-sdk';

function MyComponent() {
  const [values, setValues] = useState<Option<string>[]>([
    { value: 'option1', label: 'Option 1' }
  ]);
  
  const options = [
    { value: 'option1', label: 'Option 1' },
    { value: 'option2', label: 'Option 2' },
    { value: 'option3', label: 'Option 3' }
  ];
  
  return (
    <FlxSelectContainer>
      <FlxSelect
        options={options}
        value={values}
        onChange={(newValues) => setValues(newValues as Option<string>[])}
        multiselect={true}
        maxSelectable={5}
        optionsDisplayMode={MultiSelectOptionsDisplayModeType.COMMA_SEPARATED}
        placeholder="Select options"
        multiSelectSearch={(props) => <MultiSelectSearch {...props} />}
        multiSelectSelections={(props) => <MultiSelectSelections {...props} />}
      >
        {(option, onClick, isSelected, isDisabled) => (
          <MultiSelectOption
            option={option}
            onClick={onClick}
            isSelected={isSelected}
            isDisabled={isDisabled}
          />
        )}
      </FlxSelect>
    </FlxSelectContainer>
  );
}

Select with form integration

Before (4.7.x)

import { FlxSelect } from '@flowx/react-ui-toolkit';
import { useForm, Controller } from 'react-hook-form';

function FormComponent() {
  const { control } = useForm();
  
  return (
    <Controller
      name="selectedOption"
      control={control}
      render={({ field, fieldState }) => (
        <FlxSelect
          {...field}
          options={options}
          error={fieldState.error}
        />
      )}
    />
  );
}

After (5.x)

import { FlxSelect, FlxSelectContainer, SelectOption } from '@flowx/react-ui-toolkit';
import { useForm, Controller } from 'react-hook-form';

function FormComponent() {
  const { control } = useForm();
  
  return (
    <Controller
      name="selectedOption"
      control={control}
      render={({ field, fieldState }) => (
        <FlxSelectContainer>
          <FlxSelect
            value={field.value}
            onChange={field.onChange}
            onBlur={field.onBlur}
            options={options}
            error={!!fieldState.error}
          >
            {(option, onClick, isSelected) => (
              <SelectOption
                option={option}
                onClick={onClick}
                isSelected={isSelected}
              />
            )}
          </FlxSelect>
        </FlxSelectContainer>
      )}
    />
  );
}
Note the change from error={fieldState.error} to error={!!fieldState.error}. The error prop is now a boolean instead of a FieldError object.

Update form controls

Form control structure

The form control structure has been simplified in v5.x with some components removed.

Removed components in v5.x

  • FlxFormField - Use native form structure instead
  • FlxFormItem - Use native form structure instead
  • FlxFormControl - Use native form structure instead
  • FlxFormContent - Use native form structure instead
  • useFormField hook - Use react-hook-form hooks directly
The FlxForm component remains unchanged and continues to work with react-hook-form.

Before (4.7.x)

import { FlxForm, FlxFormField, FlxFormItem, FlxFormControl } from '@flowx/react-ui-toolkit';
import { useFormField } from '@flowx/react-ui-toolkit';
import { useForm } from 'react-hook-form';

function MyForm() {
  const form = useForm();
  
  return (
    <FlxForm {...form}>
      <FlxFormField
        control={form.control}
        name="username"
        render={({ field }) => (
          <FlxFormItem>
            <FlxFormControl>
              <Input {...field} />
            </FlxFormControl>
          </FlxFormItem>
        )}
      />
    </FlxForm>
  );
}

After (5.x)

import { FlxForm, Input } from '@flowx/react-ui-toolkit';
import { useForm, Controller } from 'react-hook-form';

function MyForm() {
  const form = useForm();
  
  return (
    <FlxForm {...form}>
      <Controller
        control={form.control}
        name="username"
        render={({ field }) => (
          <div className="form-field">
            <Input {...field} />
          </div>
        )}
      />
    </FlxForm>
  );
}

Update icon imports

The icon system structure has changed in v5.x.

Icon dictionary removal

Before (4.7.x)

import { Icon } from '@flowx/react-ui-toolkit';
import { IconDictionary } from '@flowx/react-ui-toolkit';

function MyComponent() {
  return <Icon name={IconDictionary.CHECK} />;
}

After (5.x)

import { Icon } from '@flowx/react-ui-toolkit';

function MyComponent() {
  // Icon names are now strings
  return <Icon name="check" />;
}
The icon set is now available as a centralized import structure without the dictionary pattern.

New components in v5.x

Chip component

Version 5.x introduces a new Chip component for displaying tags, filters, and selections.
import { Chip } from '@flowx/react-ui-toolkit';

function MyComponent() {
  return (
    <div>
      <Chip label="New Feature" />
      <Chip 
        label="Removable" 
        onRemove={() => console.log('removed')}
      />
      <Chip 
        label="Clickable" 
        onClick={() => console.log('clicked')}
      />
    </div>
  );
}

Dependency changes

Removed dependencies

The following dependencies have been removed from v5.x:
  • react-use-measure - No longer required
  • react-remove-scroll - No longer required
  • @react-spring/web - No longer required
  • @radix-ui/react-use-controllable-state - Replaced with @base-ui-components/react
  • @radix-ui/react-slot - Replaced with @base-ui-components/react
  • @radix-ui/react-use-previous - Replaced with @base-ui-components/react

Added dependencies

The following dependencies have been added in v5.x:
If your application directly uses @radix-ui primitives, you’ll need to continue including them in your dependencies. The UI Toolkit has migrated to @base-ui-components/react.

Testing your migration

Component checklist

Test the following components thoroughly:
  • All Select components (single and multi-select)
  • Forms with validation
  • Date pickers
  • Tables with data
  • Modals and overlays
  • File uploads
  • Document viewers
  • Accordions
  • Steppers
  • Tab bars
  • Toasts and notifications
  • Buttons and interactive elements

Common issues

Ensure you’re passing Option<T> objects instead of raw values. The value should be the entire option object, not just the value property.
// Incorrect
value="option1"

// Correct
value={{ value: "option1", label: "Option 1" }}
Check that you’re converting the error prop to a boolean for components like Select:
// Incorrect
error={fieldState.error}

// Correct
error={!!fieldState.error}
Update icon references from the dictionary pattern to string-based names:
// Incorrect
name={IconDictionary.CHECK}

// Correct
name="check"
Ensure you’re importing the Option type and using it correctly:
import { FlxSelect, Option } from '@flowx/react-ui-toolkit';

const [value, setValue] = useState<Option<string> | null>(null);

Rollback plan

If you encounter critical issues during migration:
1

Revert package.json changes

Restore the 4.7.x version in your package.json.
2

Reinstall dependencies

Run npm install to restore the previous dependencies.
3

Revert code changes

Use git to revert any code changes made during migration.
4

Document issues

Document any blocking issues you encountered for future reference.

Getting help

If you encounter issues during migration:

Next steps

Breaking changes reference

Review the complete list of breaking changes across versions

Build docs developers (and LLMs) love