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.2.4] - 2026-08-09

Added

  • Popup's prop and context types are now exported from the package root. PopupProps, PopupType, PopupHeaderProps, PopupToggleButtonProps, and PopupContext were defined but never re-exported, so consumers could render Popup, PopupHeader, and PopupToggleButton but had no way to name their props — e.g. when writing a wrapper component or typing the return of usePopup(). They're now importable from @multinaire/expo-ui alongside the components themselves.
  • Input gained a maxHeight prop. Caps how tall a multiline field grows, in pixels. Once the cap is reached the content scrolls inside the field instead of expanding further and pushing the rest of the layout down. Defaults to three times the theme's height.large (300px with the stock theme); pass maxHeight to override it. Ignored unless multiline is set.

Changed

  • Buttons pulse more visibly while isLoading. The loading pulse on Button, ActionButton, IconButton, MenuButton, FloatingActionButton, and SocialLoginButton was easy to miss: it only faded to 0.5 opacity. It now dips to 0.35, so a busy button reads as busy at a glance. The 800ms half-cycle is unchanged — the pulse is deeper, not faster. Layout, sizing, and the button's content are unchanged. Skeleton placeholders (Animate, and the isLoading state of Typography, Icon, Photo, and friends) keep the original gentler pulse — a screenful of placeholders at the stronger setting is distracting.
  • Typography with onPress now renders as a pressable. onPress used to be forwarded to the underlying RN Text, which fires the handler but gives no visual feedback. The text is now wrapped in an AnimatedPressable driven by usePressableInteraction, so it dims on press and hover like the button components. margin and flex move to the wrapper (the inner Text keeps flex so vertical alignment still works), leaving outer layout unchanged; testID stays on the Text. Text without onPress is unchanged.
  • Icon with onPress now renders as a pressable. Previously onPress was forwarded straight to the underlying SVG, which gave no press feedback and behaved inconsistently across platforms and between the custom and Iconsax icon sets. The icon is now wrapped in an AnimatedPressable driven by usePressableInteraction, so it dims on press and hover like Button, IconButton, and Badge. testID moves to the pressable when onPress is set, and stays on the icon itself otherwise. Icons without onPress are unchanged.

Fixed

  • Accordion animating to a stale height when its content changed. The content height was measured once on the first layout pass and locked in for the lifetime of the panel — it had to be, because the measured node sat in flow inside the clipped wrapper and so kept re-reporting the wrapper's animated height on every frame of an expand/collapse. Content that arrived or changed after that first pass (async-loaded text, a growing list, re-wrapping after a rotation or font-scale change) left the panel expanding to the old height, clipping or over-padding its content. The measured node is now absolutely positioned inside the wrapper, so it is always laid out at its own natural size regardless of how far the wrapper is collapsed; onLayout therefore reports the real content height every time it changes, and an open panel animates smoothly to its new size. Measurement is held in a Reanimated shared value rather than component state, so re-measuring no longer costs a render.
  • Input with multiline not growing with its content on web. On native the field expands as text wraps, but on web multiline renders a real <textarea>, whose height comes from its rows attribute rather than its content — so it stayed a fixed height and scrolled internally instead. The field now uses CSS field-sizing: content on web, letting the browser size it to its content. In browsers without field-sizing support (notably Firefox) it keeps the previous fixed-height, internally-scrolling behavior. The scrollbar shown once a multiline field reaches its cap is hidden on web via scrollbar-width: none; the field still scrolls, and native is unaffected.
  • Input's wrapper row not following its multiline field's height on web. Even once the field itself grew, the row around it stayed locked at height.medium. The row cancelled its own fixed height with height: undefined, which works under React Native's StyleSheet.flatten (it copies the undefined over the earlier value) but not under styleq, which react-native-web uses — there, a property whose value is undefined is skipped without claiming the property, leaving the earlier height in force. It now uses height: 'auto', which overrides consistently on both platforms.
  • ListPicker rows with long labels wrapping out of their row. Each row is a fixed-height Card (height.medium), but its label was free to wrap onto a second line — so a long text either overflowed the row's bounds or pushed its leading icon and selected checkmark out of vertical alignment, and rows stopped lining up with each other. Labels are now capped at a single line and truncate with an ellipsis instead of wrapping. Short labels are unaffected.

[1.2.3] - 2026-07-29

Changed

  • BREAKING (behavioral): ScrollContainer no longer fills its parent by default. Previously, ScrollContainer always applied flexGrow: 1 internally — via React Native's ScrollView base style — even when no flex prop was passed, because an omitted flex couldn't override it. If you rely on a ScrollContainer without flex to fill the remaining screen height, pass flex={1} explicitly now. This matches the prop's documented default, which has always been "none".

Fixed

  • Popup filling the entire screen on native when its children include a ScrollContainer. Popup sizes itself on native by measuring how tall its content naturally is inside a full-window wrapper; a ScrollContainer's always-on flexGrow: 1 (see above) made it greedily expand to fill that wrapper, blowing the sheet out to full height regardless of how little content it held. ScrollContainer now only grows when flex is explicitly passed, so it sizes to its content inside Popup by default.
  • ListPicker resizing on web as content changed in 'list' mode. On web there's no ancestor with a definite height for flex: 1 to grow into (unlike native's bottom sheet), so the list shrink-wrapped to whatever was currently rendered and visibly resized on every keystroke while searching or as items loaded. ListPicker now gives its list a fixed height on web (8 rows) in 'list' mode, so it stays stable and scrolls internally instead of resizing.
  • Accordion not expanding on native (iOS and Android). Its content height was measured via onLayout on a child laid out inside an already-collapsed (height: 0) Animated.View; on native, a normal in-flow child of a collapsed animated parent never receives a real layout pass, so the measured height stayed stuck at 0 forever and the panel never grew (web was unaffected, since it goes through real CSS layout instead). Fixed by leaving the wrapper unclipped (and invisible) until the first real measurement lands, so that first layout pass happens naturally instead of being deferred, then switching to the normal animated height. Also added collapsable={false} to the wrapper to keep it from being optimized out of Android's native view hierarchy.

[1.2.2] - 2026-07-28

Added

  • Native bottom sheet presentation for Popup. On native, Popup now renders as a true bottom sheet (via @swmansion/react-native-bottom-sheet) with drag-to-dismiss and keyboard-aware height, instead of a Modal-based sheet simulation. MultinaireUI now wraps its children in a PopupWrapper (BottomSheetProvider) automatically — no additional setup is required.
  • @swmansion/react-native-bottom-sheet peer dependency (required, >=0.16.2).
  • usePopup().isDialog. Convenience boolean shorthand for usePopup().type === 'dialog', used internally by Dialog, Menu, ListPicker, and DateTimePicker and available to any custom popup content.

Changed

  • BREAKING: Popup no longer accepts a type prop. Presentation is now fully automatic and platform-based — always a bottom sheet on native, always a centered dialog on web. Remove any type="sheet" / type="dialog" passed to Popup. usePopup().type still reports the resolved presentation (read-only) so children (e.g. Dialog, Menu, ListPicker, DateTimePicker) can adjust for bottom safe-area insets.

Fixed

  • Popup content overflowing on web. Modal content is now capped to 80% of the viewport height and clips overflow, instead of growing past the edges of the screen for tall content.
  • AutoCompleteInput suggestion panel layout jump. The suggestion list now expands/collapses by animating its measured content height, instead of snapping to full height and fading opacity in/out, which used to shift surrounding layout abruptly.
  • Accordion expand/collapse layout jump. Same fix as above — content height is now measured and animated instead of relying on LinearTransition/fade transitions.

[1.2.1] - 2026-07-27

Fixed

  • peerDependencies version mismatch fixed an issue where peerDependencies for react* is mismatched.

[1.2.0] - 2026-07-27

Added

  • Accordion component (common). Collapsible panel built on Card, with an animated header (leading icon, title, optional badge, and a trailing chevron icon that defaults to ArrowUp2/ArrowDown2 based on active). It's a controlled component — the parent owns active state and toggles it via onPress. Expand/collapse and layout shifts are animated with react-native-reanimated.
  • AutoCompleteInput component (inputs), plus its row renderer AutoCompleteInputItem. A text input built on the same InputWrapper as Input, with an animated suggestion panel (Card-based, react-native-reanimated fade/layout transitions) that appears below it. Suggestions are supplied via items and filtered either client-side with searchPredicate or externally (e.g. server-side search wired up through onChangeText, toggling isLoading). Selecting a suggestion via onSelect auto-fills the input with its text. Supports minCharacters, maxVisibleItems (scrollable beyond that), noResultsText, and query highlighting in each row via highlightMatch.
  • Markdown component category. New theme-aware markdown renderer, usable with just a markdown string (no hook wiring required):
    • MarkdownTypography — a thin wrapper around react-native-enriched-markdown's EnrichedMarkdownText, typed directly from its props. Styling is theme-derived by default; pass a partial markdownStyle to override.
    • useEnrichedMarkdownStyle hook — exposes the theme-derived MarkdownStyle (typed from react-native-enriched-markdown) used by MarkdownTypography, for custom EnrichedMarkdownText composition.
  • react-native-enriched-markdown peer dependency (required, >=0.7.0).
  • New src/constants.ts module, exported from the package root: BREAKPOINTS and MAX_WIDTHS (previously internal to useResponsiveDesign), plus IS_ANDROID, IS_IOS, and IS_WEB platform flags.
  • hoverBackgroundColor in TabButtonStyle and SideBarButtonStyle. TabBar, TabContainer, and SideBar buttons now tint their background on hover (web/desktop only) when unfocused, distinct from the existing global press/hover opacity dim. Defaults to 'base' for top/bottom tabs and 'backgroundVariant' for sidebar items. Container gained matching onHoverIn/onHoverOut props to support this.

Fixed

  • Rapid taps selecting button/tab text on web. Typography (and everything built on it — buttons, tabs, badges, labels) rendered RN's Text, which is selectable by default on React Native Web (unlike native, where Text isn't selectable unless opted in). A quick second tap landed as a browser double-click on selectable text and selected it instead of registering as a second press. Typography now defaults selectable to false, matching native behavior; pass selectable explicitly to opt back in for content that should support copy/select.
  • Remaining SSR hydration mismatch in useResponsiveDesign. Its module-level width/height fallback still called Dimensions.get('window') directly instead of a fixed literal — on web this resolves to 0/0 on the server but the real viewport size on the client (read at bundle-evaluation time, before hydration), so the two isHydrated-gated fallback branches held different values per environment. The fallback is now the deterministic literal 0/0. Also fixed viewport width/height never updating after mount (useWindowDimensions changes weren't propagated into state); the hook's onLayout now only overrides the auto-tracked dimensions when explicitly wired up.
  • Light/dark theme flash on mount with SSR. useIsHydrated previously flipped from false to true via useSyncExternalStore, which React resolves through a passive effect — running after the browser paints. This meant ThemeProvider (and useResponsiveDesign) briefly painted their placeholder value ('light' / 0,0), then visibly repainted with the real value a frame later. useIsHydrated now flips inside a layout effect instead, which React guarantees resolves before the hydrated frame is painted — the placeholder is never actually shown on screen.
  • Persisted theme/language flash on mount, on web. ThemeProvider and LocalizationProvider read the persisted theme mode/language via AsyncStorage.getItem() inside a useEffect, so even though @react-native-async-storage/async-storage's web backend is just localStorage wrapped in a Promise, the applied value always landed a frame after the initial paint. On web, both providers now read localStorage directly and synchronously, from inside a layout effect — the persisted value is applied before the first paint instead of after it. Native is unaffected (still reads via AsyncStorage in an effect, which has no equivalent paint-timing concern).

[1.1.1] - 2026-07-17

Added

  • useIsHydrated hook — returns false on the server and during the client's hydration render, true immediately after mount. Exported so consumers can gate their own browser/device-only reads (window, matchMedia, etc.) behind hydration the same way the library now does internally.
  • onLayout handler in useResponsiveDesign. - setting internal width/height instead of windows's default.

Fixed

  • SSR hydration mismatches in ThemeProvider, LocalizationProvider, and useResponsiveDesign. On web, useColorScheme() and useWindowDimensions() read real browser state synchronously during render, and LocalizationProvider resolved the persisted/system language from AsyncStorage — none of which the server can know, so the client's hydration render diverged from the server-rendered markup. Color scheme, viewport dimensions, and the initial language now render with deterministic values ('light', 0/0, and the first configured/passed language respectively) until hydration completes, then switch to the real values immediately after mount. Translation resource bundles are also now registered synchronously during render instead of in a useEffect, so t() resolves correctly on the very first render everywhere.

[1.1.0] - 2026-07-13

Added

  • create-app CLI (@multinaire/create-app) — scaffolds a new project from a @multinaire/expo-ui template: npx @multinaire/create-app my-app. Supports --type expo (default, available now); --type react-native is reserved for an upcoming bare React Native CLI template.
  • Expo project template (templates/expo-template) — a production-ready Expo Router app pre-wired with @multinaire/expo-ui, theme.json, i18n (i18next/react-i18next), Iconsax icons, DateTimePicker, and AsyncStorage-backed theme/language persistence. Ships its own .npmrc, AGENTS.md, and .claude/ config.
  • Templates documentation — new "Templates" section in the docs site covering create-app usage and the Expo Template's structure and pre-installed modules.

Changed

  • Default backgroundVariant theme color (light & dark) now uses a translucent overlay (rgba(0, 0, 0, 0.04) light / rgba(255, 255, 255, 0.04) dark) instead of a flat gray, matching the value already used across templates and the Theme Builder.
  • GitHub Packages authentication docs standardized on the PERSONAL_ACCESS_TOKEN environment variable name (previously AUTH_TOKEN in Installation), matching the .npmrc shipped in every template.

Fixed

  • package.json repository/bugs/homepage URLs — corrected from the pre-rename multinaire/ui to multinaire/expo-ui, matching the actual repository (stale since the 1.0.7 package rename).

CI

  • Added a manual workflow_dispatch workflow (publish-create-app.yml) to publish @multinaire/create-app to GitHub Packages independently of the library's release cycle.

[1.0.8] - 2026-07-04

Fixed

  • Published package was missing the build/ directory. The SDK 56 upgrade in 1.0.7 bumped expo-module-scripts to a version where expo-module prepare no longer builds the package (it's now a no-op). Since nothing else in npm ci/npm publish ran the build step, the 1.0.7 tarball published to GitHub Packages shipped without compiled output. Added a prepublishOnly script (expo-module prepublishOnly) so the library is always cleaned and rebuilt before publishing.

CI

  • Bumped actions/checkout and actions/setup-node to v5 in both workflows, clearing the "Node.js 20 is deprecated" warning from GitHub Actions (v4 bundled a Node 20 runtime; v5 targets Node 24).
  • Added a manual workflow_dispatch trigger to the npm publish workflow so it can be run on demand instead of only on release creation.

[1.0.7] - 2026-07-03

Breaking Changes

Package renamed: @multinaire/ui@multinaire/expo-ui. Update your dependency and every import:

npm uninstall @multinaire/ui
npm install @multinaire/expo-ui
// Before
import MultinaireUI, { Button, Typography } from '@multinaire/ui';

// After
import MultinaireUI, { Button, Typography } from '@multinaire/expo-ui';

Also update any declare module '@multinaire/ui' TranslationSchema augmentation and tsconfig.json path mappings to @multinaire/expo-ui. See the Migration Guide.

Changed

  • Upgraded to Expo SDK 56. Bumped peer/dev dependencies accordingly: expo ~56.0.13, react 19.2.3, react-native 0.85.3, react-native-reanimated 4.3.1, react-native-worklets 0.8.3, react-native-screens 4.25.2, react-native-svg 15.15.4, typescript ~6.0.3, and the expo-* family to their SDK 56 releases. Minimum supported versions are now Expo SDK 56 and React Native 0.85.
  • expo-navigation-bar / expo-status-bar / expo-system-ui usage updated for their SDK 56 APIs (declarative <NavigationBar>/<StatusBar> components instead of imperative calls). No change to MultinaireUI's public behavior.

Removed

  • @react-navigation/native peer dependency — navigation-related types are now sourced through expo-router's re-exports, so the package no longer needs to be installed separately alongside expo-router.

[1.0.6] - 2026-06-27

Added

  • Dialog.onCancel prop — optional () => void callback invoked when the cancel button is pressed (used when type="confirm"). Previously the cancel button only called onRequestClose on the parent Popup.

Fixed

  • DancingScript and OpenSans missing locale font keys — the MultinaireUI font map was missing my and th locale entries for DancingScript and OpenSans, causing text to fall back to the wrong font when the active locale was Myanmar or Thai. The locale-specific keys are now registered.

[1.0.5] - 2026-06-26

Added

  • NotoSans font family"NotoSans" is now a valid fontFamily value in theme.json. The library bundles NotoSans (Latin), NotoSans Myanmar, and NotoSans Thai. The correct glyph set is selected automatically based on the active locale: my → Myanmar, th → Thai, anything else → Latin.
  • translate(key, options?) interpolation parameterLocalizationContext.translate now accepts an optional options: Record<string, unknown> second argument for i18next variable substitution (e.g. translate('welcome', { appName: 'MyApp' })).

Fixed

  • Popup backdrop tap on Android — tapping outside the modal no longer dismisses it on Android, preventing accidental dismissals. iOS behavior is unchanged.
  • Input multiline padding — vertical padding on multiline inputs is now applied to the inner TextInput rather than the container, ensuring correct text alignment on all platforms.

[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.