Welcome UI V5 focuses on the rework of our foundations and moving from reakit to ariakit (reakit v2).
Upgrade steps
1. Update your dependencies
Make sure you update all @welcome-ui
packages and styled-components
packages:
{"dependencies": {"@welcome-ui/YOUR_PACKAGE": "^5.0.0","@xstyled/styled-components": "^3.7.3","react": "^18.0.0","styled-components": "^5.3.9"}}
2. Migrate foundations
We reworked our theme's colors, spacing, typography, and many other properties. Use the migration script to migrate easily to V5 on a welcome-ui project.
yarn migrate "../yourProject/src/**/**.**(tsx|ts|js)"
3. Migrate Reakit to Ariakit
We also migrated to the new Ariakit library (reakit v2) on some of our components. To migrate easily, you can find components migration below.
To resume:
- We now pass on a
store
property the component's state and remove "State" from the hook name.
- const drawerState = useDrawerState()+ const drawer = useDrawer()- <Drawer {...useDrawerState}>+ <Drawer store={drawer}>
visible
is now replaced by theopen
property- To force open a component, use now the
defaultOpen
property
- const drawerState = useDrawerState({ open: true })+ const drawer = useDrawer({ defaultOpen: true })
- Access the actual component's state with
useState
:
- const drawerState = useDrawerState()- const isOpen = drawerState.visible+ const drawer = useDrawer()+ const isOpen = drawer.useState('open')
Theme
Colors
We changed our colors dark and light to be fully compatible with the coming dark mode (in beta). Now dark are black rgba with transparency, and light white rgba with transparency.
We also had to rework our colors naming for typescript compatibility reasons:
- Before:
colors.dark.900
- After:
colors['dark-900']
We rework some colors:
- v4 compare to v5
- [success/danger/warning/info].500 <-> [success/danger/warning/info]-300
- [success/danger/warning/info].700 <-> [success/danger/warning/info]-400
- new color [success/danger/warning/info]-500
- nude.400 <-> nude-500
- nude.500 <-> nude-400
- nude.700 <-> nude-600
- nude.800 <-> nude-700
- ** the light colors are all white with opacity, you need to replace the old light color for text with new black color **
- light.800 <-> dark-100
- light.700 <-> dark-200
- light.500 <-> dark-400
- light.200 <-> dark-400
- light.100 <-> dark-500
- now the light colors variants are 100, 200, 400, 500, 700, 900(without opacity)
- ** the dark colors are all black with opacity, it's also used for text color **
- dark.100 <-> dark-500
- dark.200 <-> dark-700
- dark.500 <-> dark.900
- dark.700 <-> dark.900
- dark.800 <-> dark.900
- now the dark colors variants are 100, 200, 400, 500, 700, 900(without opacity)
- new color white (get the light.900 for dark mode)
- new color black (get the dark.900 for dark mode)
- the color for html is now dark-500
Spacing
We rework our spacing:
- v5 compare to v4
- xxs (2px) <-> new size (before it was 6px)
- xs (4px) <-> new size (before it was 8px)
- sm (8px) <-> xs
- md (12px) <-> same size
- lg (16px) <-> lg (15px)
- xl (24px) <-> xxl
- xxl (32px) <-> 3xl (30px)
- 3xl (48px) <-> 5xl (50px)
- 4xl (64px) <-> 6xl
- 5xl (96px) -> new size
- 6xl (128px) -> new size
- 7xl (192px) -> new size
Typography
We change the name of variants to xs
s
m
lg
and remove useless variants.
- meta1 and meta2 has been removed and replaced by
sm
andxs
- body1 become
lg
- body2 become
md
- body3 become
sm
- body4 become
xs
- subtitle1 become
subtitle-md
- subtitle2 become
subtitle-sm
Components
Accordion
We migrated to Ariakit and added an useAccordion
hook to play with the component's store.
+ const accordion = useAccordion()- <Accordion title="accordion">+ <Accordion store={accordion} title="accordion">= ...= </Accordion>
Alert / Toast / Growl
-
All components
- We have adjusted colors and spacing.
- Position
top
has been replaced withtop-center
and positionbottom
has been replaced withbottom-center
. - We removed the property
closeButtonDataTestId
. Now we add-close-button
after yourdataTestId
property.
-
Alert
- The props
icon
is now given to the Alert component and not to Alert.Title. - You must use the
cta
prop instead of pass the Alert.Button as a Children - You must use the
isFullWidth
prop to have an alert with a 100% max width
- The props
-
Toast
- In order to use
Toast
component, you must add theNotifications
component in your project root. - The
useToast
hook is deprecated. Instead, you can directly usetoast
function. - The props
icon
is now given to Toast.Growl / Toast.Snackbar component and not to Toast.Title.
- In order to use
Badges
- rework
Badge
component now rounded
Buttons
- We have adjusted colors and spacing.
- The
xl
size has been removed. - The
ternary-negative
has been removed. - The
quaternary
variant is now namedghost
. - The icon size now adjusts to the size of the button.
Drawer
We migrated to Ariakit. We now pass the component's state from useDrawer
to the store
property:
- const drawerState = useDrawerState()+ const drawer = useDrawer()- <Drawer {...drawerState}>+ <Drawer store={drawer}>= ...= </Drawer>
We replace props by:
hideOnClickOutside
becomehideOnInteractOutside
<Drawer.Backdrop>
is removed and replace by a propertywithBackdrop
. You can personalize your backdrop with thebackdrop
property.
DropdownMenu
We migrated to Ariakit. Now we pass the component's state from useDropdownMenu
to the store
property:
- const dropdownMenuState = useDropdownMenuState()+ const dropdownMenu = useDropdownMenu()- <DropdownMenu.Trigger {...dropdownMenuState}>+ <DropdownMenu.Trigger store{dropdownMenu}>= ...= </DropdownMenu.Trigger>- <DropdownMenu {...dropdownMenuState}>+ <DropdownMenu store={dropdownMenu}>- <DropdownMenu.Item {...dropdownMenuState}>+ <DropdownMenu.Item store={dropdownMenu}>= ...= </DropdownMenu.Item>= ...= </DropdownMenu>
If you want to not close DropdownMenu item on click please add a hideOnClose={false}
on DropdownMenu.Item
:
<DropdownMenu.Item hideOnClose={false} store={dropdownMenu}>...</DropdownMenu.Item>
EmojiPicker
We migrated to Ariakit. Now we pass the component's state from useEmojiPicker
on the store
property:
- const emojiPickerState = useEmojiPicker()+ const emojiPicker = useEmojiPicker()- <EmojiPicker.Trigger {...emojiPickerState}>+ <EmojiPicker.Trigger store{useEmojiPicker}>= ...= </EmojiPicker.Trigger>- <EmojiPicker.Trigger {...emojiPickerState} />+ <EmojiPicker.Trigger store={useEmojiPicker} />
and defaultTabState
becomes defaultTabStore
FileDrop
accept
property changed on v14 of react-dropzone:
- Before:
accept: "image/*"
- After:
accept: { "image/*": [] }
See more about showOpenFilePicker and media type.
Icons
We rework our icon size:
- v5 compare to v4
- This size has been removed <-> xxs (7px)
- xs (12px) <-> xs (10px)
- sm (16px) <-> sm (12px)
- md (24px) <-> md (15px)
- lg (32px) <-> lg (20px)
- xl (48px) <-> xl (27.574px)
- xxl (64px) <-> new size
We remove all @welcome-ui/icons.*
packages (except icons.font). There is now two packages available:
- @welcome-ui/icons using svg
- @welcome-ui/icons.font using webfont
We renamed some icons:
<GetIcon>
become<DownloadIcon>
<EyeIcon>
become<ShowIcon>
<ThumbupIcon>
become<ThumbUpIcon>
<ThumbdownIcon>
become<ThumbDownIcon>
<FlagFillIcon>
become<FlagIcon>
<FlagIcon>
become<FlagOutlineIcon>
<ChevronIcon>
become<CodeIcon>
<DuplicateIcon>
become<CopyIcon>
<TagsIcon>
become<TagIcon>
<SalaryIcon>
become<EuroCurrencyIcon>
- new
<SalaryIcon>
icon
Link
- the
isExternalLink
becomeisExternal
Modal
- We have adjusted colors and spacing.
- Modal.Title is now named Modal.Header and has props
title
(mandatory) andsubtitle
(optional). - To ensure good spacing between modal's sub-components, they must be wrapped with Modal.Content.
- Modal.Body is now the content box for Modal.
- Modal.Cover has been removed.
- We migrated to Ariakit and added an
useModal
hook to play with the component store.
- const modalState = useModalState()+ const modal = useModal()- <Modal {...modalState}>- <Modal.Content>...- </Modal.Content>+ <Modal store={modal}>+ <Modal.Content store={modal}>+ <Modal.Body>...+ </Modal.Body>+ </Modal.Content>= ...= </Modal>
Popover
- We migrated to Ariakit and added a
usePopover
hook to play with the component store.
- const popoverState = usePopoverState()+ const popover = usePopover()- <Popover.Trigger {...popoverState}>+ <Popover.Trigger store={popover}>= ...= </Popover.Trigger>- <Popover {...popoverState}>+ <Popover store={popover}>= ...= </Popover>
RadioGroup
We removed the check icon on radio input and changed the style of it. We also reworked accessibility.
Tabs
We migrated to Ariakit. Now we pass the component state from useTab
on the store
property:
- const tabState = useTabState()+ const tab = useTab()- <Tab.List {...tabState}>+ <Tab.List store={tab}>- <Tab {...tabState}>+ <Tab store={tab}>= ...= </Tab>= </Tab.List>- <Tab.Panel {...tabState}>+ <Tab.Panel store={tab}>= ...= </Tab.Panel>
and selectedId
become defaultSelectedId
Tag
- We have adjusted colors and spacing.
- The
lg
size has been removed. - The
shape
prop has been removed. - The icon size now adjusts to the size of the tag.
Tooltip
We added a div around the Children of the tooltip when the children has a disabled prop otherwise the tooltip does not trigger. We removed popper.js and only use Ariakit for fixed or not fixed tooltip.
Swiper
We rework the swiper component:
<Swiper.Slide>
has been removed, you can embed and style your slides as you wantslidesToShow
option becomeslidesPerView
and now takes an object to define the number of slides per device{ mobile: 1, tablet: 1, desktop: 1 }
renderPaginationItem
,nextButton
,prevButton
andslidesToSwipe
options have been removed
Now we pass the component state from useSwiper
on the store
property:
- const state = useSwiperState()+ const swiper = useSwiper()- <Swiper state={state}>+ <Swiper store={swiper}>= ...= </Swiper>