How do i wrap a custom component (React) into st.columns

Summary

How do i wrap a custom component (A new Material Card) into a streamlit column with the component width limited by the column width.
For example, if theres 12 columns - i want to be able to place 12 of the custom components into a single row based on column index.

Right now, the iframe takes up the full width of the page rather than the width of the column

Steps to reproduce

Code snippet:

## Full runable streamlit test 
import streamlit as st
from st_card_component import *
import random

st.set_page_config(layout="wide")

st.subheader("Test Application!")
st.markdown("---")


plant_areas = ['A','B','C','D','E']
units = ['AA','BB','CC']
colours = ['red','orange','green','grey']

dataList = [5, 10, 30, 200]
col1,col2 = st.columns([3,1])
col1.write(CardComponent("World", 10,20,"green",dataList,99), unsafe_allow_html=True)

col2.write(CardComponent("World", 10,20,"green",dataList,98), unsafe_allow_html=True)

plant_areas_col = plant_areas
plant_areas_col.insert(0,'Unit')
cols = st.columns(len(plant_areas_col))
for i,x in enumerate(cols):
    x.caption(plant_areas_col[i])
for u in units:
    cols2 = st.columns(len(plant_areas_col))
    for i,x in enumerate(cols2):
        if i == 0:
            x.write(u)
        else:
            dataList = [5, 10, 30, 200]
            # Using metric looks fine
            #x.metric("",str(random.choices(dataList,k=1)),str(random.choices(dataList)))
            x.write(CardComponent("World", random.choices(dataList,k=1),random.choices(dataList,k=1),random.choices(colours,k=1),dataList,u+str(i)))



# Card Component 
  return (
    <div>
      <Card variant="outlined" sx={{ backgroundColor: alertColour }}>
          <CardHeader   sx={{color: "#ffffff"}}
          title= {"Today: " + countToday } 
          subheaderTypographyProps={{ color: 'white' }} 
          subheader= {"Last Week: " + countLastWeek} />

          <CardContent  >
          <Sparklines data={dataList} height={10}>
            <SparklinesLine color="white" style={{ fill: "none" }} />    
            <SparklinesNormalBand />
          </Sparklines>

          </CardContent>
      </Card>
    </div>
  )

Expected behavior:

I want the custom component cardcomponent to be sized to the streamlit column rather than the full width of the page

Actual behavior:

The custom component takes up the full width of the page
CURRENT LAYOUT

PREFERRED LAYOUT

Debug info

  • Streamlit version: (get it with $ streamlit version)
  • Python version: (get it with $ python --version)
  • Using Conda? PipEnv? PyEnv? Pex?
  • OS version:
  • Browser version:

Requirements file

Using Conda? PipEnv? PyEnv? Pex? Share the contents of your requirements file here.
Not sure what a requirements file is? Check out this doc and add a requirements file to your app.

Links

  • Link to your GitHub repo:
  • Link to your deployed app:

Additional information

If needed, add any other context about the problem here.

Easy fix

plant_areas_col = plant_areas
plant_areas_col.insert(0,'Unit')
cols = st.columns(len(plant_areas_col))
for i,x in enumerate(cols):
    x.caption(plant_areas_col[i])
for u in units:
    cols2 = st.columns(len(plant_areas_col))
    for i,x in enumerate(cols2):
        if i == 0:
            **with cols2[i]:**
                 x.write(u)
        else:
            dataList = [5, 10, 30, 200]
            # Using metric looks fine
            #x.metric("",str(random.choices(dataList,k=1)),str(random.choices(dataList)))
            **with cols2[i]:**
                x.write(CardComponent("World", random.choices(dataList,k=1),random.choices(dataList,k=1),random.choices(colours,k=1),dataList,u+str(i)))

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.