npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-rocketchat-uikit

v1.2.1

Published

React reconciler for building Rocket.Chat Apps UI Kit blocks

Readme

react-rocketchat-uikit

A React-based renderer for Rocket.Chat UiKit blocks. Write UiKit layouts using JSX components and render them to the Rocket.Chat block JSON format.

Installation

npm install react-rocketchat-uikit

Quick Start

import {
  render,
  Actions,
  Button,
  Section,
  Context,
  Mrkdwn,
} from "react-rocketchat-uikit";

const blocks = render(
  <>
    <Section text="Hello *world*!" />
    <Actions>
      <Button appId="my.app" blockId="b1" actionId="approve">
        Approve
      </Button>
      <Button appId="my.app" blockId="b1" actionId="reject" style="danger">
        Reject
      </Button>
    </Actions>
  </>,
);
// blocks → Rocket.Chat UiKit JSON array

Components

Layout Blocks

<Divider>

A horizontal rule that visually separates blocks.

<Divider />
<Divider blockId="divider1" />

<Section>

A flexible block for displaying text, optional fields, and an accessory element.

// Text only
<Section text="Hello *world*" />

// With fields
<Section fields={['Field A', 'Field B']} />

// With a Button accessory
<Section text="Pick one">
  <Button  blockId="b1" actionId="a1">Click</Button>
</Section>

<Actions>

Renders a set of interactive elements in a horizontal row.

<Actions blockId="actions1">
  <Button blockId="actions1" actionId="a1">
    Yes
  </Button>
  <Button blockId="actions1" actionId="a2">
    No
  </Button>
  <DatePicker blockId="actions1" actionId="a3" placeholder="Pick date" />
</Actions>

<Input>

A labelled input field that wraps a single input element.

<Input label="Name" hint="Enter your full name" optional>
  <PlainTextInput blockId="b1" actionId="name" placeholder="John Doe" />
</Input>

<Context>

Renders a mix of small text and image elements side by side.

<Context>
  <Mrkdwn text="*Bold* note" />
  <ImageElement imageUrl="https://example.com/icon.png" altText="icon" />
  <Plain text="plain note" />
</Context>

<Image>

A standalone image block with an optional title.

<Image
  imageUrl="https://example.com/photo.jpg"
  altText="A photo"
  title="My Photo"
/>

<Callout>

A highlighted callout box with an optional variant and accessory.

<Callout text="Something went wrong" variant="danger" />

// With a Button accessory
<Callout text="Action needed" variant="warning">
  <Button  blockId="b1" actionId="a1">Fix</Button>
</Callout>

<Preview>

A rich preview block with thumb or preview image.

title and description accept plain strings, TextObjects, or React text elements (<Mrkdwn>, <Plain>). Items that cannot be serialized are silently skipped.

// Thumbnail variant
<Preview
  title={["Article Title"]}
  description={["A short description"]}
  thumb={{ url: "https://example.com/thumb.png" }}
/>

// Preview-image variant (mutually exclusive with thumb)
<Preview
  title={["Article Title"]}
  description={["A short description"]}
  preview={{ url: "https://example.com/preview.png" }}
  externalUrl="https://example.com"
/>

// No media
<Preview
  title={["Article Title"]}
  description={["A short description"]}
/>

// React text elements in title / description
<Preview
  title={[<Mrkdwn text="*Article Title*" />]}
  description={["Plain prefix — ", <Mrkdwn text="_italic detail_" />]}
  thumb={{ url: "https://example.com/thumb.png" }}
/>

// With a Context footer
<Preview
  title={["Article Title"]}
  description={["A short description"]}
  thumb={{ url: "https://example.com/thumb.png" }}
>
  <Context>
    <Mrkdwn text="Posted by *User*" />
  </Context>
</Preview>

<VideoConference>

A video-conference block (only valid in Message surfaces).

<VideoConference callId="call-123" title="Team Standup" blockId="vc1" />

<InfoCard>

A card block composed of one or more <InfoCardRow> children.

<InfoCard>
  <InfoCardRow background="default">
    <Mrkdwn text="*Label:* value" />
  </InfoCardRow>
  <InfoCardRow background="secondary">
    <Plain text="Another row" />
    <IconButton blockId="b1" actionId="edit" icon="edit" />
  </InfoCardRow>
</InfoCard>

<InfoCardRow>

A single row inside an <InfoCard>. Accepts <Mrkdwn>, <Plain>, or <ImageElement> children, plus an optional <IconButton> which becomes the row action.

| Prop | Type | Description | | ------------ | -------------------------- | -------------------- | | background | 'default' \| 'secondary' | Row background style |

<Conditional>

Conditionally renders its child blocks depending on the hosting engine. This is the only block that can contain other layout blocks directly.

<Conditional engine={["rocket.chat"]}>
  <Section text="Only shown in Rocket.Chat" />
</Conditional>

<TabNavigation>

A tab-navigation bar containing one or more <Tab> elements.

Experimental — this block type may change in future versions.

<TabNavigation>
  <Tab blockId="b1" actionId="tab1" title="Overview" selected />
  <Tab blockId="b1" actionId="tab2" title="Details" />
  <Tab blockId="b1" actionId="tab3" title="Settings" disabled />
</TabNavigation>

Interactive Elements

<Button>

<Button blockId="b1" actionId="click" style="primary" value="val">
  Click me
</Button>

<StaticSelect> / <MultiStaticSelect>

<StaticSelect  blockId="b1" actionId="color" placeholder="Pick">
  <Option value="red">Red</Option>
  <Option value="blue">Blue</Option>
</StaticSelect>

// With a pre-selected value
<StaticSelect  blockId="b1" actionId="color" placeholder="Pick" initialValue="red">
  <Option value="red">Red</Option>
  <Option value="blue">Blue</Option>
</StaticSelect>

<UsersSelect> / <MultiUsersSelect>

<UsersSelect blockId="b1" actionId="user" placeholder="Select user" />
<MultiUsersSelect blockId="b1" actionId="users" placeholder="Select users" />

<ChannelsSelect> / <MultiChannelsSelect>

<ChannelsSelect blockId="b1" actionId="channel" placeholder="Select channel" />
<MultiChannelsSelect blockId="b1" actionId="channels" placeholder="Select channels" />

<ConversationsSelect> / <MultiConversationsSelect>

<ConversationsSelect blockId="b1" actionId="conv" />
<MultiConversationsSelect blockId="b1" actionId="convs" />

<DatePicker> / <TimePicker>

<DatePicker  blockId="b1" actionId="date" initialDate="2024-01-01" />
<TimePicker  blockId="b1" actionId="time" initialTime="09:00" />

<PlainTextInput>

<PlainTextInput blockId="b1" actionId="msg" placeholder="Type here" multiline />

<Option>

A selectable item used inside <StaticSelect>, <MultiStaticSelect>, <Overflow>, <CheckboxGroup>, <RadioButtonGroup>, and <ToggleSwitch>. The label is passed as children; description accepts a string, TextObject, or a React text element (<Plain>, <Mrkdwn>).

<Option value="red">Red</Option>
<Option value="red" description="A warm colour">Red</Option>
<Option value="red" description={<Plain text="A warm colour" />}>Red</Option>
<Option value="edit" url="https://example.com">Edit</Option>

<Overflow>

<Overflow blockId="b1" actionId="more">
  <Option value="edit">Edit</Option>
  <Option value="delete">Delete</Option>
</Overflow>

<CheckboxGroup> / <RadioButtonGroup>

<CheckboxGroup blockId="b1" actionId="checks">
  <Option value="a">Option A</Option>
  <Option value="b">Option B</Option>
</CheckboxGroup>

<ImageElement>

An inline image for use inside <Section> (as accessory) or <Context>. This is not the standalone <Image> block.

<ImageElement imageUrl="https://example.com/icon.png" altText="icon" />

<IconButton>

An icon-only button used as the action inside an <InfoCardRow>. Requires an icon name; use variant to control the visual style.

<IconButton blockId="b1" actionId="edit" icon="edit" />
<IconButton blockId="b1" actionId="delete" icon="trash" variant="destructive" label="Delete" />

<Tab>

A single tab for use inside <TabNavigation>.

Experimental — this element type may change in future versions.

<Tab blockId="b1" actionId="tab1" title="Overview" selected />

<ToggleSwitch>

Takes <Option> children, each representing one toggle item.

<ToggleSwitch blockId="b1" actionId="toggle">
  <Option value="on">Enable feature</Option>
</ToggleSwitch>

<LinearScale>

<LinearScale
  blockId="b1"
  actionId="rating"
  minValue={1}
  maxValue={5}
  initialValue={3}
  preLabel="Bad"
  postLabel="Excellent"
/>

Text Objects

<Mrkdwn>

<Mrkdwn text="*Bold* and _italic_" />

<Plain>

<Plain text="Just plain text" emoji />

Shorthand Components

For common single-element patterns, shorthand components reduce boilerplate by combining a wrapper block and its single child element into one component.

<ActionButton>

An <Actions> block with a single <Button> — the most common action pattern.

// ❌ Verbose
<Actions>
  <Button  blockId="b1" actionId="a1">Click</Button>
</Actions>

// ✅ Shorthand
<ActionButton  blockId="b1" actionId="a1">Click</ActionButton>

<InputTextInput>

An <Input> block with a single <PlainTextInput>.

// ❌ Verbose
<Input label="Name">
  <PlainTextInput  blockId="b1" actionId="name" placeholder="Enter name" />
</Input>

// ✅ Shorthand
<InputTextInput label="Name"  blockId="b1" actionId="name" placeholder="Enter name" />

<InputStaticSelect>

An <Input> block with a single <StaticSelect>.

// ❌ Verbose
<Input label="Color">
  <StaticSelect  blockId="b1" actionId="color">
    <Option value="red">Red</Option>
    <Option value="blue">Blue</Option>
  </StaticSelect>
</Input>

// ✅ Shorthand
<InputStaticSelect label="Color"  blockId="b1" actionId="color">
  <Option value="red">Red</Option>
  <Option value="blue">Blue</Option>
</InputStaticSelect>

// With a pre-selected value
<InputStaticSelect label="Color"  blockId="b1" actionId="color" initialValue="red">
  <Option value="red">Red</Option>
  <Option value="blue">Blue</Option>
</InputStaticSelect>

<InputDatePicker>

An <Input> block with a single <DatePicker>.

// ❌ Verbose
<Input label="Birthday">
  <DatePicker  blockId="b1" actionId="bday" initialDate="2000-01-01" />
</Input>

// ✅ Shorthand
<InputDatePicker label="Birthday"  blockId="b1" actionId="bday" initialDate="2000-01-01" />

<ContextMrkdwn>

A <Context> block with a single <Mrkdwn> element.

// ❌ Verbose
<Context>
  <Mrkdwn text="*Bold* note" />
</Context>

// ✅ Shorthand
<ContextMrkdwn text="*Bold* note" />

<ContextPlain>

A <Context> block with a single <Plain> text element.

// ❌ Verbose
<Context>
  <Plain text="Some text" />
</Context>

// ✅ Shorthand
<ContextPlain text="Some text" />

<ContextImage>

A <Context> block with a single <ImageElement>.

// ❌ Verbose
<Context>
  <ImageElement imageUrl="https://example.com/img.png" altText="img" />
</Context>

// ✅ Shorthand
<ContextImage imageUrl="https://example.com/img.png" altText="img" />

<SectionButton>

A <Section> block with a <Button> accessory.

// ❌ Verbose
<Section text="Pick one">
  <Button  blockId="b1" actionId="a1">Click</Button>
</Section>

// ✅ Shorthand
<SectionButton text="Pick one"  blockId="b1" actionId="a1">Click</SectionButton>

<SectionOverflow>

A <Section> block with an <Overflow> accessory.

// ❌ Verbose
<Section text="Options">
  <Overflow  blockId="b1" actionId="more">
    <Option value="edit">Edit</Option>
    <Option value="delete">Delete</Option>
  </Overflow>
</Section>

// ✅ Shorthand
<SectionOverflow text="Options"  blockId="b1" actionId="more">
  <Option value="edit">Edit</Option>
  <Option value="delete">Delete</Option>
</SectionOverflow>

Full Example

import {
  render,
  ActionButton,
  InputTextInput,
  InputStaticSelect,
  ContextMrkdwn,
  SectionButton,
  Divider,
  Option,
} from "react-rocketchat-uikit";

const blocks = render(
  <>
    <SectionButton text="Welcome to the form!" blockId="b1" actionId="info">
      Info
    </SectionButton>
    <Divider />
    <InputTextInput
      label="Your Name"
      blockId="b2"
      actionId="name"
      placeholder="Enter your name"
    />
    <InputStaticSelect label="Favorite Color" blockId="b3" actionId="color">
      <Option value="red">Red</Option>
      <Option value="green">Green</Option>
      <Option value="blue">Blue</Option>
    </InputStaticSelect>
    <Divider />
    <ActionButton blockId="b4" actionId="submit" style="primary">
      Submit
    </ActionButton>
    <ContextMrkdwn text="Powered by *Rocket.Chat UiKit*" />
  </>,
);

API Reference

render(element: ReactElement): LayoutBlock[]

Renders JSX elements into Rocket.Chat UiKit block JSON. Accepts a single element or a fragment containing multiple blocks.

resetActionIdCounter(): void

Resets the internal auto-increment counter used when actionId is omitted from an element. Call this between independent renders (e.g., in tests) to ensure deterministic IDs.

import { render, resetActionIdCounter, ActionButton } from 'react-rocketchat-uikit';

resetActionIdCounter();
const blocks = render(<ActionButton  blockId="b1">Click</ActionButton>);

TypeScript Utilities

Two generic helpers are exported for typing custom props that extend the block-kit wire format.

Actionable<Block>

Adds the required actionable fields (appId, blockId, actionId) and optional fields (confirm, dispatchActionConfig) to any block type. Mirrors Actionable<Block> from @rocket.chat/ui-kit, which is not part of that package's public API.

import type { Actionable } from 'react-rocketchat-uikit';

type MyButtonProps = Partial<Actionable<{
  style?: 'primary' | 'danger';
  label: string;
}>>;

LayoutBlockish<Block>

Adds the optional appId and blockId fields to any block type. Mirrors LayoutBlockish<Block> from @rocket.chat/ui-kit.

import type { LayoutBlockish } from 'react-rocketchat-uikit';

type MyBlockProps = LayoutBlockish<{
  title: string;
}>;
// → { title: string; appId?: string; blockId?: string }

License

MIT