Skip to content

Features & roadmap — pinky-streamlit

Update date : 2026-05-31 13:30

Current state

Module Status Key exports
core/constants.py stable PALETTES, PALETTE, ICONS, MATERIAL_ICONS, Icon, Palette, PaletteColors, Palette.to_config_toml()
core/session.py stable get_session(), LocalSessionConfig
core/db.py stable load_static, load_analytic, load_crud, load_nocache, update_data, insert_data, invalidate_crud, add_status_icons
core/page.py stable setup_page(), Logo, AppFont, DEFAULT_FONT, load_static_asset
ui_components/text.py planned text, header, badge, empty_state
ui_components/charts.py planned donut_chart, bar_chart, line_chart, area_chart
ui_components/status.py planned status_card, StatusStepConfig
ui_components/layouts.py planned card_grid, divider
ui_components/widgets.py planned filters, add_dialog, action_grid, stage_upload_dialog
ui_components/data.py planned metric, detail, data_editor — drilldown excluded (post-MVP)

MVP — migrate ui_components

Each module lands under ui_components/<module>.py with its own .css file. Module-scoped CSS: style.css = Streamlit normalization only; component CSS loaded on demand.

render_markdownui_components/text.py

def render_markdown(content: str, mermaid_js: str | None = None) -> None:
    """Render markdown with embedded Mermaid diagrams."""

Splits on ```mermaid fences. Plain parts → st.markdown. Mermaid blocks → components.html. Caller loads mermaid.min.js from stage and passes as string.

stage_upload_dialogui_components/widgets.py

def stage_upload_dialog(title, files: list[UploadFileConfig], stage_path, session) -> None

Key behaviours: per-file validation, cross-file consistency check, session.file.put_stream(), uploader_key increment resets widget after upload.

Out of scope (MVP)

  • drilldown (data.py) — multi-level state machine, needs its own design review
  • page.py mobile layout
  • Chat component (Cortex streaming)
  • media.py

Post-MVP — ordered by priority

drilldownui_components/data.py

Interactive multi-level drill with breadcrumb navigation. Already implemented in backup, excluded from MVP for design review.

def drilldown(df: pd.DataFrame, config: DrilldownConfig) -> None

Breadcrumb stored in st.session_state; Excel export at any depth.

page.py — mobile layout

setup_page() targets desktop today. Mobile variant: - Single-column forced layout, 44px min touch targets, st.sidebar collapsed by default - Viewport meta via components.html - Detection: st.context.headers User-Agent or ?mobile=1 query param

"Tell me a story" — analytic story mode

A story_button(metrics_config) that generates a focused 5–7 slide infographic surfacing only over/underperformance vs baseline. One insight per slide, no noise.

  • Detection: pure Snowpark SQL delta (no Cortex)
  • Renderer: HTML/CSS sequence via components.html (Datagora/Elabe infographic style)
  • Config: per-app StoryMetricConfig (metric, baseline comparison type)

Backlog

  • Chat componentst.chat_message wrapper with Cortex streaming
  • status.py — timeline variant — horizontal timeline for many short-label steps
  • media.py — audio waveform preview + image viewer with zoom