Miro Goettler
Fix color, add explaination
c56d4e4
"""
Heavily inspired by the code of:
https://arnaudmiribel.github.io/streamlit-extras/extras/stylable_container/
"""
import streamlit as st
mui_shadows = {
0: "none",
1: "0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)",
2: "0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)",
3: "0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)",
4: "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)",
5: "0px 3px 5px -1px rgba(0,0,0,0.2),0px 5px 8px 0px rgba(0,0,0,0.14),0px 1px 14px 0px rgba(0,0,0,0.12)",
6: "0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)",
7: "0px 4px 5px -2px rgba(0,0,0,0.2),0px 7px 10px 1px rgba(0,0,0,0.14),0px 2px 16px 1px rgba(0,0,0,0.12)",
8: "0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)",
9: "0px 5px 6px -3px rgba(0,0,0,0.2),0px 9px 12px 1px rgba(0,0,0,0.14),0px 3px 16px 2px rgba(0,0,0,0.12)",
10: "0px 6px 6px -3px rgba(0,0,0,0.2),0px 10px 14px 1px rgba(0,0,0,0.14),0px 4px 18px 3px rgba(0,0,0,0.12)",
11: "0px 6px 7px -4px rgba(0,0,0,0.2),0px 11px 15px 1px rgba(0,0,0,0.14),0px 4px 20px 3px rgba(0,0,0,0.12)",
12: "0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)",
13: "0px 7px 8px -4px rgba(0,0,0,0.2),0px 13px 19px 2px rgba(0,0,0,0.14),0px 5px 24px 4px rgba(0,0,0,0.12)",
14: "0px 7px 9px -4px rgba(0,0,0,0.2),0px 14px 21px 2px rgba(0,0,0,0.14),0px 5px 26px 4px rgba(0,0,0,0.12)",
15: "0px 8px 9px -5px rgba(0,0,0,0.2),0px 15px 22px 2px rgba(0,0,0,0.14),0px 6px 28px 5px rgba(0,0,0,0.12)",
16: "0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)",
17: "0px 8px 11px -5px rgba(0,0,0,0.2),0px 17px 26px 2px rgba(0,0,0,0.14),0px 6px 32px 5px rgba(0,0,0,0.12)",
18: "0px 9px 11px -5px rgba(0,0,0,0.2),0px 18px 28px 2px rgba(0,0,0,0.14),0px 7px 34px 6px rgba(0,0,0,0.12)",
19: "0px 9px 12px -6px rgba(0,0,0,0.2),0px 19px 29px 2px rgba(0,0,0,0.14),0px 7px 36px 6px rgba(0,0,0,0.12)",
20: "0px 10px 13px -6px rgba(0,0,0,0.2),0px 20px 31px 3px rgba(0,0,0,0.14),0px 8px 38px 7px rgba(0,0,0,0.12)",
21: "0px 10px 13px -6px rgba(0,0,0,0.2),0px 21px 33px 3px rgba(0,0,0,0.14),0px 8px 40px 7px rgba(0,0,0,0.12)",
22: "0px 10px 14px -6px rgba(0,0,0,0.2),0px 22px 35px 3px rgba(0,0,0,0.14),0px 8px 42px 7px rgba(0,0,0,0.12)",
23: "0px 11px 14px -7px rgba(0,0,0,0.2),0px 23px 36px 3px rgba(0,0,0,0.14),0px 9px 44px 8px rgba(0,0,0,0.12)",
24: "0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12)",
}
def card(
border=1,
padding=12,
border_radius=8,
width=None,
key=None,
color=None,
):
"""
This functions wraps Streamlit code to create a flexbox layout.
Users can set justify-content and align-items arguments of the function to achieve the desired layout.
"""
if key is None:
unique_hash = hash(str(border) + str(padding) + str(width) + str(border_radius) + str(color))
else:
unique_hash = key
unique_id = f"_card_key_{unique_hash}"
css_styles = []
# markdown elements in streamlit get bottom margin by default
# this needs to be removed to allow proper flex layout
css_styles.append(
"""
> div:first-child {
margin-bottom: -1rem;
}
"""
)
chosen_border = mui_shadows[border]
width_css = f"width: {width};" if width is not None else ""
# Your css styles are applied directly to the container div
#box-shadow: {chosen_border};
css_styles.append(
f"""
{{
background-color: {color};
padding: {padding}px;
border-radius: {border_radius}px;
{width_css}
}}
"""
)
# Streamlit will automatically set the width of all elements to the full width.
# This needs to be disabled to achieve standard HTML behavior
css_styles.append(
"""
*:not(div[data-testid="stCheckbox"], div[data-testid="stCheckbox"] * ):not(div[class="st-emotion-cache-chk1w8 e1ycw9pz2"] *) {
width: unset !important;
}
"""
)
style_text = """
<style>
"""
#:not(button[data-testid="stCopyButton"])
for style in css_styles:
style_text += f"""
div[data-testid="stVerticalBlock"]:has(> div.element-container > div.stMarkdown > div[data-testid="stMarkdownContainer"] > p > span.{unique_id}) {style}
"""
# This span is used to uniquely identify the container div with css :has(...the span...)
# therefore, the span should not be visible and not interfere with the flex layout
style_text += f"""
div.element-container:has(span.{unique_id}) {{
display: none;
}}
code {{
white-space: pre-wrap !important;
}}
</style>
<span class="{unique_id}"></span>
"""
container = st.container()
container.markdown(style_text, unsafe_allow_html=True)
return container