Skip to main content

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.0.4] - 2026-06-02

Added

  • Hover & press interaction states on all interactive components — Button, ActionButton, IconButton, MenuButton, SocialLoginButton, FloatingActionButton, Card, Container (when onPress is set), Checkbox, and InputWrapper now animate their opacity on hover (web/desktop) and press, with a smooth 150ms timing transition. The animation is automatically disabled while a button is loading or has no onPress handler.
  • usePressableInteraction hook exported from @multinaire/ui — returns an animatedStyle and a set of overrideProps (onHoverIn, onHoverOut, onPressIn, onPressOut) you can spread onto any Pressable to add the same hover/press opacity feedback used by the built-in components.
  • useButtonStyles hook is now exported from @multinaire/ui (previously an internal button helper) — resolves the background, foreground, and disabled styles for a given button type.

Changed

  • All interactive components migrated from TouchableOpacity to Pressable — this enables hover support on web/desktop and aligns with the React Native recommended interaction primitive. The previous activeOpacity feedback is replaced by the new usePressableInteraction animation.
  • AnimatedTouchableOpacity export renamed to AnimatedPressable — an Animated-wrapped Pressable. Update any imports of AnimatedTouchableOpacity to AnimatedPressable. See the migration guide.
  • Minimum Node version raised to >=22 (was >=18).

Fixed

  • Popup safe-area insets on Android — popup content is now wrapped in a SafeAreaProvider with explicit initial metrics so the safe-area insets resolve correctly inside the Modal's Android window.
  • Popup open delay removed — the child content no longer waits on a 50ms setTimeout before rendering, so popups open immediately.
  • ListPicker layout on Android — now renders using the dialog layout on Android (previously only when the popup type was dialog), preventing clipped sheet content.

[1.0.3] - 2026-05-20

Added

  • testID auto-detection on Typography — when children is a string, the component automatically sets testID to that string value so text elements are addressable in tests without extra configuration.
  • testID fallback to placeholder on Input, PickerButton, and MediaPickerButton — when no explicit testID is provided, the placeholder value is used as the test identifier.
  • Built-in testID on InputWrapper clear button — always "clear-input".
  • Built-in testID markers on Pagination — the animated label receives the current item value as its testID; the focused step container receives "<item>-is-focused".
  • Built-in testID markers on DateTimePicker navigation buttons — previous icon is "previous", next icon is "next".

Changed

  • LocalizationProvider.defaultLanguage — the 'system' option is renamed to 'auto'. Update any explicit defaultLanguage="system" to defaultLanguage="auto".
  • LocalizationContext.language — type narrowed from 'system' | Language to Language; the active locale is always a concrete code.
  • LocalizationContext.languages — type narrowed from ('system' | Language)[] to Language[]; the array no longer includes 'system' as a first entry.
  • LocalizationContext.changeLanguage — parameter type narrowed from 'system' | Language to Language.

Fixed

  • StackHeader top safe area — simplified the safe-area condition: the inset is now skipped only when the parent navigator is a tab or drawer. The grandparent-stack detection introduced in 1.0.2 has been removed.

Removed

  • useScreenOptions deprecated propertiesstack, stackWithOverrides, topTab, topTabWithOverrides, bottomTab, bottomTabWithOverrides, sideBar, sideBarWithOverrides have been removed (deprecated in 1.0.2). Use useScreenOptions(type).screenOptions instead.

[1.0.2] - 2026-05-09

Added

  • testID prop on all interactive components — Button, ActionButton, IconButton, MenuButton, SocialLoginButton, FloatingActionButton, BottomTabButton, SideBarButton, TopTabButton, Container, Icon, Badge, Card, Input, InputWrapper, Checkbox, Toggle, PickerButton, MediaPickerButton, ListPickerItem. When a title is available the prop defaults to the title value so most components are automatically addressable without extra configuration.
  • Built-in testID markers on structural elements: Popup overlay ("modal-overlay"), PopupHeader close button ("modal-close"), StackHeader back button ("navigation-back"), StackHeader close button ("navigation-close").
  • defaultLanguage prop on MultinaireUI and LocalizationProvider — set the initial language. Pass 'system' (default) to auto-detect from the device locale via expo-localization, or a locale code (e.g. 'fr') to hard-code the startup language.
  • languages array in LocalizationContext — ordered list of all supported locales derived from the translations prop. Always starts with 'system' so you can offer an "Auto-detect" option in a language picker.
  • defaultThemeMode prop on MultinaireUI and ThemeProvider — set the initial theme mode ('system' | 'light' | 'dark'). Defaults to 'system'.
  • themeModes array in ThemeContext — always ['system', 'light', 'dark'].
  • TranslationSchema augmentation interface — declare your locale types once in a .d.ts file and get type-safe locale codes (Language) and translation keys (TranslationKey) across all components and hooks.
  • Language and TranslationKey types exported from @multinaire/ui.
  • backTitle prop on StackHeader — override the back-button label. Defaults to 'Back'.
  • closeTitle prop on StackHeader — override the modal close-button label. Defaults to 'Close'.
  • confirmTitle prop on DateTimePicker — override the confirm button label. Defaults to 'Confirm'.
  • previousTitle, nextTitle, doneTitle props on PageContainer — override the navigation button labels. Defaults are 'Previous', 'Next', 'Done'.
  • NavigatorType type ('stack' | 'top-tab' | 'bottom-tab' | 'side-bar') exported from @multinaire/ui.
  • useScreenOptions(type) now accepts a navigator type and returns a unified screenOptions function plus title(), tabBarLabel(), and tabBarIcon() helper functions for type-safe screen configuration.

Changed

  • Toggle default color changed from 'primary' to 'success'. Pass color="primary" explicitly to preserve the previous appearance.
  • String props that display user-facing text (button titles, input labels, placeholders, error messages, popup titles, etc.) are now typed as TranslationKey. When TranslationSchema is augmented this provides compile-time checking that only defined keys are passed. Without augmentation the type stays string.
  • TypographyProps.children is now typed as TranslationKey | Exclude<ReactNode, string>. String literals passed as children must be valid translation keys when TranslationSchema is in use.
  • useScreenOptions legacy return properties (stack, topTab, bottomTab, sideBar, and their *WithOverrides variants) are deprecated. They continue to work but will be removed in a future minor version. Migrate to useScreenOptions(type).screenOptions.

Fixed

  • Toggle internal state was updated even when onChange was not provided. State now only updates when a handler is present.
  • Tab bar icon color no longer falls back to 'transparent'; the color is correctly cast from the theme context.
  • Container with both safeAreaEdges and onPress now throws a descriptive runtime error — these two props are mutually exclusive.
  • StackHeader top safe area — stacks nested inside another user stack no longer double-apply the top safe area inset. The header now checks for a grandparent navigator to detect genuine nesting, covering the common Expo Router case.
  • StackHeader desktop title — when navigating back, the right-side container switched to a column layout but kept flex={1}, which prevented the title from rendering. The flex is now only applied when there is no back button (row layout).

Deprecated

  • useScreenOptions() return properties: stack, stackWithOverrides, topTab, topTabWithOverrides, bottomTab, bottomTabWithOverrides, sideBar, sideBarWithOverrides. Use useScreenOptions(type).screenOptions instead.
  • createTabSceenOptions (typo) renamed to createTabScreenOptions. The old name is no longer exported.

[1.0.1] - 2026-04-18

Changed

  • useUI renamed to useTheme — the hook was shipped under the wrong name in 1.0.0. Update every call site: const { colors, variables, fonts } = useTheme().

[1.0.0] - 2026-04-17

Breaking Changes

Package renamed: @multinaire/multinaire-design@multinaire/ui

All Multinaire prefixes removed from the public API. Update every import accordingly.

Provider / root entry point

BeforeAfter
MultinaireDesignProvider (default export)MultinaireUI (named + default export)
MultinaireDesignPropsMultinaireUIProps

Hooks

BeforeAfter
useMultinaireThemeuseTheme
useMultinaireThemeModeuseThemeMode
useMultinaireLocalizationuseLocalization
useMultinaireModalusePopup
useMultinaireKeyboarduseKeyboard
useMultinaireResponsiveDesignuseResponsiveDesign
useMultinaireLoadingAnimationuseAnimate

Icons

BeforeAfter
MultinaireIconsIcons

Components — renamed

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

All other Multinaire* components drop the prefix (e.g. MultinaireButtonButton).

Prop types renamed to match their component names exactly:

Old nameNew name
TextPropsTypographyProps
ImagePropsPhotoProps
SwitchPropsToggleProps
KeyboardAvoidingViewPropsKeyboardAvoidingContainerProps
ScrollViewPropsScrollContainerProps
ListViewPropsListContainerProps
TabViewPropsTabContainerProps
PageViewPropsPageContainerProps
ListPickerItemListPickerItemData
DatePickerPropsDateTimePickerProps

Removed

  • MenuButton.type prop ('default' | 'warning' | 'error') — foreground color is now always onBackground
  • ButtonType.destructive — use 'error' instead

Changed

  • Page animation changed from fade to directional slide (forward slides in from the right, backward from the left)

Added

  • MultinaireUI is now also the default export of @multinaire/ui

See the Migration Guide for a full upgrade walkthrough.