File size: 2,346 Bytes
db55b72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import contextlib

import streamlit as st
import streamlit.components.v1 as components


@contextlib.contextmanager
def st_flex(
    flex_direction="null",
    justify_content="null",
    align_items="null",
    flex="null",
    widths=None,
):
    """[flex](https://developer.mozilla.org/en-US/docs/Web/CSS/flex) for Streamlit.

    Warning: This custom component uses a lot of heuristics. But styling flex is
    important in CSS and missing from Streamlit. st.columns does a poor job at
    horizontally aligning elements.

    Args:
        flex_direction: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction
        justify_content:
            https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
        align_items: https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
        flex: https://developer.mozilla.org/en-US/docs/Web/CSS/flex
        widths: An array containing the minimal widths of all elements. This somewhat
            defeats the purpose of flex, but Streamlit forces the width of elements,
            which is why forcing this parameter is unfortunately needed.
    """
    placeholder = st.empty()
    with placeholder.container():
        placeholder = st.empty()
        with placeholder.container():
            yield
        components.html(
            f"""
            <script>
            window.frameElement.style.display = 'none';
            // Get the current script node
            const frameElement = window.frameElement.parentElement;

            // Get the parent element
            const parentElement = frameElement.parentElement;

            // Change container
            const container = parentElement.firstChild.firstChild;
            container.style.display = 'flex';
            container.style.flexDirection = '{flex_direction}';
            container.style.justifyContent = '{justify_content}';
            container.style.flex = '{flex}';
            container.style.alignItems = '{align_items}';
            container.width = '';
            container.className = '';

            // Change children
            let i = 0;
            for (const child of container.children) {{
              child.style.width = `${{{widths}?.[i] || 60}}px`;
              child.className = '';
              i += 1;
            }}
            </script>""",
        )