Major Changes
e6651adThanks @bataevvlad! - UI Kitten v6: React 19, React Native 0.81, Expo 54, all components migrated to functional, ESM build system, New Architecture ready.
Minor Changes
-
#1871
83bf8fdThanks @bataevvlad! - Add accessibility support forButton,Input,CheckBox,Radio,RadioGroup,Toggle,
Select,SelectItem,ProgressBar,CircularProgressBar,Spinner,ModalandPopover.These components now expose a role, and where applicable their checked, selected, expanded,
disabled, busy and numeric value state, to VoiceOver, TalkBack and web screen readers. Before
this change no component in the library set a single accessibility prop, so screen reader
users received an unlabelled view hierarchy.The props are emitted as
roleandaria-*rather thanaccessibilityStateand
accessibilityValue. React Native Web does not read either of those objects, so the
conventional spelling would have produced correct native output and no web accessibility at
all.accessibilityRoleis emitted alongsiderolebecauseTouchableOpacityignores
role. Anything a consumer passes — in modern or legacy spelling — still takes precedence.Overlays gain
aria-modaland support the iOS escape gesture.ModalandPopoveraccept a
newbackdropAccessibilityLabelprop; without it the backdrop stays out of the accessibility
tree rather than appearing as an unnamed control.Coverage is deliberately partial. Focus management in overlays,
Menu,Drawer, the
navigation components,Autocompleteand the calendar grid are not addressed — see the
accessibility guide for the full list and for the touch-target sizes that fall below the
platform minimums.Behaviour change:
Selectpreviously discarded every pass-through prop before rendering
its trigger, soaria-label,accessibilityLabeland otherTouchableWebPropsmembers
declared bySelectPropshad no effect. They now reach the trigger as the type always
implied. Code that passed such a prop toSelectand relied on it being ignored will see it
apply. -
#1871
c0e274dThanks @bataevvlad! - Calendar navigation is now reachable for assistive technology.Calendar,RangeCalendar,
DatepickerandRangeDatepickeracceptarrowLeftAccessibilityLabeland
arrowRightAccessibilityLabelto name the header's previous / next controls, which were
unlabelled buttons before. Day, month and year cells expose abuttonrole with their selected
and disabled state.Autocompletedocuments that the enclosingScrollViewor list needs
keyboardShouldPersistTaps='handled'; with React Native's default the first tap on an option
only dismisses the keyboard. -
#1871
6ce4786Thanks @bataevvlad! -Modal(and thereforePopover,Select,Autocomplete,Datepicker,RangeDatepicker,
TooltipandOverflowMenu) now presents its content through a root-level panel that
ApplicationProviderrenders around the app, instead of rendering the React NativeModal
at the call site.What moved. The native modal is still a React Native
Modal, but in the React tree it is
now a sibling of the app content rather than a descendant of the view that opened it. With
the keyboard open, aScrollView,FlatListorSectionListwith the default
keyboardShouldPersistTaps='never'used to claim the first tap on modal content during the
responder capture phase (root to target, firsttruewins) and only dismiss the keyboard, so
anAutocompleteoption needed two taps. Modal content is no longer inside that list, so a
single tap selects. SettingkeyboardShouldPersistTaps='handled'on the host list is no
longer required; it stays harmless.Nesting. iOS presents one chain of modals only: a second modal presented from a view
controller that is already presenting is refused. An overlay opened from inside a UI Kitten
Modaltherefore registers with that modal as its parent and renders inside the parent's
native modal, so Select, Tooltip, Popover and Datepicker keep working inside aModal.Consumer contexts. The presented element leaves the call site, so React contexts
provided belowApplicationProvider(navigation, i18n, form libraries, your own providers)
are no longer visible inside modal content. UI Kitten's own theme and mapping contexts are
bridged, so nestedThemeProvideroverrides still apply. Either move those providers above
ApplicationProvider, wrap the modal content in them, or opt a given modal out with the new
renderInlineprop onModalandPopover, which restores the previous inline rendering
(and the first-tap behaviour) for that modal and everything nested inside it.Overlay inside your own React Native
Modal. Such an overlay has no hoisted parent and
would be presented from the root, which iOS refuses while your modal is showing. Either wrap
that modal's content in a nestedApplicationProvider(its panel then presents overlays from
inside your modal) or passrenderInline. Rendering
<ModalPanelContext.Provider value={null}>forces inline rendering for a whole subtree.A
Modalrendered without anyApplicationProviderabove it still works: it renders inline
as before and warns once in development.
Patch Changes
-
#1871
efe22ddThanks @bataevvlad! - Fix Popover, Tooltip, OverflowMenu, Select, Autocomplete and Datepicker content rendering on top of
its anchor on edge-to-edge Android (React Native 0.81+, Expo 54). React Native presents every
Modalwindow edge-to-edge there, so the anchor position measured below the status bar is now
shifted by the status bar height without requiringModalService.setShouldUseTopInsets. Also
guards theshouldUseTopInsetsoffset against a missingStatusBar.currentHeight. -
#1871
657fc23Thanks @bataevvlad! - Stop shipping build leftovers in the published tarballs.builder-bob is configured with
source: ".", so it swept the package root into the build output. Every ESM package published alib/module/package.jsonthat was a copy of its own manifest — with no"type": "module"field and amainpointing at a path that does not exist — alongsidelib/module/CHANGELOG.mdandlib/module/tsconfig.build.json. Toolchains that determine module type from the nearestpackage.jsonwould read the ESM output as CommonJS; it only worked because Node falls back to syntax detection. bob now writes its own{"type": "module"}marker instead.@ui-kitten/processoralso shipped 38 spec and spec-config files (its!*.spec.*exclusion only matched the package root, notjs/), which is a third of the tarball. -
e8e14beThanks @bataevvlad! - Declare the./devsupportsubpath inexportsand stop the package importing itself.Four internal modules imported through the package's own name —
progressBarand
circularProgressBarpulled from@ui-kitten/componentsitself, a circular import of the
package barrel, whilemodalandcalendarHeaderreached in via undeclared subpaths.
Metro reported these asnot listed in the "exports"and fell back to file-based
resolution; they now use relative imports../devsupportis a real public surface (RenderProp,TouchableWebElement) and is now a
declared export with its own types, react-native, source, and default conditions.
Bundling a consumer app produces noexportswarnings. -
#1871
561a0acThanks @bataevvlad! - Ship a dual CommonJS + ES module build with type definitions that work under every
TypeScript module resolution.@ui-kitten/componentspublished ESM-only output whose.d.tsfiles sat in an ES-module
scope (lib/typescript/package.jsonwith"type": "module") but used extensionless relative
imports. UndermoduleResolution: node16/nodenextTypeScript rejected them with TS2834,
which made every root export disappear (Module '"@ui-kitten/components"' has no exported member 'Button').@ui-kitten/date-fns,@ui-kitten/eva-iconsand@ui-kitten/moment
pointedmainat ESM without a"type"field andtypesat their raw.tssource, so they
were reported asMasquerading as CJSand consumers compiled the library's TypeScript under
their own tsconfig.All four packages now build
lib/commonjs,lib/moduleand generated declarations for both
(lib/typescript/commonjs,lib/typescript/module) via react-native-builder-bob, and the
relative imports in the ESM declarations carry explicit.jsextensions.exportsexposes
importandrequireconditions with matchingtypes; thereact-nativeandsource
conditions still resolve to the TypeScript source for Metro.@arethetypeswrong/clireports
no problems fornode10,node16(CJS and ESM) andbundler.Every export object also ends with a
defaultcondition pointing at the CommonJS build with
matching types, as a fallback for resolvers that match none ofsource,react-native,
importorrequire.The dual layout costs tarball size. Measured with
npm pack(bytes, gzip):package 6.0.0-beta.2 (ESM only) dual build dual build, trimmed @ui-kitten/components375 697 479 774 421 524 @ui-kitten/moment3 780 6 240 5 458 @ui-kitten/eva-icons2 760 4 591 4 082 @ui-kitten/date-fns2 343 3 651 3 362 The trimmed column drops the
.js.mapfiles fromlib/commonjs(themoduletree keeps its
source maps). The.d.ts.mapfiles are kept in both declaration trees: without them,
go-to-definition lands on the generated.d.tsinstead of the shipped.tssource. The
remaining growth is the second JavaScript build and the second copy of the declarations,
which is the price of resolving correctly under bothrequireandimport. -
73e517fThanks @bataevvlad! - ExportAutocompleteRef,InputRef, andListReffrom the package root.All three were defined and exported by their own modules but never re-exported from the
barrel, so consumers had no way to type a ref forAutocomplete,Input, orList—
the same gap that madeIconRefunusable in practice. They now sit alongside the
already-exportedCalendarRef,DatepickerRef,RangeCalendarRef,RangeDatepickerRef,
andSelectRef. -
#1871
2bee712Thanks @bataevvlad! - Export the types used by public component props from the package root.EvaStatus,EvaSize,EvaInputSize,LiteralUnion,RenderProp,RenderFCPropandChildrenWithPropstype props such asButtonProps.status,.sizeand.accessoryLeft, but were only reachable through@ui-kitten/components/devsupport— a path whose name tells users not to import it. Anyone typing a wrapper component needed them.RenderPropandRenderFCPropalso now default their type parameter, so the documented bare spelling compiles:import type { RenderProp } from "@ui-kitten/components"; const accessory: RenderProp = <Icon name="star" />; // previously: TS2314
-
#1871
48f2806Thanks @bataevvlad! - Stop leaking type errors into consumer projects understrictwithoutskipLibCheck.Six errors reached apps that typecheck their
node_modules:ThemedThemeTypedeclared an optional__themeIdon an interface extending an index-signature type, which emitted a TS2411 error inthemeStore.d.ts.withStylesleft its style generic unconstrained, so the returnedThemedComponentClassemitted two TS2344 errors.MomentDateService.localeDatais assigned viasetLocale()from the constructor, which TypeScript cannot see (TS2564).DateFnsServicepassed the optionaloptions.formatstraight to date-fns (TS2345, twice).
@ui-kitten/momentand@ui-kitten/date-fnspublish no.d.tsand pointtypesat their raw TypeScript, so their source is typechecked directly by consumers — the last two now compile cleanly understrict. -
#1871
918ef23Thanks @bataevvlad! -Inputno longer derives@undefined/containerand@undefined/inputtest identifiers when
notestIDis passed. Derived identifiers are only emitted for an explicittestID, so the
wrapper and the text field stay free of placeholder identifiers in the accessibility tree.
Components that wrapInput, such asAutocomplete, are covered by the same guard. -
#1871
1d65240Thanks @bataevvlad! - Fix the web bundle breaking with"TurboModuleRegistry" is not exported by "react-native-web".
The edge-to-edge Android check inMeasureElementnow reads theDeviceInfoconstants through
NativeModules, which react-native-web ships as a shim and bridgeless React Native forwards to the
TurboModule registry, so web bundlers such as Vite, Rollup and webpack resolve the import again. -
92eedc8Thanks @bataevvlad! - Ship generated type definitions instead of raw source.typespointed at./index.ts, so consuming projects typechecked the library's own
source under their tsconfig and saw 221 errors fromnode_modules— with no workaround,
sinceskipLibCheckonly skips.d.tsfiles. The package now builds.d.tsvia
react-native-builder-bob'stypescripttarget and pointstypesat
./lib/typescript/index.d.ts.Fixing the 22 type errors that blocked declaration output also corrected real bugs:
React.ReactTextwas removed in React 19; replaced withstring | numberacross 19 sitesCalendar'sgetViewMode()was typed() => stringbut returns aCalendarViewModeTabView's view pager ref was typed as the component value rather thanViewPagerRefDatepickerPropsdeclared conflictingonBlur/onFocusinherited fromViewPropsdateServicewidened toNativeDateService | DateService<D>instead ofDateService<D>
Button,Select, andDatepickernow acceptstring | numberfor text props, matching
CheckBox/Toggle/Radioand the runtime behaviour ofFalsyText. Previously the
idiomatic<Button>TEXT</Button>did not typecheck.Type-only changes — the compiled bundle is byte-identical.
-
#1871
f00c66bThanks @bataevvlad! - Accept elements forTopNavigationaccessories, and fixRTLService.isRTL()on web.TopNavigationProps.accessoryLeftandaccessoryRightwere typed() => ReactElementwhile the JSDoc promisedReactElement | () => ReactElementand the runtime accepted both — the element form rendered correctly but failed to typecheck. They are nowRenderProp, matchingButtonand the rest of the library.RTLService.isRTL()returnedI18nManager.isRTLunguarded. react-native-web leaves that undefined, so a method declared to returnbooleanreturnedundefinedon web, andignoreRTL()'s default argument came out undefined with it. -
#1871
f8ca657Thanks @bataevvlad! - Document the v5 → v6 migration and ship a codemod that performs most of it.website/docs/migration/5x-to-6.mdis new: ref types, the React 19 fallout, thestyledremoval,
the@eva-design/*moves, and the Jest change the ESM-only build requires.The codemod itself lives at
src/codemodand is private for now, so it does not join the release
set. Two documentation samples that still imported@eva-design/evanow import@ui-kitten/eva,
matching the install instructions. -
Updated dependencies [
657fc23,03cad37,e6651ad]:- @ui-kitten/processor@6.0.0
- @ui-kitten/mapping-base@6.0.0