@rocapine/react-native-onboarding
Changelog
All notable changes to @rocapine/react-native-onboarding are documented here.
[Unreleased]
[1.50.1] - 2026-06-19
Changed
- Version parity bump. No functional changes to the headless SDK; released alongside
@rocapine/react-native-onboarding-ui1.50.1 (UI-onlyRadioGroup/CheckboxGrouptick-at-end layout fix).
[1.50.0] - 2026-06-19
Added
- ComposableScreen
RadioGroup/CheckboxGroup— tick + sub-label customization. New tick propstickPosition("start"|"end", default"start"),tickColor,tickSelectedColor,tickBorderRadius(default: radiotickSize / 2full circle, checkbox4), andtickSize(tick diameter / box side in px, default20— radio's inner dot and checkbox's ✓ glyph scale with it). Each item now accepts an optionalsubLabel(secondary line) with state-aware styling:itemSubLabelColor,itemSelectedSubLabelColor,itemSubLabelFontSize,itemSubLabelFontWeight,itemSubLabelFontFamily,itemSubLabelFontStyle. Itemlabelis now optional — when a label or sub-label is absent no gap is rendered.
[1.49.1] - 2026-06-19
Changed
- Version parity bump — no headless SDK changes. Released alongside the UI fix for ComposableScreen Carousel active dot sizing.
[1.49.0] - 2026-06-19
Added
- ComposableScreen
Carouselelement — more dot controls. New propsactiveDotWidth,activeDotHeight(active-dot size; default todotWidth/dotHeightwhen unset),dotsPosition("top"|"bottom", default"bottom"), anddotsMarginBottom(default0). Complements the existingdotColor/activeDotColor/dotWidth/dotHeight/dotsGap/dotsMarginTop.
[1.48.0] - 2026-06-19
Added
- Carousel pagination dot customization — the
Carouselstep payload accepts an optionalpaginationobject:show,dotColor,activeDotColor,dotWidth,dotHeight,activeDotWidth,activeDotHeight,gap,position("top"|"bottom"),marginTop,marginBottom. All fields optional; omittingpaginationkeeps the previous default look.
[1.47.0] - 2026-06-19
Added
- Injectable navigation — new
OnboardingNavigationAdaptertype, defaultexpoRouterAdapter, anduseOnboardingNavigation()hook.OnboardingProvideraccepts an optionalnavigationprop to plug in any navigation library (react-navigation, custom) instead ofexpo-router.
Changed
expo-routeris now an optional peer dependency (was a hidden hard import). When installed it is used automatically; otherwise inject anavigationadapter.useOnboardingStepcallsnavigation.useFocusEffectinstead of importingexpo-routerdirectly. Existing expo-router apps require no changes.
[1.46.0] - 2026-06-18
Added
- New
DrawingPadComposableScreenUIElementtype (type + Zod schema). A freehand drawing / signature surface that serializes the captured drawing into runtime variable(s):variableNamereceives an SVG path string,imageVariableNamereceives a base64 image data URI. Props:strokeColor,strokeWidth,backgroundColor,clearable,imageFormat("png"|"jpeg"), a customizable clear button (clearButtonPosition(4 corners),clearButtonOffset,clearButtonSize,clearButtonColor,clearButtonIconColor,clearButtonLabel), plus allBaseBoxProps. The renderer (UI package) requires the optional peer dependency@shopify/react-native-skia.
[1.45.0] - 2026-06-18
Added
SliderComposableScreen UIElement — a continuous numeric input bound to a variable. Value is stored as a stringified float (kind: "float") so expressions/conditions coerce it numerically. Props:variableName,defaultValue(number),min(0),max(1),step(0 = continuous), plusminimumTrackTintColor/maximumTrackTintColor/thumbTintColoranddisabled. Schema refinesmin <= max. Exposed viaSliderElementPropsand theUIElementunion /UIElementSchema.
[1.44.7] - 2026-06-18
Changed
- Version sync with
@rocapine/react-native-onboarding-ui@1.44.7(gradient elements no longer fill the screen). No headless changes.
[1.44.6] - 2026-06-18
Fixed
- Asset prefetch/preload now works for
ComposableScreensteps. The element tree walker inextractAssetUrlsrecursed intoprops.children, but theUIElementschema storeschildrenas a top-level sibling ofprops, so container recursion never fired — every nestedImage/Video/Lottie/Riveasset was skipped (composable screens always wrap content inSafeAreaView/ScrollView/stacks). Now recurses intoelement.children, so nested assets warm the cache as intended.
[1.44.5] - 2026-06-16
Changed
- Version sync with
@rocapine/react-native-onboarding-ui@1.44.5(staggered autoplayProgressIndicatorloader bars no longer reset to empty). No headless changes.
[1.44.4] - 2026-06-16
Changed
- Version sync with
@rocapine/react-native-onboarding-ui@1.44.4(empty/nullfontFamilynow falls back to the theme default). No headless changes.
[1.44.3] - 2026-06-16
Fixed
- Production no longer gets pinned to the offline fallback. The production
onboarding query was cache-first with
staleTime: Infinity: it returned the AsyncStorage cache and never called the edge function again, and it cached whatevergetStepsreturned — including the offline fallback. So a single first-launch fetch failure (timeout / offline / cold-start) cached the fallback and pinned every subsequent launch to it, while the device stopped hitting the studio entirely. The query now (1) never caches the fallback (detected via theONBS-Onboarding-Id: "fallback"header), so a bad launch self-heals on the next start, and (2) uses stale-while-revalidate — it serves the cache for an instant first paint while refreshing from the network in the background, so studio re-deploys propagate and a stale cache recovers.
[1.44.2] - 2026-06-15
Fixed
- Italic font faces are no longer dropped. The runtime font registry keyed
variants by weight only, so a
700-italicface was overwritten by the700-normalface at the same weight — anyfontStyle: "italic"text then rendered upright. Variants are now keyed by weight + style, both faces are registered, andresolveFontFamily/useResolvedFontStyle/useResolvedFontFamilyaccept an optionalfontStyleargument and pick the italic face when requested (falling back to the upright face when no italic is registered at that weight). - Apple SF Pro fonts now render at all weights on iOS. A manifest family
whose name collides with the iOS system font (
SF Pro,SF Pro Display,SF Pro Text,SF Pro Rounded,system, … — matched case- and separator-insensitively) is no longer registered as a bundled face on iOS: registering under the system family name made iOS give the system font precedence, so only Regular resolved (other weights rendered as tofu). On iOS such families now resolve tofontFamily: undefinedso React Native uses the real system font honoringfontWeight. On Android (no SF Pro system font) the bundled faces register and resolve normally.
Added
isSystemFontFamily,normalizeStyle, and theFontStyleKey/RegisteredFacetypes are now exported from the package.
[1.44.1] - 2026-06-15
Changed
- Runtime font registration — fonts now register under their file's
PostScript name (the font file's base name, e.g.
Inter-SemiBold.ttf→Inter-SemiBold) instead of a synthesized<family>-<weight>name.buildRegisteredNamenow derives the name from the font URL, stripping directory, query string, and extension.
[1.44.0] - 2026-06-11
Changed
- Version bump only — paired with
@rocapine/react-native-onboarding-ui1.44.0 (OnboardingPagekeyboardVerticalOffsetprop). No headless changes.
[1.43.0] - 2026-06-11
Added
ProgressiveBlurImageblurAppear— optional{ delay?, duration?, easing? }on the element schema. Drives a delayed fade-in of the blur layer over the always-visible sharp base image (the photo shows immediately, then the progressive blur arrives). Omitting it keeps the legacy static-on-mount blur.easing∈"linear" | "ease-in" | "ease-out" | "ease-in-out". New exportedBlurAppeartype.
[1.42.1] - 2026-06-11
Changed
- Version sync — no functional change to the headless SDK. Released alongside
@rocapine/react-native-onboarding-ui@1.42.1(Buttonflexfix) to keep both packages on the same version.
[1.42.0] - 2026-06-10
Added
- RadioGroup / CheckboxGroup per-item shadow — new optional props on both element schemas:
itemShadowColor,itemShadowOffset({ width, height }),itemShadowOpacity(0–1),itemShadowRadius(≥0), anditemElevation(≥0, Android). Applied to each item row.
[1.41.2] - 2026-06-10
Changed
- Version sync only — no headless changes. Bumped in lockstep with
@rocapine/react-native-onboarding-ui1.41.2 (appliesshadow*props on Stack/ZStack containers).
[1.41.1] - 2026-06-09
Changed
- Version sync only — no headless changes. Bumped in lockstep with
@rocapine/react-native-onboarding-ui1.41.1 (fixes a statictransformbeing suppressed until an element's entering animation finished).
[1.41.0] - 2026-06-09
Added
autoFocusprop onInputelement — whentrue, the input focuses on mount and the keyboard opens automatically. Optional, defaults tofalse.
[1.40.0] - 2026-06-09
Added
- Background asset preloader — once the onboarding payload is fetched, every remote image/video/Lottie/Rive/SVG asset referenced anywhere in the flow is warmed in the background so later screens render without a load flash. Fully non-blocking (never gates first render) and always on (no config). Covers ComposableScreen element trees (
Image/ProgressiveBlurImage/Video/Lottie/Rive, recursing through container children),MediaContent,Carousel, andLoaderdidYouKnowImages. Bundled assets (MediaSourcelocalPathId) are skipped — only remote URLs are warmed. - New exports —
extractAssetUrls(onboarding)(pure: returns dedupedAssetRef[]of remote assets, safe on partial/malformed payloads) andpreloadAssets(assets)(fire-and-forget; native image prefetch via expo-image/RN Image, HTTP-cache warm for video/Lottie/Rive/SVG with bounded concurrency).AssetRef/AssetKindtypes exported. Hosts can call these manually for custom preloading.
Changed
expo-imageadded as an optional peer dependency — used for batched image prefetch when present; falls back toImage.prefetchfrom react-native when absent. No-op if neither warms.
[1.39.0] - 2026-06-08
Added
AnimatedTextUIElement schema — type + Zod schema for the new count-up text element (from/to/duration/delay/easing/autoplay/loop/decimals/thousandsSeparator+ text styling). Added to the ComposableScreenUIElementunion.tois required; the element renders the number only and never writes a variable. See the UI package for the animatedTextInputrenderer.
[1.38.2] - 2026-06-08
Changed
- Version sync only — no headless changes. Bumped in lockstep with
@rocapine/react-native-onboarding-ui1.38.2 (UI-side fix: memoizeAnimatedBoxentering/exiting/layout builders so entry transitions don't restart on re-render).
[1.38.1] - 2026-06-08
Changed
- Version sync only — no headless changes. Bumped in lockstep with
@rocapine/react-native-onboarding-ui1.38.1 (UI-side re-render fixes in the Loader animations and ComposableScreen render tree).
[1.38.0] - 2026-06-08
Added
ProgressIndicatorvalue range (minValue/maxValue/step) — the indicator is no longer fixed to 0–100.minValue(default 0) andmaxValue(default 100) set an arbitrary value range, soautoplayanimatesinitialValue → maxValueand the boundvariableName/ label carry the raw value (not a percentage). Enables an animated count-up to N:{ minValue: 0, maxValue: 5000, step: 50, autoplay: true, variableName: "…" }, then read{{var}}in aText(mode: "expression").step(default 1,> 0) snaps the displayed/written value and bounds the per-sweep write count to(maxValue − minValue) / step— use a coarse step for large ranges.ProgressIndicator.labelSuffix— suffix appended after the label value (default"%"); set""or a unit (e.g." kg") for non-percentage ranges.
Changed
ProgressIndicatorvalue/initialValueno longer capped at 100 — their Zod.min(0).max(100)was relaxed to a plain number; out-of-range values clamp to[minValue, maxValue]at runtime instead of failing parse. Defaults (minValue:0,maxValue:100,step:1,labelSuffix:"%") keep existing percentage payloads byte-identical.
[1.37.0] - 2026-06-08
Added
onPresson every UIElement —BaseBoxPropsnow carries an optionalonPress: ButtonAction[], so any element can be made tappable with the same action list asButton.actions("continue"/{type:"setVariable"}/{type:"custom"}, run sequentially,"continue"terminal). Flows automatically to every ComposableScreen element variant via the sharedBaseBoxProps. The UI runtime ignores it on elements that own their own gesture (Button,RadioGroup,CheckboxGroup,DatePicker,Input,WheelPicker) — see the UI changelog.arrayOpon thesetVariableaction —SetVariableButtonActiongains an optionalarrayOp: "append" | "remove" | "toggle"that treats the target variable as the JSON-encodedstring[]multi-select used byCheckboxGroup.value/labelare the single member to add (dedup), drop, or flip; the storedlabelstays comma-joined like a real checkbox andkindis ignored. Lets any element (viaonPress) orButtonadd/remove a chip from a multi-select without aCheckboxGroupwidget. OmittingarrayOpkeeps the existing overwrite behavior.
Changed
ButtonActionmoved tocommon.types.ts—ButtonAction,CustomButtonAction,SetVariableButtonActionand their Zod schemas now live insteps/common.types.ts(shared with the newonPress), re-exported fromsteps/ComposableScreen/elements/ButtonElement.tsfor back-compat. No change to the public API surface or payload shape.
[1.36.2] - 2026-06-08
Changed
- Version alignment — no headless changes; bumped to stay in lockstep with
@rocapine/react-native-onboarding-ui1.36.2 (ComposableScreen text-element font fallback fix).
[1.36.1] - 2026-06-04
Changed
- Expo SDK 56 / React Native 0.85 alignment — bumped build-time
react(19.2.3) andreact-native(0.85.3) dev dependencies so the package builds against the SDK 56 toolchain. No runtime/API changes (peer deps stay*).
[1.36.0] - 2026-06-04
Added
blurRadiusprop on theImageComposableScreen element — optional non-negative number applying a uniform Gaussian blur (nativeImage.blurRadius, no extra dependency).0/omitted = sharp; ignored for SVGs.- New
ProgressiveBlurImageComposableScreen element — a full-bleed image with a gradient-masked Gaussian blur baked in (sharp where themaskis transparent, progressively blurred where it's opaque — the "welcome screen" hero look). Props:url,intensity(0–100, maps to a blur radius),tint(light/dark/default),mask,maxBlurOpacity, plus standard box props. Themaskis a union — linear ({ from, to, stops },typeoptional) or radial ({ type:"radial", center?:{x,y}, radius?, stops }); each stop'sopacity= blur strength. Existing{ from, to, stops }payloads stay valid as linear. Leaf element (nochildren); intended as the bottom layer of aZStack. New exported typesLinearBlurMask/RadialBlurMask. (UI renders this by masking a blurred copy of the image — see the UI changelog.)
[1.35.0] - 2026-06-02
Added
hapticprop onButton,RadioGroup,CheckboxGroupComposableScreen elements — optional enum"none" | "light" | "medium" | "heavy" | "soft" | "rigid"mapping to expo-hapticsImpactFeedbackStyle. Opt-in: absent or"none"= no feedback, so existing onboardings are unchanged. Backed by the sharedHapticStyletype +HapticStyleSchemaenum insteps/common.types.ts.
[1.34.1] - 2026-06-02
Changed
- Example onboarding — added a second WebP image (landscape, 16:9) to the default onboarding's first composable screen, alongside the existing portrait WebP. No schema or API change.
[1.34.0] - 2026-06-02
Added
ScrollViewelementalignItems/justifyContent— two optional props on theScrollViewUIElement controlling cross-axis alignment (alignItems:"flex-start"|"center"|"flex-end"|"stretch"|"baseline") and distribution along the scroll axis (justifyContent:"flex-start"|"center"|"flex-end"|"space-between"|"space-around"). Applied to the scroll content container.
[1.33.0] - 2026-06-01
Added
RichTextcontainer UIElement — a wrapping flex row of childTextelements (words + padded/rounded/rotated "chips" that wrap and align together, e.g. a "Boost your[energy]" marketing title). Because each child renders as a real flex child of a<View>(not a nested<Text>like inlineTextSpans), it honors its own box props —padding,borderRadius,borderWidth,backgroundColor,margin,transform— plusrenderWhenandexpressionmode. Plain-text children are split into one item per word so the row wraps word-by-word like a paragraph (chips flow inline with the text); children with box styling or motion stay atomic.childrenare schema-restricted toTextonly.propsare layout props (gap,alignItems— incl."baseline"—justifyContent,flexWrapdefaulting to"wrap") plus allBaseBoxProps, plus inherited text-style defaults (fontSize,fontWeight,fontFamily,fontStyle,color,textAlign,letterSpacing,lineHeight) — declare the title's base typography once on the container and each childTextinherits it (child overrides win). New exported type:RichTextElementProps. (Distinct from inlineTextSpan, which stays a single text-style-only wrapping paragraph.)
[1.32.0] - 2026-06-01
Added
- Animations / transitions / effects on every UIElement —
BaseBoxPropsgains two optional fields, so any ComposableScreen element can declare motion. Schema mirrorsreact-native-reanimated:presetvalues are the exact reanimated builder names and modifier fields map to builder methods.transform(static):{ translateX?, translateY?, scale?, scaleX?, scaleY?, rotate? (deg) }.animation:{ entering?, exiting?, layout?, effect? }.entering/exiting:{ preset, duration?, delay?, easing?, spring? }. Entering presets:FadeIn(Up/Down/Left/Right),SlideIn(Up/Down/Left/Right),ZoomIn(Rotate/Up/Down/Left/Right/EasyUp/EasyDown),BounceIn(Up/Down/Left/Right),FlipIn(XUp/YLeft/XDown/YRight/EasyX/EasyY),StretchIn(X/Y),RotateIn(DownLeft/DownRight/UpLeft/UpRight),RollIn(Left/Right),PinwheelIn,LightSpeedIn(Left/Right); exiting presets are the matching…Out…names.layout:{ preset, duration?, spring? }—LinearTransition,FadingTransition,SequencedTransition,JumpingTransition,CurvedTransition,EntryExitTransition.effect(continuous loop, not a reanimated builder name):{ preset: "pulse" | "fade" | "rotate" | "shimmer" | "bounce", duration?, delay?, easing?, loop?, minScale?/maxScale? (pulse), minOpacity? (fade), degrees? (rotate) }.
easing("linear"|"ease-in"|"ease-out"|"ease-in-out") andspring({ damping?, stiffness?, mass? }, mirrors.springify(config)and wins overeasing). New exported types:AnimationEasing,SpringConfig,EnteringPreset,ExitingPreset,LayoutPreset,EffectPreset,EnteringAnimation,ExitingAnimation,LayoutAnimation,ElementEffect,ElementAnimation,ElementTransform.
TextSpanextended — inline rich-text spans gainbackgroundColor,opacity(0–1),textTransform("none"|"uppercase"|"lowercase"|"capitalize"),textDecorationColor,textDecorationStyle("solid"|"double"|"dotted"|"dashed"), andlineHeight. All optional, inline-safe (animation/transform remain element-level only — spans are not UIElements).
[1.31.0] - 2026-06-01
Added
- Inline rich text for
Text—TextElementProps.contentis nowstring | TextSpan[]. A span array renders styled fragments inline (nested<Text>) that wrap together on one baseline. NewTextSpantype andTextSpanSchemaexported from the headless package. Span fields (all optional excepttext):text,fontWeight,fontStyle,fontFamily,fontSize,letterSpacing,color,textDecorationLine("none"|"underline"|"line-through"|"underline line-through"). Omitted span props inherit from the parentText. Inmode: "expression",{{variable}}interpolation applies to each span'stext.
Changed
TextElementPropsSchema.contentwidened fromz.string()toz.union([z.string(), z.array(TextSpanSchema)]). Backward compatible — existing string payloads validate and render unchanged.
[1.30.0] - 2026-05-29
Added
ProgressIndicatorUIElement — new ComposableScreen element rendering a linear or circular progress display bound to an int variable (0–100). Schema (ProgressIndicatorElementPropsSchema) and type (ProgressIndicatorElementProps,ProgressEasing) exported from the headless package and added to theUIElementunion. Props (all optional, plusBaseBoxProps):variant("linear"|"circular"),variableName(bound int variable — written each frame during autoplay, read otherwise),value(static 0–100),autoplay,loop,initialValue(0–100),duration(ms),delay(ms before the animation starts),easing("linear"|"ease-in"|"ease-out"|"ease-in-out"),color,trackColor,thickness,size,showLabel,labelColor.
[1.29.0] - 2026-05-29
Added
DatePicker:"now"sentinel for date bounds —defaultValue,minimumDate, andmaximumDatenow accept the literal string"now"in addition to ISO 8601 date strings."now"resolves to the current date/time at render, so a max date that should always be "today" no longer goes stale at module-load time. Schema validation accepts a value when it is"now"or parses viaDate.parse.SetVariableButtonActionSchema/SetVariableButtonAction— exported from the headless package and added to theButtonActionSchemaunion ({ type: "setVariable", name, value, label?, valueMode?, kind? }).
Fixed
ButtonActionSchemarejectedsetVariableactions — the headless union only accepted"continue"and{ type: "custom" }, while the UI package and runtime already supportedsetVariable. Any ComposableScreen payload using asetVariablebutton action failed parsing withinvalid_union. Headless now mirrors the UI variant, fixing the schema drift.
[1.28.0] - 2026-05-29
Added
RadioGroup/CheckboxGroup:showTickprop — both schemas extend with optionalshowTick: boolean(defaulttrue). Whenfalse, the per-item indicator (radio circle / checkbox box) is omitted; the item label and selected background / border styling still render. Lets authors build pill / card-style single- and multi-select groups without the tick glyph.
[1.27.0] - 2026-05-29
Added
- Unary condition operators
is_empty/is_not_empty/is_null/is_not_null— usable inrenderWhen,Button.disabledWhen, andnextStep.branches[].condition. They take novalue(schema makesvalueoptional for these and still required for binary operators).emptyis type-aware (empty/whitespace string, empty array, or unset/null);nullis unset/null only — a set-but-empty""is not null yet is empty. ExportsUNARY_CONDITION_OPERATORS+isUnaryConditionOperator. WheelPickerUIElement — scrolling wheel selector for the ComposableScreen system. Binds a variable viavariableName/defaultValue. Options come from either an explicititems: Array<{label, value}>or an auto-generated numericrange: {min, max, step?, unit?}(exactly one required;unitformats labels as"<value> <unit>"). Styling viaitemColor/itemFontSize/itemFontFamilyplus standardBaseBoxProps. ExportsWheelPickerElementProps,WheelPickerItem,WheelPickerRange,WheelPickerElementPropsSchema, and helpersresolveWheelPickerItems/generateWheelPickerRangeItems(shared with the UI renderer + default collection). Rendered via the optional@react-native-picker/pickerpeer dep (same as thePickerstep).
Fixed
- Condition evaluation now decodes JSON-array variable values — multi-select elements (
CheckboxGroup) store their value as a JSON string ("[]"when empty).evaluateConditiondecodes such strings back to an array before testing, so a fully-deselected group correctly reads as empty: arenderWhen/disabledWhenusingis_not_emptynow hides/disables again when the last item is unselected (previously"[]"was treated as a non-empty string and never fell back).containsagainst these values is now real array membership rather than a substring match.
[1.26.0] - 2026-05-28
Added
IconUIElement:fill+fillOpacityprops —IconElementPropsSchemaextends with optionalfill: string(any CSS color; omit ⇒ Lucide default"none"outlined) andfillOpacity: number(0–1, clamped). Enables filled / tinted Lucide icons (Star,Heart,Bookmark,Circle,CheckCircle2, …) from CMS payload.
Changed
onboarding-example.tsComposableScreen demo — wrappedrootYStack in aScrollViewUIElement so the payload scrolls (page renderer is intentionally a plainView flex:1, seecomposable-screen-runtime.md). HeroStaricon also showcasesfill+fillOpacity: 0.2tint.
[1.25.1] - 2026-05-28
Added
aspectRatioonBaseBoxProps— every UIElement now accepts an optional positiveaspectRationumber, mirroring the React Native style prop. Pair withwidth/heightto derive the other dimension instead of hard-coding both.
[1.25.0] - 2026-05-27
Added
ScrollViewComposableScreen UIElement — new container element wrapping children in a scrollable view. Props (ScrollViewElementProps, extendsBaseBoxProps):horizontal,bounces,showsVerticalScrollIndicator,showsHorizontalScrollIndicator,alwaysBounceVertical,alwaysBounceHorizontal,contentInset(ScrollViewContentInset:{ top, right, bottom, left }, iOS-only),contentContainerPadding,keyboardShouldPersistTaps.KeyboardAvoidingViewComposableScreen UIElement — new container element. Props (KeyboardAvoidingViewElementProps, extendsBaseBoxProps):behavior(KeyboardAvoidingBehavior:"padding" | "height" | "position", defaults to iOSpadding/ Androidheight),keyboardVerticalOffset,enabled.- Schema guard: no nested KeyboardAvoidingView —
ComposableScreenStepPayloadSchemanowsuperRefines the element tree and rejects anyKeyboardAvoidingViewnested inside another, reporting the offending elementid.
Backend note:
onboarding-studioshould mirror both new UIElement types (union + Zod schema + editor picker) and the nested-KAV validation rule, and default thepickerarchetype template to wrap its picker in aKeyboardAvoidingView.
[1.24.0] - 2026-05-27
Added
- Button per-state style overrides —
ButtonElementPropsgainspressedStyle?: ButtonStyleOverrideanddisabledStyle?: ButtonStyleOverride, each aPartialof the overridable Button props (BaseBoxPropsplusvariant,backgroundColor,color,fontSize,fontWeight,fontFamily,fontStyle,textAlign). NestedpressedStyle/disabledStyleare not overridable. NewtransitionDurationMs?: numbercontrols the rest/pressed/disabled animation length (default150). - Shadow fields on
BaseBoxProps—shadowColor,shadowOffset({ width, height }),shadowOpacity(0–1),shadowRadius, andelevation(Android) on every UIElement variant. Currently applied by theButtonrenderer in the UI package; schema accepts them on all elements.
Changed
disabledBackgroundColor/disabledColordeprecated — superseded bydisabledStyle.backgroundColor/disabledStyle.color. Still honored as a fallback whendisabledStyleis absent, so existing payloads are unaffected.
Backend note:
onboarding-studioshould mirror the newpressedStyle,disabledStyle, andtransitionDurationMsButton fields plus the shadow fields onBaseBoxProps, and surface per-state style editors. JSON serialization passes through unchanged.
[1.23.0] - 2026-05-26
Added
renderWhenon every UIElement variant — optionalrenderWhen?: LeafCondition | ConditionGroupfield on every entry of theUIElementdiscriminated union (Stack, Text, Image, Lottie, Rive, Icon, Video, Input, Button, RadioGroup, CheckboxGroup, DatePicker, Carousel, ZStack, SafeAreaView). Reuses the existingLeafConditionSchema/ConditionGroupSchemafromcommon.types— no new condition types. When the condition evaluates falsy against current ComposableScreen variables, the runtime skips rendering the element and its entire subtree. Companion toButton.disabledWhen(visual disabled state) andBranch.condition(flow-level next-step selection); userenderWhenfor in-screen conditional visibility (validation errors, variable-gated sections, etc.).
Backend note:
onboarding-studioshould mirror the optionalrenderWhenfield on every UIElement variant and surface a "Render when" condition picker in the element properties panel, reusing the Branch condition builder. JSON serialization passes through unchanged.
[1.22.0] - 2026-05-11
Added
kindonComposableVariableEntry— optional"int" | "float" | "string"tag on stored variables, exported asComposableVariableKind. Drives expression-mode coercion forsetVariableactions (numeric math vs string concat). Existing code paths ignore the tag, so back-compat is preserved.
Backend note:
onboarding-studioshould optionally surface akindfield onsetVariableactions and on any default variable seeding UI.
[1.21.0] - 2026-05-11
Added
defaultIndexandvariableNameon ComposableScreenCarousel— new optional props onCarouselElementProps.defaultIndex(integer, ≥ 0, nullable) sets the initial page at mount.variableNamebinds the carousel index to a variable in the ComposableScreen variable store:setVariablebutton actions targeting that name scroll the carousel imperatively, and user swipes write the new index back to the variable so other elements (Text{{var}}interpolation, branchingevaluateCondition) can react. Invalid / out-of-range values clamp to[0, children.length - 1]; missing / non-numeric values fall back todefaultIndex ?? 0.
Backend note:
onboarding-studioshould mirror thedefaultIndexandvariableNamefields on the Carousel UIElement schema and surface them in the CMS editor.
[1.20.0] - 2026-05-11
Added
disabledWhenon ComposableScreenButton— new optional prop onButtonElementPropsaccepting aLeafCondition | ConditionGroup(the same schema used byBranch.condition). When the condition evaluates truthy against current onboarding variables, the button blocks all press actions (continue, setVariable, custom) and renders in a disabled visual style.disabledBackgroundColoranddisabledColoronButton— optional per-button overrides for the disabled-state colors. Defaults fall back totheme.colors.disableandtheme.colors.text.disable.evaluateCondition,evaluateLeaf,isConditionGroup,Conditionnow exported from the package root so UI code (and host apps) can reuse the same condition runtime that powers branching.
Backend note:
onboarding-studioshould mirror theseButtonschema fields and reuse the existing condition-builder UI from theBranch.conditioneditor.
[1.19.0] - 2026-05-07
Added
fontFamily: "inherit"on ComposableScreenText/Button/Input—TextElementProps,ButtonElementProps, andInputElementPropsnow typefontFamilyasstring | "inherit". Omitting the prop or passing the literal"inherit"makes the renderer fall back totheme.typography.defaultFontFamily. Zod schemas remainz.string().optional()— the"inherit"literal is just a recognised string, no migration required for existing payloads.
Backend note: The
onboarding-studioserver should surface"inherit"(or omission) as a first-class option when authoring Text/Button/InputfontFamilyso CMS users can opt into the host app's default font.
[1.18.0] - 2026-05-06
Added
fontStyle: "normal" | "italic"on Text-rendering ComposableScreen UIElements. Top-level prop onTextElementProps,ButtonElementProps,InputElementProps. Per-item propitemFontStyleonRadioGroupElementPropsandCheckboxGroupElementProps. All optional; Zod-validated asz.enum(["normal", "italic"]).optional().setVariablebutton action —Button.actionsaccepts a new entry{ type: "setVariable", name: string, value: string, label?: string }that writes directly into the variable map. Useful to capture which branch a user chose before"continue"triggersresolveNextStepNumber. Stored shape matches existing element writes ({ value, label }).OnboardingProgressContext.getVariables()— synchronous getter that returns the latest variable snapshot from a ref. Use it insideonContinuehandlers to feedresolveNextStepNumberwith values just written bysetVariable, since React state reads are stale within the same tick.
Fixed
- Branching with same-tick
setVariable+continue— variables were read from React state in the handler that just wrote them, so branch conditions evaluated against pre-set values and fell through to the default target.setVariablenow updates a ref synchronously alongside the state setter;getVariables()exposes the fresh snapshot.
Backend note: The
onboarding-studioserver must mirror the newfontStyle(anditemFontStylefor RadioGroup/CheckboxGroup) field on the affected UIElement schemas, and the newsetVariablebutton action variant in theButtonActionunion and CMS editor.
[1.17.1] - 2026-05-04
Fixed
- Runtime fonts manifest —
registerFontsnow accepts the array shape returned byonboarding-studio({ family: [{ weight, style, url }, ...] }) in addition to the legacy{ family: { weightKey: url } }map. Previously, iterating an array withObject.entriesproduced numeric indices ("0".."N") as weight keys and passed the variant object asurl, causing native expo-font to throwloadSingleFontAsync expected resource of type Assetand warnings likeFailed to load font "X" weight 8 from [object Object]. The newnormalizeFamilyVariantsdedupes by weight and prefersstyle: "normal"variants over italic.
Added
FontVariantEntryandFontFamilyManifestInputexported types.FontsManifestwidened toRecord<string, FontFamilyManifestInput>so array-shape manifests are typed end-to-end.
[1.17.0] - 2026-04-30
Added
- Runtime font download + load —
Onboardingresponse now accepts an optional top-levelfonts?: FontsManifestfield, whereFontsManifest = Record<string, Partial<Record<FontWeightKey, string>>>. Font files are downloaded and registered viaexpo-font(optional peer dependency) when the onboarding payload is fetched.FontWeightKeyaccepts named (regular,medium,semibold,bold,extrabold) or numeric (100…900) keys, normalized internally. OnboardingProvider.fontsFallback?: ReactNode— rendered while the onboarding payload is fetched and remote fonts are downloading. Defaults tonull.<FontLoaderGate fonts={...} fallback={...}>— standalone gate component that registers fonts and exposes aFontRegistryvia context, for hosts that do not useOnboardingProvider.useFontRegistry()anduseResolvedFontFamily(family, weight)hooks for resolving afamily + weightrequest to the registered font name with a closest-weight fallback (CSS-style font matching).- New exports:
FontWeightKey,FontFamilyManifest,FontsManifest,FontRegistry,registerFonts,resolveFontFamily,normalizeWeight,FontRegistryProvider,useFontRegistry,useResolvedFontFamily,FontLoaderGate.
Changed
OnboardingProvidernow wraps children in an internalOnboardingDataGate(useQuery) followed byFontLoaderGate, blocking render until the onboarding payload is fetched and any declared fonts finish loading. The previousprefetchQuerycall is removed.
Backend note:
onboarding-studioshould mirror the newOnboarding.fontsfield — see the migration prompt in the PR description. ComposableScreen UIElement schemas are unchanged; this is an API-level addition.
[1.16.0] - 2026-04-29
Added
Button.actionsordered action array —ButtonElement.propsnow acceptsactions?: ButtonAction[], whereButtonAction = "continue" | { type: "custom"; function: string; variables?: string[] }. Actions run sequentially on press;awaits any returned Promise; aborts the remaining chain on a thrown error;"continue"is terminal.OnboardingProvider.customActionsprop —Record<string, CustomActionHandler>whereCustomActionHandler = (args: { variables: Record<string, ComposableVariableEntry | undefined> }) => void | Promise<void>. Functions are invoked by name fromButton.actions{ type: "custom", function, variables }, receiving the requested variables filtered from the live ComposableScreen variable map.- New exports:
ButtonAction,CustomButtonAction,ButtonActionSchema,CustomButtonActionSchema,CustomActionHandler,CustomActions,ComposableVariableEntry.
Changed
Button.action?: "continue"is now deprecated but still accepted as a back-compat alias. Whenactionsis absent andaction === "continue", runtime treats it asactions: ["continue"]. CMS payloads should migrate toactions.
Backend note: The
onboarding-studioserver must mirror the newButton.actionsfield in itsComposableScreenUIElement schema (Zod) and CMS editor (ordered list of"continue"or{ type: "custom"; function: string; variables?: string[] }). The legacyactionfield should be kept readable for historical payloads.
[1.15.0] - 2026-04-28
Added
SafeAreaViewUIElement — new container element mirroringreact-native-safe-area-context'sSafeAreaView. Props:mode?: "padding" | "margin",edges?accepting either("top" | "right" | "bottom" | "left")[]or a per-edge object mapping each edge to"off" | "additive" | "maximum". ExtendsBaseBoxProps. Exports:SafeAreaViewElementProps,SafeAreaEdge,SafeAreaEdgeMode,SafeAreaViewElementPropsSchema.
Backend note: The
onboarding-studioserver must be updated to accept and validate the new"SafeAreaView"element type in theComposableScreenUIElement union. MirrorSafeAreaViewElementPropsSchema(with the strict per-edge object) in the backend validation layer and addSafeAreaViewto the CMS editor element-type picker. Run the schema-sync/publish process inonboarding-studio(regenerate Zod schemas, bump validator package, deploy) before publishing this SDK release so CI and runtime payloads do not drift.
[1.14.0] - 2026-04-28
Added
ZStackUIElement — new container type that stacks children on top of each other using absolute positioning. Props: allBaseBoxPropsfields (width, height, padding, borderRadius, overflow, backgroundGradient, etc.). Children fill the container bounds by default, enabling image-with-overlay patterns.ZStackElementPropsandZStackElementPropsSchemaexported from the headless package.
[1.13.1] - 2026-04-28
Added
ZStackUIElement — new container type that stacks children on top of each other using absolute positioning. Props: allBaseBoxPropsfields (width, height, padding, borderRadius, overflow, backgroundGradient, etc.). Children fill the container bounds by default, enabling image-with-overlay patterns.ZStackElementPropsandZStackElementPropsSchemaexported from the headless package.
[1.13.0] - 2026-04-28
Added
-
backgroundGradientonBaseBoxProps— all UIElement types now accept an optionalbackgroundGradientprop alongsidebackgroundColor. Accepts aGradientBackgrounddiscriminated union (currentlytype: "linear"). -
LinearGradientConfig— linear gradient config:fromandtoare namedGradientEdgepositions ("top","bottom","left","right","topLeft","topRight","bottomLeft","bottomRight");stopsis an array of{ color: string; position?: number }(min 2 stops, position 0–1). -
Exports —
GradientBackground,GradientEdge,GradientStop,LinearGradientConfig, andGradientBackgroundSchemaexported from the headless package.
[1.12.0] - 2026-04-28
Added
-
Multi-path branching — every step schema now includes a
nextStepfield (nullable, defaults tonull). Whennull, navigation proceeds linearly. When set, an ordered list ofbranchesis evaluated; the first matching branch wins and navigation jumps tobranch.targetStepId. If no branch matches,defaultTargetStepIdis used as a fallback; if that is absent or unresolved, linear progression applies. -
Branch.conditionnullable — anullcondition on a branch is treated as unconditional (always matches). Useful as a final catch-all entry after guarded branches. -
Condition schema —
LeafConditionSchema,ConditionGroupSchema,BranchSchema, andNextStepSchemaadded tocommon.types.tsand exported from the package. Supported operators:eq,neq,gt,lt,gte,lte,contains,in,not_in. Conditions nest recursively viaConditionGroup(logic: "and" | "or",conditions: Array<LeafCondition | ConditionGroup>).ConditionValueSchemaacceptsstring | number | boolean | Array<string | number | boolean>. -
BaseStepTypeSchema— all per-step Zod schemas now extend a single shared base (id,name,displayProgressHeader,customPayload,continueButtonLabel,buttonSection,figmaUrl,nextStep) via.extend(). Previously each schema declared these fields independently. -
variableNameonQuestionandPicker— optionalz.string().min(1)field. When set, the answer selected on that step is stored in the global variable store under this key and becomes available to branch conditions on subsequent steps. -
Variable store —
OnboardingProgressContextgainsvariables: Record<string, any>andsetVariable(name, value). The store is written by the host app'sonContinuehandler and read byresolveNextStepNumber. -
resolveNextStepNumber(currentStep, variables, steps)— new exported pure function. Returns the 1-indexed step number to navigate to, ornullwhen the flow ends. Resolution order: matching branch →defaultTargetStepId→ linear next →null. Self-referencing targets (branch or default pointing back to the current step) are silently skipped to prevent infinite-loop routing. -
evaluateConditionmodule — pure condition-evaluation logic extracted tosrc/evaluateCondition.tswith no domain dependencies. ExportsevaluateLeaf,evaluateCondition,isConditionGroup, and theConditiontype. -
Test suite — Vitest added as a dev dependency. 75 tests across
evaluateCondition.test.tsandresolveNextStepNumber.test.tscovering all operators, AND/OR nesting up to 3 levels, branch ordering, unconditional branches,defaultTargetStepIdfallback, self-loop guard, and edge cases.
Changed
NextStepSchema.branchesnow defaults to[]— omittingbranchesfrom anextStepobject is valid; callers can set onlydefaultTargetStepId.
[1.11.1] - 2026-04-27
Changed
-
BaseBoxPropsexpanded — all UIElement schemas now inheritminWidth,maxWidth,minHeight,maxHeight,flexShrink,flexGrow,backgroundColor, andoverflowfrom the base. Previously these were missing or inconsistently defined per element. -
StackElement(YStack/XStack) props — now correctly extendsBaseBoxPropsinstead of declaringwidth/heightas number-only standalone fields.widthandheightnow acceptnumber | string(e.g."100%"). Stack-specific props retained:gap,alignItems,justifyContent,flexWrap. -
TextElementprops — now correctly extendsBaseBoxPropsinstead of duplicating margin/padding/border fields. Text-specific props retained:content,mode,fontSize,fontWeight,fontFamily,color,textAlign,letterSpacing,lineHeight. -
InputElementprops — addedfontFamily,lineHeight,letterSpacing. -
ButtonElementprops — removed redundantalignSelfoverride (now inherited fromBaseBoxPropswith the full enum). -
RiveElementprops — renamedautoplay→autoPlay(consistent casing with all other elements). -
CarouselElementprops — added dot style props:dotColor,activeDotColor,dotWidth(default20),dotHeight(default4),dotsGap(default8),dotsMarginTop(default12).
[1.11.0] - 2026-04-24
Added
CarouselUIElement schema forComposableScreen— new discriminated-union variant withtype: "Carousel". Takeschildren: UIElement[]— any renderable UIElement tree as slide content (same recursive system asYStack/XStack). Props:carouselType("normal"|"left-align"|"parallax"|"stack", default"normal"),autoPlay(boolean, defaultfalse),autoPlayInterval(number ms, default3000),loop(boolean, defaulttrue),showDots(boolean, defaulttrue),height(number, optional), plus allBaseBoxProps. Validated byCarouselElementPropsSchema(Zod). ExportsCarouselElementPropstype.
Backend note: The
onboarding-studioserver must be updated to accept and emit theCarouselUIElementvariant inComposableScreenpayloads. MirrorCarouselElementPropsSchemain the backend validation layer and addCarouselto the CMS element-type picker.
[1.10.0] - 2026-04-23
Added
DatePickerUIElement schema forComposableScreen— new discriminated-union variant withtype: "DatePicker". Props:variableName(string, optional — context key; selected date written as ISO 8601 string),defaultValue(ISO string, optional),minimumDate/maximumDate(ISO strings, optional),mode("date"|"time"|"datetime", default"date"),display("default"|"spinner"|"calendar"|"clock"|"compact"|"inline", optional — platform-specific),textColor,accentColor,locale(strings, optional), plus allBaseBoxProps. Validated byDatePickerElementPropsSchema(Zod).
Backend note: The
onboarding-studioserver must be updated to accept and emit theDatePickerUIElementvariant inComposableScreenpayloads. MirrorDatePickerElementPropsSchemain the backend validation layer and addDatePickerto the CMS element-type picker.
[1.9.0] - 2026-04-22
Added
CheckboxGroupUIElement schema forComposableScreen— new discriminated-union variant withtype: "CheckboxGroup". Props:variableName(string, optional — context key; selected values written as a JSONstring[]),items(Array<{ label: string; value: string }>, required, min 1),defaultValues(string[], optional — must reference valid item values),gap(number),direction("vertical"|"horizontal"), per-item styling (itemBackgroundColor,itemSelectedBackgroundColor,itemBorderColor,itemSelectedBorderColor,itemBorderRadius,itemBorderWidth,itemColor,itemSelectedColor,itemFontSize,itemFontWeight,itemFontFamily,itemPadding,itemPaddingHorizontal,itemPaddingVertical), plus allBaseBoxProps. Validated byCheckboxGroupElementPropsSchema(Zod); includessuperRefinechecks for unique item values and validdefaultValuesentries (per-index error paths).
Backend note: The
onboarding-studioserver must be updated to accept and emit theCheckboxGroupUIElementvariant inComposableScreenpayloads. MirrorCheckboxGroupElementPropsSchemain the backend validation layer and addCheckboxGroupto the CMS element-type picker.
[1.8.1] - 2026-04-22
Added
alignSelfprop onBaseBoxProps— available on all elements that extendBaseBoxProps(Input,RadioGroup,Image,Lottie,Rive,Icon,Video). Accepts"auto" | "flex-start" | "flex-end" | "center" | "stretch" | "baseline".
Changed
alignSelfonStackElement—StackElementPropsandStackElementPropsSchemanow includealignSelf(same enum) in addition to the existingalignItems.
[1.8.0] - 2026-04-21
Added
ButtonUIElement schema forComposableScreen— new discriminated-union variant withtype: "Button". Props:label(string, required, non-empty),action("continue", optional — defaults to callingonContinue),variant("filled"|"outlined"|"ghost"),backgroundColor,color,fontSize,fontWeight,fontFamily,textAlign,alignSelf, plus allBaseBoxProps. Validated byButtonElementPropsSchema(Zod).RadioGroupUIElement schema forComposableScreen— new discriminated-union variant withtype: "RadioGroup". Renders a group of radio options from an inlineitems: Array<{ label: string; value: string }>array. Props:variableName(string, optional — context key),defaultValue,gap,direction("vertical"|"horizontal"), allBaseBoxProps, and per-item styling (itemBackgroundColor,itemSelectedBackgroundColor,itemBorderColor,itemSelectedBorderColor,itemBorderRadius,itemBorderWidth,itemColor,itemSelectedColor,itemFontSize,itemFontWeight,itemFontFamily,itemPadding,itemPaddingHorizontal,itemPaddingVertical). Validated byRadioGroupElementPropsSchema(Zod).- Structured variable entries —
ComposableVariableEntrytype introduced:{ value: string; label?: string }. ThecomposableVariablescontext map is nowRecord<string, ComposableVariableEntry>instead ofRecord<string, string>.RadioGroupwrites bothvalue(raw) andlabel(human-readable) when an item is selected. Expression interpolation inTextelements resolveslabelfirst, falling back tovalue.
Note on semver: The
composableVariablestype changed fromRecord<string, string>toRecord<string, ComposableVariableEntry>. This is published as a minor bump (not major) becausecomposableVariablesis an internal context value not part of the public API contract. Existing consumers remain unaffected — access.valueon the entry for the same string result.
Changed (internal)
ComposableScreenelement types and Zod schemas split intoelements/subfolder — one file per element type.types.tsnow assembles theUIElementunion andUIElementSchemaby importing individual schemas.
Backend note: The
onboarding-studioserver must be updated to accept and emit theRadioGroupUIElementvariant inComposableScreenpayloads. MirrorRadioGroupElementPropsSchemain the backend validation layer and addRadioGroupto the CMS element-type picker.
[1.7.0] - 2026-04-21
Added
fontFamilyprop onTextUIElement — optionalfontFamily?: stringadded to theTextvariant ofUIElementand toTextElementPropsSchema(Zod). Pass any font family name loaded viaexpo-font(or a system font) to apply a custom typeface to a text node.
Backend note: The
onboarding-studioserver should be updated to accept and emitfontFamilyonTextUIElement props, and to expose a font-family input in the CMS text-element editor.
[1.6.0] - 2026-04-21
Added
InputUIElement schema forComposableScreen— new discriminated-union variant withtype: "Input". Renders a<TextInput>that writes its value into shared context viavariableName. Props:variableName(string, optional — context key),placeholder,placeholderColor,defaultValue,keyboardType,returnKeyType,autoCapitalize,secureTextEntry,maxLength,multiline,numberOfLines,editable, plus typography and layout props (color,fontSize,textAlign,padding*) and allBaseBoxProps(backgroundColor,borderWidth,borderRadius,borderColor,width,height,opacity,margin*). Validated byInputElementPropsSchema(Zod).- Variable context —
OnboardingProgressContextnow holdscomposableVariables: Record<string, string>andsetComposableVariable. Values written byInputelements survive navigation betweenComposableScreensteps. - Expression mode for
Textelements —mode?: "plain" | "expression"prop added toTextElementPropsSchema. When"expression",{{variableName}}patterns incontentare interpolated fromcomposableVariablesat render time. Default ("plain") is unchanged.
Backend note: The
onboarding-studioserver must be updated to accept and emit theInputUIElementvariant inComposableScreenpayloads, and to support themodeprop onTextelements. MirrorInputElementPropsSchemaand the updatedTextElementPropsSchemain the backend validation layer and addInputto the CMS element-type picker.
[1.5.0] - 2026-04-21
Added
IconUIElement schema forComposableScreen— new discriminated-union variant withtype: "Icon". Props:name(string, required — Lucide icon name),size(number),color(string),strokeWidth(number), plus allBaseBoxProps. Validated byIconElementPropsSchema(Zod).VideoUIElement schema forComposableScreen— new discriminated-union variant withtype: "Video". Props:url(string, required),autoPlay(boolean),loop(boolean),muted(boolean),controls(boolean), plus allBaseBoxProps. Validated byVideoElementPropsSchema(Zod).
Backend note: The
onboarding-studioserver must be updated to accept and emitIconandVideoUIElementvariants inComposableScreenpayloads. MirrorIconElementPropsSchemaandVideoElementPropsSchemain the backend validation layer and add both types to the CMS element-type picker.
[1.4.0] - 2026-04-21
Added
LottieUIElement forComposableScreen— renders a Lottie animation from a remote JSON URL vialottie-react-native(optional peer dep). Supportssource(required),autoPlay,loop,speed, and allBaseBoxProps(width,height,opacity,margin*,padding*,border*).RiveUIElement forComposableScreen— renders a Rive animation from a remote.rivURL viarive-react-native(optional peer dep). Supportsurl(required),autoplay,fit,alignment,artboardName,stateMachineName, and allBaseBoxProps.
Changed
BaseBoxPropsrefactor —width,height,opacity,margin*,padding*,borderWidth,borderRadius, andborderColorare now defined once in a sharedBaseBoxPropstype andBaseBoxPropsSchema, then extended byImage,Lottie, andRiveelement schemas. Stack and Text schemas are unchanged.
[1.3.0] - 2026-04-17
Added
ImageUIElement forComposableScreen— renders a remote image via React Native<Image>. Supportsurl(required),width,height,aspectRatio,resizeMode(cover|contain|stretch|center),borderRadius,borderWidth,borderColor,opacity, and all margin / padding shorthand props.aspectRatioprop onImageelements — applied as a size fallback whenheightis omitted; defaults to16/9so images never collapse to zero height.
[1.2.0]
Added
- ComposableScreen (under development) — new step type that defines a
declarative UI element tree (
YStack,XStack,Text) driven entirely from the CMS. TheUIElementtype and its Zod schema now support the following props on stack elements:borderWidth,borderRadius,borderColor,overflow,opacity,margin,marginHorizontal,marginVertical,width,height,minWidth,maxWidth,minHeight,maxHeight. Text elements gainmargin,marginHorizontal,marginVertical,borderWidth,borderRadius,borderColor, andopacity.
Note:
ComposableScreenis under active development. The schema may change before it is considered stable.