-
Notifications
You must be signed in to change notification settings - Fork 38
iTwinUI react v3 migration guide
To help with the migration (for breaking changes), we also provide a migration tool that scans your project repo for old code and runs automated codemods.
Download options:
- Clone iTwinUI-migration-tool GitHub repo (recommended)
- Download zip file (version: 24 Sep 2024) with the tool (for users outside the iTwin GitHub org)
This page documents all breaking changes in @itwin/itwinui-react@^3.0.0
. Make sure to install the latest 3.x version and resolve any version conflicts.
Also see @itwin/[email protected]
migration guide.
- #1389: iTwinUI is now ESM-first and correctly supports both ESM and CJS environments.
-
#1412: All styles have been wrapped inside a cascade layer named
itwinui
. See the styling documentation for more. - #1583: Bumped minimum required react version to 17. If you're still on react 16, please update to react 17 (which has no breaking changes).
-
#1298: Most components are now polymorphic (support
as
prop), spread their rest props, and forward their refs. -
#1346: The build now targets
es2020
instead ofes2018
. As a result, you might need to update some of your build tools (e.g. babel).
-
#1302: The dependencies on
@itwin/itwinui-css
and@itwin/itwinui-variables
have been removed. This means@itwin/itwinui-react
will bring its own stylesheet. - #1331, #1506: The dependency on tippy.js has been removed in favor of floating ui. While the basic usage is unchanged, all advanced props from tippy are no longer available. Components affected: Tooltip, Select, ComboBox, DropdownMenu, DropdownButton, SplitButton.
-
#1514: The dependency on
@types/react-table
has been removed. See:Table
section.
-
#1265: Removed the deprecated
useTheme
hook.<ThemeProvider>
is now always required to be wrapped around every tree within which iTwinUI components are used.+ <ThemeProvider> <App /> + </ThemeProvider>
Note: This doesn't mean that you need to wrap every single component. The important thing is that there is always a
ThemeProvider
available at some point when you traverse up the tree from an iTwinUI component. If not found, an error will be thrown. The easiest way to do this is by adding aThemeProvider
in your top-level entrypoint. -
#1478:
ThemeProvider
now defaults thetheme
value to"inherit"
(previously"light"
), while still using"light"
as fallback if there is no parent theme found. Also the inherit behavior has been made more resilient for cases where react context fails.
-
#1322: All CSS imports within components have been removed.
- For packages: No change required! Styles will be handled manually by applications or automatically by fallback logic within iTwinUI.
-
For applications:
@itwin/itwinui-react/styles.css
should now be manually imported at the entrypoint.If your application is still using v2, it may not be possible without npm aliases. In such a case, iTwinUI will fall back to using a dynamic import to automatically import missing CSS. However, for best experience and more robustness, we recommend that applications migrate to v3 and continue to manually import+ import '@itwin/itwinui-react/styles.css';
styles.css
.
-
#1302: All elements have had their class names changed to prevent conflict with older versions. These classes are considered a private implementation detail, so if you were relying on them in your code, it is strongly recommended to instead use your own classes or data attributes. Most iTwinUI components support passing a custom
className
prop.- .iui-button { + .my-button { /* ... */ }
<Button onClick={() => {}} + className='my-button' >
If you find a component where it is not possible to add a custom class, then please open an issue.
-
#1298:
Props
types will no longer be exported for any component. UseReact.ComponentProps
orReact.ComponentPropsWithoutRef
instead. In most cases, it is also useful to manually omit theas
prop because it relies on generics.import { Avatar, - type AvatarProps, } from '@itwin/itwinui-react'; + type AvatarProps = Omit<React.ComponentPropsWithoutRef<typeof Avatar>, 'as'>;
-
#1433: Updated package
exports
to prevent importing internal utilities.
-
#1461: The behavior of disabled buttons has been changed to make them focusable and use
aria-disabled
instead ofdisabled
attribute. While this is technically a breaking change, it shouldn't affect most uses. If you run into any issues, you can restore the old behavior using the newhtmlDisabled
prop. -
#1435: SplitButton:
className
is now passed to the button instead of the component wrapper. UsewrapperProps
if the old behavior is desired.
-
#1406: Removed
setFocus
prop. Checkbox can be focused by usingautoFocus
orref
. -
#1371:
className
andstyle
will now always be applied on the checkbox input element (instead of conditionally being applied on the wrapper in some cases). If checkbox is used withoutlabel
, then no changes should be needed. Iflabel
is used, then passclassName
andstyle
towrapperProps
.<Checkbox label='Checkbox label' - className={wrapperClassname} - style={wrapperStyle} + wrapperProps={{ className: wrapperClassName, style: wrapperStyle }} />
-
#1406: Removed
setFocus
prop. ColorPicker can be automatically focused by using it withinPopover
.
-
#1406: Removed
setFocus
prop. ComboBox can be focused by usinginputProps.autoFocus
orinputProps.ref
.
-
#1269: All dialog variants have
flex
applied by default. This means the content should be wrapped withDialog.Content
orModalContent
for optimal layout.<Modal> - my content + <ModalContent>my content</ModalContent> </Modal>
-
#1300:
modalRootId
andownerDocument
props have been removed fromModal
, in favor of the newportal
prop (also available inDialog
). This new prop can accept any HTMLElement, with no opinion on how it gets created.- <Modal modalRootId='my-custom-root'> + <Modal portal={{ to: myCustomRootElement }}>
-
#1565: Removed
Menu
component in favor ofDropdownMenu
.
-
#1400: The deprecated
ErrorPage
component will now dynamically import illustrations (previously it was statically importing the entire illustrations package, bloating the bundle). No required API changes.
-
#1406: Removed
setFocus
prop. Input can be focused by usingautoFocus
orref
.
-
#1544:
iconDisplayStyle
has been removed.svgIcon
is now always displayed inline and doesn't support buttons.- For icons below input, use
<StatusMessage>
. For inline buttons, use<InputWithDecorations>
.
- For icons below input, use
-
#1406: Removed
setFocus
prop. LabeledInput can be focused by usingautoFocus
orref
. -
#1355: Removed
inputStyle
andinputClassName
props; style and className props are being passed down to input. AddedwrapperProps
,labelProps
,messageProps
,messageIconProps
,inputWrapperProps
to pass props to sub elements.
-
#1355:
iconDisplayStyle
has been removed.svgIcon
is now always displayed inline and doesn't support buttons. -
#1406: Removed
setFocus
prop. LabeledTextarea can be focused by usingautoFocus
orref
. -
#1355: Removed
textareaStyle
andtextareaClassName
props; style and className props are being passed down to textarea. AddedwrapperProps
,labelProps
,messageProps
,messageIconProps
to pass props to sub elements.
-
#1355: Removed
selectStyle
andselectClassName
props; style and className props are being passed down to textarea. AddedwrapperProps
,labelProps
,messageProps
,messageIconProps
to pass props to sub elements.
-
#1406: Removed
setFocus
prop. Radio can be focused by usingautoFocus
orref
. -
#1409:
RadioTile
'sclassName
andstyle
props will now always be applied on the<input>
element instead of conditionally being applied on the wrapper when label is passed. AddedwrapperProps
,iconProps
,labelProps
,subLabelProps
to individually customize each part of the component.<Radio label = 'Radio label' - className={wrapperClassname} - style={wrapperStyle} + wrapperProps={{ className: wrapperClassName, style: wrapperStyle }} />
-
#1406: Removed
setFocus
prop. RadioTile can be focused by usingautoFocus
orref
.
-
#1406: Removed
setFocus
prop. Select can be focused by usingtriggerProps.ref
.
-
#1458: Top-level props (className, style, etc) now passed to the main inner div instead of to the wrapper. Use
wrapperProps
to restore old behavior.
-
#1406: Removed
setFocus
prop. Slider can be focused by usingthumbProps.ref
.
-
#1406: Removed
setFocus
prop. Textarea can be focused by usingautoFocus
orref
.
-
#1527: Tile's
leftIcon
andrightIcon
props no longer setsize
for the buttons so it must be done manually.<Tile // ... - leftIcon={<IconButton styleType='borderless'>...</IconButton>} + leftIcon={<IconButton styleType='borderless' size='small'>...</IconButton>} - rightIcon={<IconButton styleType='borderless'>...</IconButton>} + rightIcon={<IconButton styleType='borderless' size='small'>...</IconButton>} />
-
#1351:
toaster
import has been removed and replaced withuseToaster
which returns a toaster object with the same public methods as before.- import { toaster } from '@itwin/itwinui-react'; + import { useToaster } from '@itwin/itwinui-react'; export default () => { + const toaster = useToaster(); return <button onClick={() => toaster.positive('hello')}>show</button> };
-
#1406: Removed
setFocus
prop. ToggleSwitch can be focused by usingautoFocus
orref
.
-
#1331: Migrated Tooltip from tippy.js to floating-ui. While the basic component usage is unchanged, all advanced props that were inherited from tippy.js have been removed. New props available:
autoUpdateOptions
,middleware
andportal
. See new docs.- The
portal
prop replaces the oldappendTo
prop. You can pass anHTMLElement
toportal.to
. - The
reference
prop now accepts a statefulHTMLElement
value, instead of a ref object. -
Note: Since floating-ui uses
ResizeObserver
, you might need to add a mock in your tests.
- The
-
#1296: Removed previously-deprecated typography components (
Body
,Headline
,Leading
,Small
,Subheading
,Title
) which have been replaced byText
.
-
#1514: Removed dependency on
@types/react-table
and instead exposed a package endpoint/react-table
for allreact-table
types. Our types are specifically tailored to the users of our Table and thus offer better type support.import { Table } from '@itwin/itwinui-react'; - import { Column, TableState } from 'react-table'; + import { Column, TableState } from '@itwin/itwinui-react/react-table';
-
#1570: We made changes to help raise type errors that might have been previously hidden. Thus, you might have to use
satisfies
when passing props to<Table>
to make sure all your types are correct.- const data = [...] + const data = [...] satisfies MyRowDataType[]
-
#1388: Removed previously-deprecated
HorizontalTabs
andVerticalTabs
. Instead useTabs
withorientation
prop. -
#1548: Tabs are now always scrollable. The
overflowOptions
prop is now a no-op.
-
#1383: Removed previously-deprecated
UserIcon
andUserIconGroup
components (replaced withAvatar
andAvatarGroup
respectively). Also removeduserIcon
prop fromHeader
(now part ofactions
prop).
-
#1384: Removed previously-deprecated
Wizard
component. UseStepper
for interactive wizards, or useWorkflowDiagram
for displaying non-interactive flowcharts.
-
#1278: Adjusted calculations in ButtonGroup's
overflowButton
callback, so that it respectsoverflowPlacement
and considers the presence of the overflowButton itself.
-
#1356: ProgressRadial has been refactored to be a single
<div>
instead of using a nested svg. Also it is recommended to explicitly setsize
when using in other components. For instance,<ProgressRadial />
inTable
'sDefaultCell.endIcon
prop (example diff), or if you were previously relying on some iTwinUI component to automatically set the progress indicator to small size, you must now use<ProgressRadial size='small'>
.
-
#1354: The value of the
isExpanded
prop will now be used as the source of truth for all renders (i.e. "controlled" mode), rather than only for the initial render. If you were previously relying on this prop to specify the initial state, you must now maintain your own state (alongside theonToggle
prop).
-
#1477: Added a new
portalContainer
prop toThemeProvider
. When specified, all floating elements (tooltips, toats, dialogs) under the ThemeProvider will read this prop from context and portal into it. -
#1506: Added new
Popover
component for public use. -
#1328: Added new
Overlay
component with customizable subcomponents:Overlay.Wrapper
,Overlay.HiddenContent
,Overlay.Overlay
-
#1073: Added new
TransferList
component which is used to move one or more items between lists. -
#1457: Added
htmlName
prop to theHeaderButton
subcomponent which handles the nativename
attribute in<button>
. -
#1419: Added
htmlSize
prop to theInput
component which handles the nativesize
attribute in<input>
. -
#1247: Added alternative subcomponent API to
Alert
. -
#1369: Added alternative subcomponent API to
Breadcrumbs
. -
#1354: Added alternative subcomponent API to
ExpandableBlock
. -
#1255: Added alternative subcomponent API to
Tile
. -
#1548: Added alternative subcomponent API to
Tabs
. -
#1355: Added
InputGrid
andInputWithDecorations
components. -
#1355: Added
padded
prop to Icon to render icons with padding. -
#1355: Added
StatusMessage
component (previously used under LabeledInput, LabeledSelect, etc(. -
#1355: Added
status
prop to Input, Textarea and Select. -
#1403: Accept additional type of
JSX.Element[]
andJSX.Element
formenuItems
prop inDropdownMenu
.
-
#1557: Directly passing
<a>
/<Button>
/<span>
as children is deprecated. Should be replaced withBreadcrumbs.Item
subcomponent.
-
#1295: Deprecated
icon
andbadge
props in favor of newstartIcon
andendIcon
props. Also affects Select and ComboBox options.
-
#1330: Deprecated
FileUploadTemplate
. Should be replaced withFileUploadCard
.
-
#1548: Deprecated
overflowOptions
prop inTabs
. It is now a no-op, as tabs will overflow by default.