Skip to main content

RSuite UI components for Streamlit — pickers, trees, carousel, timeline, and more.

Project description

st-rsuite

Built using RSuite · Streamlit Components v2

PyPI version Python >=3.10 License Open in Streamlit


Components

Pickers — rich popups with full interaction

Calendar popups, scrolling time panels, range selection with hover highlighting — everything you'd expect from a production date/time picker.

Component Description Streamlit equivalent
date_picker Calendar popup with format control, one-tap, ISO week st.date_input
date_range_picker Dual-calendar popup for date ranges, hover range st.date_input (range mode)
time_picker Time picker with scrolling panel, AM/PM st.time_input
time_range_picker Time range picker with dual panels --

Inputs — simple keyboard-only entry

Lightweight alternatives with no popup. Users navigate date segments with arrow keys and typing.

Component Description Streamlit equivalent
date_input Keyboard-only date input (no popup) st.date_input
date_range_input Keyboard-only date range input (no popup) st.date_input (range mode)

Selection

Component Description Streamlit equivalent
radio_tile Tile-based radio group with icons and descriptions st.radio

Tree — hierarchical data selection

Component Description Streamlit equivalent
check_tree Standalone tree with checkboxes, searchable --
check_tree_picker Dropdown picker with checkbox tree inside st.multiselect (flat)
multi_cascade_tree Multi-select cascading column navigation --

Display & Input

Component Description Streamlit equivalent
carousel Content/image carousel with autoplay, local files & URLs --
timeline Timeline with custom react-icons --
pin_input PIN/verification code input with masking st.text_input

All components are MIT licensed (RSuite is fully open-source).

Installation

uv add st-rsuite

or with pip:

pip install st-rsuite

Quick start

import streamlit as st
from datetime import date, time, timedelta
from st_rsuite import (
    date_picker, date_range_picker, time_picker,
    time_range_picker, date_input, date_range_input,
    radio_tile, check_tree, check_tree_picker,
    multi_cascade_tree, carousel, timeline, pin_input,
)

# ── Pickers ───────────────────────────────────────────────────────────────────

d = date_picker(label="Pick a date", value=date.today(), one_tap=True, key="my_dp")

start, end = date_range_picker(
    label="Trip dates",
    value=(date.today(), date.today() + timedelta(days=7)),
    hover_range="week",
    key="my_drp",
)

t = time_picker(
    label="Pick a time", value=time(9, 30),
    format="hh:mm aa", show_meridiem=True, key="my_tp",
)

t_start, t_end = time_range_picker(
    label="Shift hours",
    value=(time(9, 0), time(17, 0)),
    key="my_trp",
)

# ── Inputs ────────────────────────────────────────────────────────────────────

d2 = date_input(label="Type a date", value=date.today(), key="my_di")

start, end = date_range_input(
    label="Date range",
    value=(date.today(), date.today() + timedelta(days=7)),
    key="my_dri",
)

# ── Selection ─────────────────────────────────────────────────────────────────

selected = radio_tile(
    options=[
        {"value": "a", "label": "Option A", "description": "First option", "icon": "☀️"},
        {"value": "b", "label": "Option B", "description": "Second option", "icon": "🌙"},
    ],
    value="a",
    inline=True,
    key="my_tile",
)

# ── Tree components ───────────────────────────────────────────────────────────

tree_data = [
    {"value": "frontend", "label": "Frontend", "children": [
        {"value": "react", "label": "React"},
        {"value": "vue", "label": "Vue"},
    ]},
    {"value": "backend", "label": "Backend", "children": [
        {"value": "python", "label": "Python"},
        {"value": "go", "label": "Go"},
    ]},
]

checked = check_tree(data=tree_data, searchable=True, default_expand_all=True, key="my_ct")

picked = check_tree_picker(
    data=tree_data, placeholder="Select items", key="my_ctp",
)

cascade_data = [
    {"value": "us", "label": "US", "children": [
        {"value": "ca", "label": "California", "children": [
            {"value": "sf", "label": "San Francisco"},
        ]},
    ]},
]

cascade_selected = multi_cascade_tree(data=cascade_data, key="my_mct")

# ── Carousel ──────────────────────────────────────────────────────────────────

active = carousel(
    items=[
        {"content": "Slide 1", "background": "#7c3aed"},
        {"content": "Slide 2", "background": "#6d28d9"},
    ],
    autoplay=True,
    key="my_carousel",
)

# ── Timeline ──────────────────────────────────────────────────────────────────

timeline(
    items=[
        {"content": "Order placed", "time": "10:00", "icon": "FaCreditCard", "color": "#7c3aed"},
        {"content": "Shipped", "time": "14:30", "icon": "FaTruck", "color": "#0891b2"},
        {"content": "Delivered", "time": "11:30", "icon": "FaCheck", "color": "#059669"},
    ],
    align="left",
    key="my_timeline",
)

# ── PinInput ──────────────────────────────────────────────────────────────────

code = pin_input(length=6, mask=False, otp=True, key="my_pin")

API

Pickers

date_picker

date_picker(
    label="",
    value=None,           # date object or YYYY-MM-DD string
    format="yyyy-MM-dd",
    appearance="default",  # 'default' | 'subtle'
    size="md",
    placeholder="",
    placement="bottomStart",
    one_tap=False,        # single-click select (no OK button)
    disabled=False,
    cleanable=True,
    block=False,          # full width
    iso_week=False,       # Monday-start weeks
    show_week_numbers=False,
    locale=None,          # e.g. 'ja_JP', 'zh_CN', 'es_ES'
    on_change=None,
    key=None,
) -> date | None

date_range_picker

date_range_picker(
    label="",
    value=None,           # tuple of (date, date)
    format="yyyy-MM-dd",
    character=" ~ ",
    appearance="default",
    size="md",
    placeholder="",
    placement="bottomStart",
    disabled=False,
    cleanable=True,
    block=False,
    iso_week=False,
    show_week_numbers=False,
    show_one_calendar=False,  # single calendar panel
    one_tap=False,
    hover_range=None,     # 'week' | 'month' | None
    locale=None,
    on_change=None,
    key=None,
) -> tuple[date | None, date | None]

time_picker

time_picker(
    label="",
    value=None,           # time object or HH:MM string
    format="HH:mm",       # 'HH:mm', 'HH:mm:ss', 'hh:mm aa'
    appearance="default",
    size="md",
    placeholder="",
    placement="bottomStart",
    disabled=False,
    cleanable=True,
    block=False,
    show_meridiem=False,  # AM/PM toggle
    locale=None,
    on_change=None,
    key=None,
) -> time | None

time_range_picker

time_range_picker(
    label="",
    value=None,           # tuple of (time, time)
    format="HH:mm",
    character=" ~ ",
    appearance="default",
    size="md",
    placeholder="",
    placement="bottomStart",
    disabled=False,
    cleanable=True,
    block=False,
    show_meridiem=False,
    locale=None,
    on_change=None,
    key=None,
) -> tuple[time | None, time | None]

Inputs

Simple keyboard-only components — no popups, designed for compact quick-entry scenarios.

date_input

date_input(
    label="",
    value=None,           # date object or YYYY-MM-DD string
    format="yyyy-MM-dd",
    size="md",
    placeholder=None,
    disabled=False,
    locale=None,
    on_change=None,
    key=None,
) -> date | None

date_range_input

date_range_input(
    label="",
    value=None,           # tuple of (date, date) or (str, str)
    format="yyyy-MM-dd",
    character=" ~ ",      # separator between start and end
    size="md",
    placeholder=None,
    disabled=False,
    locale=None,
    on_change=None,
    key=None,
) -> tuple[date | None, date | None]

Selection

radio_tile

radio_tile(
    options=[...],        # list of dicts: {value, label, description?, icon?}
    value=None,           # default selected value
    inline=False,         # horizontal layout
    disabled=False,
    locale=None,
    on_change=None,
    key=None,
) -> str | None

Tree / Hierarchical

check_tree

check_tree(
    data=[...],           # [{value, label, children?: [...]}]
    value=None,           # list of selected values
    cascade=True,         # parent/child cascade selection
    searchable=True,      # show search input
    default_expand_all=False,
    show_indent_line=False,
    height=360,           # tree height in px
    disabled=False,
    uncheckable_values=None,
    locale=None,
    on_change=None,
    key=None,
) -> list[str]

check_tree_picker

check_tree_picker(
    data=[...],           # [{value, label, children?: [...]}]
    value=None,           # list of selected values
    cascade=True,
    searchable=True,
    countable=True,       # show selected count in toggle
    appearance="default",
    size="md",
    placeholder="Select",
    placement="bottomStart",
    disabled=False,
    cleanable=True,
    block=False,
    default_expand_all=False,
    show_indent_line=False,
    height=320,
    uncheckable_values=None,
    locale=None,
    on_change=None,
    key=None,
) -> list[str]

multi_cascade_tree

multi_cascade_tree(
    data=[...],           # [{value, label, children?: [...]}]
    value=None,           # list of selected values
    cascade=True,
    searchable=False,
    column_width=156,     # width of each cascade column
    column_height=320,    # height of each cascade column
    disabled=False,
    uncheckable_values=None,
    locale=None,
    on_change=None,
    key=None,
) -> list[str]

Display & Input

carousel

carousel(
    items=[...],          # [{content?, src?, alt?, background?, color?}]  # src: URL or local file path
    autoplay=True,
    autoplay_interval=4000,  # ms between slides
    placement="bottom",   # indicator: 'top' | 'bottom' | 'left' | 'right'
    shape="dot",          # indicator: 'dot' | 'bar'
    active_index=0,
    locale=None,
    on_change=None,
    key=None,
) -> int                  # active slide index

timeline

timeline(
    items=[...],          # [{content, time?, icon?, color?}]
    align="left",         # 'left' | 'right' | 'alternate'
    endless=False,        # continuous timeline line
    locale=None,
    key=None,
) -> None                 # display-only

The icon field accepts react-icons names (e.g. "FaCheck", "FaTruck", "MdEmail") or emoji strings as fallback. 150+ icons from Font Awesome 5 and Material Design are included.

pin_input

pin_input(
    length=6,
    value="",
    mask=False,           # password-style masking
    type="number",        # 'number' | 'alphabetic' | 'alphanumeric'
    size="md",
    placeholder="",
    disabled=False,
    read_only=False,
    otp=False,            # one-time password autocomplete
    attached=False,       # remove spacing between fields
    locale=None,
    on_change=None,
    key=None,
) -> str                  # current PIN value

Locale / i18n

All components accept a locale parameter to switch calendar labels, month/day names, and button text to the target language. RSuite ships 29 locales out of the box.

When locale is not set, the component automatically detects the browser's language (navigator.language) and uses the closest matching RSuite locale.

from st_rsuite import date_picker

# Japanese
date_picker(label="日付を選択", locale="ja_JP", one_tap=True, key="jp")

# Chinese (Simplified)
date_picker(label="选择日期", locale="zh_CN", one_tap=True, key="cn")

# Spanish
date_picker(label="Elegir fecha", locale="es_ES", one_tap=True, key="es")

Available locales: ar_EG, ca_ES, cs_CZ, da_DK, de_DE, en_GB, en_US, es_AR, es_ES, fa_IR, fi_FI, fr_FR, gu_IN, hu_HU, it_IT, ja_JP, kk_KZ, ko_KR, ne_NP, nl_NL, pl_PL, pt_BR, ru_RU, sv_SE, th_TH, tr_TR, uk_UA, zh_CN, zh_TW

Running the example

uv add st-rsuite
uv run streamlit run examples/showcase.py

Development

# Clone and install
git clone https://github.com/lperezmo/st-rsuite.git
cd st-rsuite
uv sync --dev

# Build frontend
cd st_rsuite/frontend
npm install
npm run build
cd ../..

# Run showcase
uv run streamlit run examples/showcase.py

Disclaimer

Full disclaimer: This project was built with the help of Claude Opus 4.6 by Anthropic, using Claude Code and streamlit/agent-skills. It is heavily based on st-mui.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

st_rsuite-0.3.2.tar.gz (9.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

st_rsuite-0.3.2-py3-none-any.whl (9.2 MB view details)

Uploaded Python 3

File details

Details for the file st_rsuite-0.3.2.tar.gz.

File metadata

  • Download URL: st_rsuite-0.3.2.tar.gz
  • Upload date:
  • Size: 9.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for st_rsuite-0.3.2.tar.gz
Algorithm Hash digest
SHA256 214ffc74f2f064e560672e4304afc4c70d65db6de761dcf8324ffebb45c36960
MD5 4657d23c3a01db40843fe0f54c413690
BLAKE2b-256 53034ab612b7c99d17e0a8d37b761c91d4ca767b20370a2d587c2431cf3ba3a4

See more details on using hashes here.

File details

Details for the file st_rsuite-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: st_rsuite-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 9.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for st_rsuite-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 12fdce62c42baa3904b523f4084ca966a96744f8495999c67566f30733db508f
MD5 2aa4c662267181b0f6acb4442193dde1
BLAKE2b-256 1c6f16587b914f6f138017ec5f3b89547d01e77312874a5434b1aa84346becbc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page