Design System — UI Components / Composants UI
Update date : 2026-05-16 02:41
Status / Statut :
ui_components/is planned for L2. The API documented here is the target interface — implementations are pending. /ui_components/est planifié pour L2. L'API documentée ici est l'interface cible — les implémentations sont en cours.
Reference for all UI components. / Référence pour tous les composants UI.
Import conventions / Conventions d'import
Always import with sks_ aliases to avoid shadowing st.* names. / Toujours importer avec des alias sks_ pour éviter d'écraser les noms st.*.
from pinky_streamlit import text as sks_text
from pinky_streamlit import header as sks_header
from pinky_streamlit import badge as sks_badge
from pinky_streamlit import metric as sks_metric
from pinky_streamlit import filters as sks_filters
Text elements / Éléments texte
header() — ui_components/text/
Section heading with optional icon. / En-tête de section avec icône optionnelle.
| Param | Type | Default | Description |
|---|---|---|---|
title |
str |
— | Header text / Texte du header |
level |
int |
2 |
Heading level 1–3 / Niveau de titre |
icon |
str \| None |
None |
Material icon string / Chaîne Material icon |
accent |
str |
"primary" |
Color token / Token de couleur |
from pinky_streamlit import header as sks_header
sks_header("Buildings", icon=str(ICONS.BUILDING), accent="primary")
sks_header("Details", level=3, icon=str(ICONS.INFO), accent="grey")
text() — ui_components/text/
Styled paragraph. / Paragraphe stylisé.
from pinky_streamlit import text as sks_text
sks_text("Step completed successfully", accent="success", size="sm")
sks_text("Note: all fields are required", accent="grey", muted=True)
badge() — ui_components/text/
Colored pill label. / Label pill coloré.
from pinky_streamlit import badge as sks_badge
sks_badge("Completed", accent="success")
sks_badge("3 alerts", accent="warning")
sks_badge("Failed", accent="error")
sks_badge("In progress", accent="primary")
empty_state() — ui_components/text/
Centered placeholder when a section has no data. / Placeholder centré quand une section n'a pas de données.
from pinky_streamlit import empty_state as sks_empty_state
sks_empty_state()
sks_empty_state("No files found", icon=str(ICONS.FOLDER))
Data elements / Éléments de données
metric() — ui_components/data/
KPI card with value, label, and optional delta. / Carte KPI avec valeur, label et delta optionnel.
from pinky_streamlit import metric as sks_metric
sks_metric("Billed penalties", "24.3 K €", delta="+2.7 K €", accent="primary", icon=ICONS.MONEY.material)
sks_metric("Active alerts", "0", accent="success", icon=ICONS.NOTIFICATION.material)
sks_metric("Anomalies", "12", delta="-3", accent="error")
Delta shows ↑ (green) or ↓ (red) automatically based on sign. / Le delta affiche ↑ (vert) ou ↓ (rouge) automatiquement selon le signe.
detail() — ui_components/data/
Single key-value row for record detail panels. / Ligne clé-valeur unique pour les panneaux de détail.
from pinky_streamlit import detail as sks_detail
sks_detail("Status", "Active", icon=ICONS.SUCCESS.material)
sks_detail("Created by", login)
data_editor() — ui_components/data/
Opinionated st.data_editor wrapper with inline edit detection, modification highlight, and save/cancel flow. / Wrapper opinioné de st.data_editor avec détection d'édition inline, surlignage des modifications et flux sauvegarde/annulation.
from pinky_streamlit import data_editor as sks_data_editor
sks_data_editor(
df=df,
key="buildings_editor",
columns={"CODE": st.column_config.TextColumn("Code"), "RATE": st.column_config.NumberColumn("Rate")},
on_save=lambda changes: update_data(session=session, data=changes, key="ID", table=TABLE),
accent="primary",
)
Internal flow / Flux interne :
1. Renders st.data_editor with columns and column_order
2. Detects changes via st.session_state[key]["edited_rows"]
3. If changes: shows a modification preview with highlight (#d0d0d0)
4. Save button → calls on_save(change_list) → st.rerun()
Key points / Points clés :
- edited_rows is a sparse dict — only modified cells are present. / edited_rows est un dict sparse — seules les cellules modifiées sont présentes.
- After save: st.session_state[key] is deleted to reset the editor. / Après sauvegarde : st.session_state[key] est supprimé pour réinitialiser l'éditeur.
Input widgets / Widgets d'entrée
filters() + FilterConfig — ui_components/widgets/
Declarative filter configuration. / Configuration déclarative des filtres.
from pinky_streamlit import filters as sks_filters, FilterConfig
filter_results = sks_filters([
FilterConfig(column="COMPANY", label="Company", widget="pills_multi"),
FilterConfig(column="STATUS", label="Status", widget="segmented_control"),
FilterConfig(column="DATE", label="Period", widget="date_range"),
FilterConfig(column="IS_ACTIVE", label="Active only", widget="toggle", default=True),
], key="my-filters")
df_filtered = df[
df["COMPANY"].isin(filter_results["COMPANY"]) &
(df["IS_ACTIVE"] == filter_results["IS_ACTIVE"])
]
Available widgets / Widgets disponibles :
| Widget | Streamlit component | Selection |
|---|---|---|
pills |
st.pills |
single |
pills_multi |
st.pills |
multi |
segmented_control |
st.segmented_control |
multi |
multiselect |
st.multiselect |
multi |
selectbox |
st.selectbox |
single + "All" |
toggle |
st.toggle |
boolean |
checkbox |
st.checkbox |
boolean |
date |
st.date_input |
single date |
date_range |
st.date_input |
range |
slider |
st.slider |
numeric or range |
number_input |
st.number_input |
numeric |
add_dialog() + FormFieldConfig — ui_components/widgets/
Declarative modal form for insert/create flows. / Formulaire modal déclaratif pour les flux d'insertion/création.
from pinky_streamlit import add_dialog as sks_add_dialog, FormFieldConfig
FORM_FIELDS = [
FormFieldConfig(column="CODE", label="Code (*)", widget="text_input", required=True, max_chars=5, col_index=0),
FormFieldConfig(column="DESCRIPTION", label="Description (*)", widget="text_input", required=True, col_index=1),
FormFieldConfig(column="RATE", label="Rate (*)", widget="number_input", required=True, min_value=0.0, max_value=100.0, default=59.0, col_index=2),
]
@st.dialog(" ", width="large")
def add():
sks_add_dialog(
title="Create building",
fields=FORM_FIELDS,
df_existing=df,
unique_columns=["CODE"],
on_save=lambda row: insert_data(session=session, data=[row], key="CODE", table=TABLE),
)
add_dialog() handles: N-column layout, required field validation, uniqueness check, on_save callback. / Gère : layout N colonnes, validation des champs requis, vérification d'unicité, callback on_save.
The @st.dialog decorator and st.rerun() stay in the page (app-specific). / Le décorateur @st.dialog et st.rerun() restent dans la page (spécifiques à l'app).
action_grid() + ActionConfig — ui_components/widgets/
Horizontal row of action buttons (app-launcher style). / Rangée horizontale de boutons d'action (style lanceur d'apps).
from pinky_streamlit import action_grid as sks_action_grid, ActionConfig
sks_action_grid([
ActionConfig(icon=str(ICONS.UPLOAD), key="btn-upload", help="Import files"),
ActionConfig(icon=str(ICONS.PLAY), key="btn-run", help="Start processing"),
ActionConfig(icon=str(ICONS.DOWNLOAD), key="btn-export", disabled=True, help="Export unavailable"),
ActionConfig(icon=str(ICONS.SETTINGS), key="btn-settings",hidden=True),
], num_cols=2, square=True)
Layout containers / Containers de mise en page
card_grid() — ui_components/layouts/
Responsive N-column card grid. / Grille de cards responsive en N colonnes.
from pinky_streamlit import card_grid as sks_card_grid
def my_card(item, idx):
st.markdown(f"**{item['title']}**")
st.caption(item["description"])
sks_card_grid(items=my_list, num_cols=3, render_func=my_card, key_prefix="my-cards")
Empty cells at the end of the grid are filled with st.empty(). / Les cellules vides en fin de grille sont remplies par st.empty().
divider() — ui_components/layouts/
Horizontal rule with optional centered label. / Ligne horizontale avec label centré optionnel.
from pinky_streamlit import divider as sks_divider
sks_divider()
sks_divider("Details", accent="primary")
sks_divider("2025", accent="grey")
Status elements / Éléments de statut
status_card() + StatusStepConfig — ui_components/status/
Card with pipeline step indicators. / Carte avec indicateurs d'étapes de pipeline.
from pinky_streamlit import status_card as sks_status_card, StatusStepConfig
steps = [
StatusStepConfig(label="Import", icon=ICONS.SUCCESS.emoji),
StatusStepConfig(label="Control", icon=ICONS.WARNING.emoji),
StatusStepConfig(label="Publish", icon=ICONS.CANCEL.emoji),
]
sks_status_card("2025/12", steps=steps, download_url="https://...", key="card-202512")
Combine with card_grid() to display a list of status cards. / Combiner avec card_grid() pour afficher une liste de cartes de statut.
Charts — Plotly toolkit / Charts Plotly
Charts use PALETTE colors and return a plotly.graph_objects.Figure. / Les charts utilisent les couleurs PALETTE et retournent un plotly.graph_objects.Figure.
from pinky_streamlit import donut_chart, bar_chart, line_chart, area_chart
fig = donut_chart(20.4, accent="error")
st.plotly_chart(fig, use_container_width=True)
fig = bar_chart(df, x="DATE_PERIOD", y="TOTAL", accent="primary")
st.plotly_chart(fig, use_container_width=True)
fig = line_chart(df, x="DATE_PERIOD", y=["RATE_1", "RATE_2"], accent=["error", "warning"])
st.plotly_chart(fig, use_container_width=True)
fig = area_chart(df, x="DATE_PERIOD", y=["CAT_A", "CAT_B"], accent=["primary", "secondary"], stacked=True)
st.plotly_chart(fig, use_container_width=True)
Common patterns / Patterns courants
Hide icon columns in dataframes / Masquer les colonnes icônes dans les dataframes
Columns produced by add_status_icons() (e.g. STATUS_ICON) should be hidden. Use column_order to control which columns are visible. / Les colonnes produites par add_status_icons() doivent être masquées. Utiliser column_order pour contrôler les colonnes visibles.
column_config = {
"CODE": st.column_config.TextColumn("Code"),
"RATE": st.column_config.NumberColumn("Rate"),
"STATUS_ICON": st.column_config.TextColumn(""), # shown as icon
}
column_order = ["STATUS_ICON", "CODE", "RATE"] # STATUS_ICON_RAW, etc. are excluded
st.dataframe(df, column_config=column_config, column_order=column_order)
Reset file_uploader after upload / Réinitialiser le file_uploader après upload
if "uploader_key" not in st.session_state:
st.session_state.uploader_key = 0
st.file_uploader("File", key=f"upload_{st.session_state.uploader_key}")
# After successful upload / Après upload réussi
st.session_state.uploader_key += 1
Multi-file validation / Validation multi-fichiers
Stop at the first blocking error. / Stopper dès la première erreur bloquante.
- Pass 1 — Name: regex on filename (type, period, extension) / Regex sur le nom de fichier
- Pass 2 — Consistency: all files share the same period / batch / Tous les fichiers partagent la même période / lot
- Pass 3 — Content: row-by-row validation (columns, format, lengths) / Validation ligne par ligne
Upload to stage / Upload vers stage
session.file.put_stream(
input_stream=file_bytes,
stage_location=f"@STAGE/{filename}",
auto_compress=False,
overwrite=True,
)
Checklist for UI components / Checklist pour les composants UI
In addition to DESIGN_SYSTEM.md / En complément de DESIGN_SYSTEM.md :
- Provide images in two variants (
{name}-light.png/{name}-dark.png) indemo/assets// Fournir les images en deux variantes - Configure filters with
FilterConfig+sks_filters()/ Configurer les filtres avecFilterConfig+sks_filters() - Configure add forms with
FormFieldConfig+sks_add_dialog()/ Configurer les formulaires avecFormFieldConfig+sks_add_dialog() - Use
sks_data_editor()for inline editing with highlight / Utilisersks_data_editor()pour l'édition inline avec surlignage - Use
sks_card_grid()/sks_action_grid()for grid layouts / Utilisersks_card_grid()/sks_action_grid()pour les layouts en grille