All pages
Powered by GitBook
1 of 1

Loading...

Components

Components are the fundamental building blocks of the UI in Flash. They represent reusable visual elements such as Button, Text, Image, Card, etc., which are used to construct layouts and interactive screens.

To use components in Flash, they must go through specific steps: making them configurable (Flash compliant) and then registering them. This process ensures the components can respond to server-driven configuration for styling, data, and behaviour.

Component vs Confiured Component

A component refers to a standard React (or React Native) component that is static in nature it uses hardcoded props and styles and behaves the same way every time it is rendered.

A configured component is a wrapper around such a component that makes it Flash compatible It can:

  • Dynamically apply styles from config

  • Render data passed from config

  • Attach configurable events and actions

This transformation allows the component to be controlled remotely through the server.

Example:

Example
// Regular Non-Flash Compatible Component
const FooterButton = ({ text, onPress }) => (
  <Pressable onPress={onPress}>
    <Text>{text}</Text>
  </Pressable>
)

// Flash-Compatible Configured Component
import { FlashPressable, FlashText } from 'flash-client'

const FooterButtonFlash = (props: ConfigurableProps) => {
  const { data } = props
  const testId = data?.testId

  return (
    <FlashPressable
      nativeID={`${testId}-button-container`}
      onPress={data?.onPress}
      configProps={props}
    >
      <FlashText
        nativeID={`${testId}-button-title`}
        configProps={props}
      >
        {data?.text}
      </FlashText>
    </FlashPressable>
  )

Configured Component vs Registered Component

A configured component is capable of consuming server driven configuration, but it is not yet known to the Flash system until it is explicitly registered.

A registered component is a configured component that has been linked to a unique componentName using the registerComponent() method. Once registered, it becomes available for use in templates created on the Flash dashboard.

In short:

  • A configured component can read and apply config

  • A registered component is a configured component that the Flash system can recognize and render dynamically

Example
// Register Flash-Compatible Component to SDK
import { Flash } from 'flash-client'
import { FooterButtonFlash, CardComponent } from './components'

Flash.registerComponent({
  FooterButtonFlash,
  CardComponent
}

Component Type

To create a Flash template in realtime from backend, we need basic building blocks. It is not always possible to create complex templates with only building blocks which has complex ui or stateful logic. So, along with basic building blocks, we also need project specific prebaked components whose ui and logic is written in codebase. Similar to basic building blocks, we register prebaked components and make them available in the dashboard during template creation in realtime.

Type
Description
Example

BaseComponent

Stateless components with no children.

Text, Image, Toast

BaseComponentWithChildren

Stateless, layout-like components that support children.

View, Pressable

PreBakedComponent

Project-specific, complex components with custom logic, no children.

CardComponent, TeamCard

PreBakedComponentWithChildren

Complex project components that also support nesting/children.

Accordion, TabLayout, Modal

These types allow balancing flexibility (basic blocks) with performance and logic encapsulation (prebaked).

Flash Component Schema

Every UI element that is rendered in your app via Flash is described using a JSON object. This schema defines the structure, style, behavior, and children of a component — all of which are interpreted by the Flash renderer on the client side.


Component — The Core Unit

Component = {
  name: string;
  components?: Array<Component>; // Nested children
  styles?: Style;
  overrides?: Overrides;
  data?: PropData;
  dataId?: string;
}

Let’s break down each field:

Field
Type
Purpose

name

string

This must match the registered name of a component (via registerComponent). Example: "FooterButtonFlash"

components

Component[]

Nested or child components, used by layout-type components like View, ScrollView, etc.

styles

Style

Styling config like margin, padding, color, etc., applied to the root of the component.

overrides

Overrides

Style or prop overrides targeted via nativeID inside the component.

data

PropData

Dynamic props to control content and behavior (text, image source, backend data etc.).

dataId

string (optional)

Can be used for fetching external data via binding systems.


Example Component JSON

{
  "name": "FooterButtonFlash",
  "data": {
    "text": "Submit",
    "testId": "footer",
  },
  "styles": {
    "padding": 12,
    "backgroundColor": "#FF5733"
  },
  "overrides": {
    "footer-button-title": {
      "styles": {
        "color": "#FFFFFF",
        "fontSize": 16
      }
    }
  }
}

This will:

  • Render the component registered as FooterButtonFlash

  • Pass data.text to it

  • Style the outer wrapper with padding and background color

  • Override styles for inner FlashText using nativeID="footer-button-title"


Supporting Types

1. Style

Style = {
  [key: string]: ViewStyle | TextStyle | ImageStyle;
}
  • This is a union of style objects similar to React Native's StyleSheet.

  • It supports keys like:

    • margin, padding, flexDirection → from ViewStyle

    • color, fontSize, fontWeight → from TextStyle

    • resizeMode, tintColor → from ImageStyle

These styles are applied to the root of the component, unless used in overrides.


2. PropData

PropData = {
  [key: string]: string | number | boolean | null | PropData | Array<PropData>;
}
  • This is the data prop passed to the component.

  • It's fully dynamic and recursive — it can contain primitives, objects, or arrays.

  • Used to drive:

    • Text or image content

    • Test IDs, flags, booleans, etc.

Props inside data are typically used inside the component like:

const text = props.data?.text

3. Overrides

Overrides = {
  [nativeId: string]: {
    props?: PropData;
    styles?: Style;
  };
}

Overrides allow the server to reach deep inside a component and override:

  • Its props

  • Its styles

This is possible only if that inner component uses nativeID.

nativeID is a identifier that says: “You can target this element with overrides.”

Example Use Case

Imagine a card component that has a title and a subtitle. You want to override the color of the subtitle only in one use case without changing the entire card component.

You can assign nativeID="card-subtitle" and override it like:

"overrides": {
  "card-subtitle": {
    "styles": {
      "color": "#999999"
    }
  }
}

⚠️ If nativeID is missing, overrides will have no effect.

Configurable Props

To make the component configurable, the component should take configProps. configProps is passed as props to the component and has flash data.

/**
 * Represents configurable properties that can be passed to a component.
 *
 * - `components`: An optional array of child components. This allows for the nesting of components, enabling complex UI structures.
 * - `styles`: An optional object that defines the styling for the component. This allows the component to be visually customized.
 * - `overrides`: An optional object that allows for overriding the styles and props of child components. This is useful for dynamic customization based on server data.
 * - `data`: An optional generic type (`Data`) that contains the data required by the component. This could include text, numbers, or other types of data that the component needs to render.
 * - `events`: An optional object that defines the events and their corresponding actions (e.g., `onPress`, `onLongPress`).
 *
 * @template Data - The type of the data prop. Defaults to `never` if not specified.
 */
export type ConfigurableProps<Data, Style> = {
  readonly components?: Array<Component>
  readonly styles?: Style
  readonly overrides?: Overrides
  readonly data?: Data
  readonly events?: EventActions
}