-
public final class StepConfigOverrideOptional config override for dynamic step content.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description public classStepConfigOverride.Companion
-
Field Summary
Fields Modifier and Type Field Description private final Map<String, Object>fieldDefaultsprivate final Stringtitleprivate final Stringsubtitleprivate final StringctaTextprivate final Map<String, List<InputOption>>fieldOptionsprivate final Map<String, Object>dataContextprivate final Map<String, MapRouteOverride>mapRoutes
-
Method Summary
Modifier and Type Method Description final Map<String, Object>getFieldDefaults()final StringgetTitle()final StringgetSubtitle()final StringgetCtaText()final Map<String, List<InputOption>>getFieldOptions()SPEC-448 §B — options supplied by the HOST APP, keyed by block id. final Map<String, Object>getDataContext()SPEC-452 — the host's data for THIS step, addressable from the console as {{hook_data.…}}.final Map<String, MapRouteOverride>getMapRoutes()SPEC-451 — the route a mapblock draws, supplied by the HOST APP, keyed by block id.-
-
Method Detail
-
getFieldDefaults
final Map<String, Object> getFieldDefaults()
-
getSubtitle
final String getSubtitle()
-
getCtaText
final String getCtaText()
-
getFieldOptions
final Map<String, List<InputOption>> getFieldOptions()
SPEC-448 §B — options supplied by the HOST APP, keyed by block id.
The app reads its own backend with its own client, auth and cache and hands the list over. No network, no credentials and no retry semantics inside this SDK — which is the point: a customer whose list sits behind their own auth cannot be served by our fetcher.
A block not named here keeps its authored options.
layoutOverrideswas REMOVED from this type. It was declared on all four SDKs and bridged by the wrappers, and no renderer ever read it — a host could set it and nothing happened. Making it work was the wrong fix: a bag that can overwrite any part of a step is unbounded, untestable and a promise we would have to keep forever. Removing a public field is normally breaking; here nothing ever read it, so no host can depend on its behaviour.
-
getDataContext
final Map<String, Object> getDataContext()
SPEC-452 — the host's data for THIS step, addressable from the console as
{{hook_data.…}}.Not another override: nothing here replaces a field. It is a read-only namespace the renderer's existing resolver reads, so the AUTHOR decides what is dynamic (by typing
{{hook_data.tour.price}}in the console, or pointing a blockbindingathook_data.…) and the host only supplies values. That is what separates it from thelayoutOverridesmistake above: the reachable surface is exactly the resolver's whitelist, and a path no author referenced does nothing at all.It exists because a screen that must show live data ON ARRIVAL — a recommendation card, a booking summary, an audio preview — has no interaction to trigger
ElementInteractionResult.fieldConfigPatches, which only fires after a tap.hook_datais one of the six rootsresolveDotPathaccepts and had no producer: every{{hook_data.x}}in every flow resolved to nothing, on both platforms.Paths walk maps and index lists, so
hook_data.recommendations.0.imageUrlresolves.
-
getMapRoutes
final Map<String, MapRouteOverride> getMapRoutes()
SPEC-451 — the route a
mapblock draws, supplied by the HOST APP, keyed by block id.The third and last route source, and the only one that can answer "where is this delivery right now": authored stops are fixed at publish time and a template variable can only carry what the flow already knows. The app reads its own routing service with its own client and hands the result over. No network, no credentials and no map-provider SDK inside ours.
Typed rather than a free-form
field_configpatch on purpose. A bag that can overwrite any key of any block is exactly whatlayoutOverrideswas, and removing that was the right call — it was unbounded, untestable, and a promise we would have had to keep forever. A route has a shape, so it gets a type.A block not named here keeps its authored route.
-
-
-
-