Skip to main content

Migration Guide

Migrating to 1.0.4 (from 1.0.3)

AnimatedTouchableOpacity renamed to AnimatedPressable

All interactive components moved from TouchableOpacity to Pressable to enable hover support on web/desktop. The exported AnimatedTouchableOpacity component was renamed accordingly. If you imported it directly, update the name:

// Before
import { AnimatedTouchableOpacity } from '@multinaire/ui';

<AnimatedTouchableOpacity activeOpacity={0.8} onPress={onPress} />;

// After
import { AnimatedPressable } from '@multinaire/ui';

<AnimatedPressable onPress={onPress} />;

AnimatedPressable is an Animated-wrapped Pressable, so the activeOpacity prop no longer applies. For the same hover/press opacity feedback the built-in components use, combine it with the new usePressableInteraction hook:

import { AnimatedPressable, usePressableInteraction } from '@multinaire/ui';

function MyButton({ onPress }) {
const { animatedStyle, overrideProps } = usePressableInteraction();

return (
<AnimatedPressable style={animatedStyle} onPress={onPress} {...overrideProps} />
);
}

Migrating to 1.0.3 (from 1.0.2)

useScreenOptions — deprecated properties removed

The stack, stackWithOverrides, topTab, topTabWithOverrides, bottomTab, bottomTabWithOverrides, sideBar, and sideBarWithOverrides properties have been removed. If you haven't already migrated away from them, update your navigators now:

// Before (removed)
const { stack, bottomTab, topTabWithOverrides } = useScreenOptions();

<Stack screenOptions={stack} />
<Tabs screenOptions={bottomTab} />
<Tabs screenOptions={topTabWithOverrides({ lazy: false })} />

// After
const { screenOptions } = useScreenOptions('stack');
const { screenOptions: tabOptions } = useScreenOptions('bottom-tab');
const { screenOptions: topOptions } = useScreenOptions('top-tab');

<Stack screenOptions={screenOptions()} />
<Tabs screenOptions={tabOptions()} />
<Tabs screenOptions={topOptions({ lazy: false })} />

Localization — 'system' renamed to 'auto'

The 'system' value for defaultLanguage has been replaced with 'auto'. If you passed defaultLanguage="system" explicitly, rename it:

// Before
<MultinaireUI defaultLanguage="system" translations={...}>

// After
<MultinaireUI defaultLanguage="auto" translations={...}>

'auto' is still the default, so no change is needed if you relied on the default behaviour.

The language and changeLanguage types in LocalizationContext and useLocalization no longer include 'system'. The languages array returned by useLocalization now contains only concrete locale codes — remove any 'system' entry handling in language pickers:

// Before — filtering out 'system' before rendering
const { languages } = useLocalization();
const displayLanguages = languages.filter(l => l !== 'system');

// After — languages only contains locale codes, no filtering needed
const { languages } = useLocalization();

Migrating to 1.0.2 (from 1.0.1)

Toggle default color

The color prop default changed from 'primary' to 'success'. If you relied on the old default, pass color="primary" explicitly:

// Before (implicit primary)
<Toggle value={isEnabled} onChange={setIsEnabled} />

// After — add color prop to keep the old appearance
<Toggle value={isEnabled} color="primary" onChange={setIsEnabled} />

useScreenOptions — new API

useScreenOptions now accepts a navigator type and returns a screenOptions function together with title(), tabBarLabel(), and tabBarIcon() helpers. The old property-based API still works but is deprecated and will be removed in a future minor version.

// Before (deprecated)
const { stack, topTab, bottomTabWithOverrides } = useScreenOptions();

<Stack screenOptions={stack} />
<Tabs screenOptions={topTab} />
<Tabs screenOptions={bottomTabWithOverrides({ tabBarActiveTintColor: 'red' })} />

// After
const { screenOptions } = useScreenOptions('stack');
const { screenOptions: tabOptions } = useScreenOptions('top-tab');
const { screenOptions: bottomOptions } = useScreenOptions('bottom-tab');

<Stack screenOptions={screenOptions()} />
<Tabs screenOptions={tabOptions()} />
<Tabs screenOptions={bottomOptions({ tabBarActiveTintColor: 'red' })} />

The title(), tabBarLabel(), and tabBarIcon() helpers make screen options fully type-safe when TranslationSchema is augmented:

const { screenOptions, title, tabBarIcon } = useScreenOptions('bottom-tab');

<Tabs.Screen
name="home"
options={{
...screenOptions(),
title: title('home'), // type-checked against TranslationSchema
tabBarIcon: tabBarIcon('Home'),
}}
/>

createTabSceenOptions renamed

The internal export createTabSceenOptions (typo) has been renamed to createTabScreenOptions. Update any direct imports:

// Before
import { createTabSceenOptions } from '@multinaire/ui';

// After
import { createTabScreenOptions } from '@multinaire/ui';

Type-safe i18n with TranslationSchema (opt-in)

String props across all components now accept TranslationKey. To unlock compile-time key checking, augment the TranslationSchema interface once in your project:

// i18n.d.ts (in your app root)
import en from '@/assets/translations/en.json';
import fr from '@/assets/translations/fr.json';

declare module '@multinaire/ui' {
interface TranslationSchema {
en: typeof en;
fr: typeof fr;
}
}

After this, passing an unknown string to any component title, placeholder, or errorText prop will produce a TypeScript error. This is entirely opt-in — without the augmentation all string props accept string as before.

ContainersafeAreaEdges + onPress are mutually exclusive

Combining both props now throws a runtime error. Wrap the SafeAreaView in a separate pressable instead:

// Before (silently broken layout)
<Container safeAreaEdges={['top']} onPress={handlePress}>
{children}
</Container>

// After
<Container safeAreaEdges={['top']}>
<Container onPress={handlePress}>
{children}
</Container>
</Container>

Migrating to 1.0.1 (from 1.0.0)

useUIuseTheme

The hook was shipped under the wrong name in 1.0.0. Replace every usage:

// Before
const { colors, variables, fonts } = useUI();

// After
const { colors, variables, fonts } = useTheme();

Migrating to 1.0.0 (from 0.3.x)

This is a breaking change release. The package has been renamed and all Multinaire prefixes have been stripped from the public API.

1. Update the package name

# Remove old package
npm uninstall @multinaire/multinaire-design

# Install new package
npm install @multinaire/ui

2. Update all imports

Replace every import from @multinaire/multinaire-design with @multinaire/ui:

// Before
import MultinaireDesignProvider, {
useMultinaireTheme,
useMultinaireLocalization,
MultinaireButton,
MultinaireText,
} from '@multinaire/multinaire-design';

// After
import MultinaireUI, {
useTheme,
useLocalization,
Button,
Typography,
} from '@multinaire/ui';

3. Rename every symbol

Use the tables below as a find-and-replace reference.

Root provider

BeforeAfter
MultinaireDesignProviderMultinaireUI
MultinaireDesignPropsMultinaireUIProps

Hooks

BeforeAfter
useMultinaireThemeuseTheme
useMultinaireThemeModeuseThemeMode
useMultinaireLocalizationuseLocalization
useMultinaireModalusePopup
useMultinaireKeyboarduseKeyboard
useMultinaireResponsiveDesignuseResponsiveDesign
useMultinaireLoadingAnimationuseAnimate

Icons

BeforeAfter
MultinaireIconsIcons

Components with intent-based renames

BeforeAfter
MultinaireTextTypography
MultinaireImagePhoto
MultinaireLoadingAnimate
MultinaireScrollViewScrollContainer
MultinaireSwitchToggle
MultinaireModalPopup
MultinaireModalHeaderPopupHeader
MultinaireModalToggleButtonPopupToggleButton
MultinaireKeyboardAvoidingViewKeyboardAvoidingContainer
MultinaireListViewListContainer
MultinairePageViewPageContainer
MultinaireTabViewTabContainer

Components — prefix-only strip

BeforeAfter
MultinaireContainerContainer
MultinaireCardCard
MultinaireBadgeBadge
MultinaireDividerDivider
MultinaireGapGap
MultinaireIconIcon
MultinairePositionedPositioned
MultinaireAvatarAvatar
MultinaireMessageMessage
MultinaireButtonButton
MultinaireIconButtonIconButton
MultinaireActionButtonActionButton
MultinaireMenuButtonMenuButton
MultinaireSocialLoginButtonSocialLoginButton
MultinaireFloatingActionButtonFloatingActionButton
MultinaireInputInput
MultinairePickerButtonPickerButton
MultinaireMediaPickerButtonMediaPickerButton
MultinaireCheckboxCheckbox
MultinairePaginationPagination
MultinairePagePage
MultinaireTopTabTopTab
MultinaireBottomTabBottomTab
MultinaireListPickerListPicker
MultinaireListPickerItemListPickerItem
MultinaireDateTimePickerDateTimePicker
MultinaireDialogDialog
MultinaireMenuMenu
MultinaireStackHeaderStackHeader
MultinaireTabBarTabBar
MultinaireTabHeaderTabHeader
MultinaireSideBarSideBar

Prop types — drop the Multinaire prefix and are renamed to match their component names exactly:

OldNew
TextPropsTypographyProps
ImagePropsPhotoProps
SwitchPropsToggleProps
KeyboardAvoidingViewPropsKeyboardAvoidingContainerProps
ScrollViewPropsScrollContainerProps
ListViewPropsListContainerProps
TabViewPropsTabContainerProps
PageViewPropsPageContainerProps
ListPickerItemListPickerItemData
DatePickerPropsDateTimePickerProps

Removed props

MenuButton.type ('default' | 'warning' | 'error') has been removed — foreground color is now always onBackground:

// Before
<MenuButton type="error" leading="Logout" title="Sign Out" onPress={signOut} />

// After
<MenuButton leading="Logout" title="Sign Out" onPress={signOut} />

ButtonType.destructive has been removed — use 'error' instead:

// Before
<Button type="destructive" title="Delete" />

// After
<Button type="error" title="Delete" />

4. Update tsconfig paths (if using the example app pattern)

// Before
"paths": {
"@multinaire/multinaire-design": ["../build/index"]
}

// After
"paths": {
"@multinaire/ui": ["../build/index"]
}