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.
Container — safeAreaEdges + 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)
useUI → useTheme
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
| Before | After |
|---|---|
MultinaireDesignProvider | MultinaireUI |
MultinaireDesignProps | MultinaireUIProps |
Hooks
| Before | After |
|---|---|
useMultinaireTheme | useTheme |
useMultinaireThemeMode | useThemeMode |
useMultinaireLocalization | useLocalization |
useMultinaireModal | usePopup |
useMultinaireKeyboard | useKeyboard |
useMultinaireResponsiveDesign | useResponsiveDesign |
useMultinaireLoadingAnimation | useAnimate |
Icons
| Before | After |
|---|---|
MultinaireIcons | Icons |
Components with intent-based renames
| Before | After |
|---|---|
MultinaireText | Typography |
MultinaireImage | Photo |
MultinaireLoading | Animate |
MultinaireScrollView | ScrollContainer |
MultinaireSwitch | Toggle |
MultinaireModal | Popup |
MultinaireModalHeader | PopupHeader |
MultinaireModalToggleButton | PopupToggleButton |
MultinaireKeyboardAvoidingView | KeyboardAvoidingContainer |
MultinaireListView | ListContainer |
MultinairePageView | PageContainer |
MultinaireTabView | TabContainer |
Components — prefix-only strip
| Before | After |
|---|---|
MultinaireContainer | Container |
MultinaireCard | Card |
MultinaireBadge | Badge |
MultinaireDivider | Divider |
MultinaireGap | Gap |
MultinaireIcon | Icon |
MultinairePositioned | Positioned |
MultinaireAvatar | Avatar |
MultinaireMessage | Message |
MultinaireButton | Button |
MultinaireIconButton | IconButton |
MultinaireActionButton | ActionButton |
MultinaireMenuButton | MenuButton |
MultinaireSocialLoginButton | SocialLoginButton |
MultinaireFloatingActionButton | FloatingActionButton |
MultinaireInput | Input |
MultinairePickerButton | PickerButton |
MultinaireMediaPickerButton | MediaPickerButton |
MultinaireCheckbox | Checkbox |
MultinairePagination | Pagination |
MultinairePage | Page |
MultinaireTopTab | TopTab |
MultinaireBottomTab | BottomTab |
MultinaireListPicker | ListPicker |
MultinaireListPickerItem | ListPickerItem |
MultinaireDateTimePicker | DateTimePicker |
MultinaireDialog | Dialog |
MultinaireMenu | Menu |
MultinaireStackHeader | StackHeader |
MultinaireTabBar | TabBar |
MultinaireTabHeader | TabHeader |
MultinaireSideBar | SideBar |
Prop types — drop the Multinaire prefix and are renamed to match their component names exactly:
| Old | New |
|---|---|
TextProps | TypographyProps |
ImageProps | PhotoProps |
SwitchProps | ToggleProps |
KeyboardAvoidingViewProps | KeyboardAvoidingContainerProps |
ScrollViewProps | ScrollContainerProps |
ListViewProps | ListContainerProps |
TabViewProps | TabContainerProps |
PageViewProps | PageContainerProps |
ListPickerItem | ListPickerItemData |
DatePickerProps | DateTimePickerProps |
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"]
}