axiom-coding-agent-setup 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/agent-browser/SKILL.md +55 -0
- package/.agents/skills/developing-with-streamlit/SKILL.md +220 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-chat-ui/SKILL.md +195 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/SKILL.md +233 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/packaged-components.md +212 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/state-sync.md +149 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/theme-css-variables.md +243 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/troubleshooting.md +121 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-dashboards/SKILL.md +147 -0
- package/.agents/skills/developing-with-streamlit/skills/building-streamlit-multipage-apps/SKILL.md +218 -0
- package/.agents/skills/developing-with-streamlit/skills/choosing-streamlit-selection-widgets/SKILL.md +139 -0
- package/.agents/skills/developing-with-streamlit/skills/connecting-streamlit-to-snowflake/SKILL.md +188 -0
- package/.agents/skills/developing-with-streamlit/skills/creating-streamlit-themes/SKILL.md +486 -0
- package/.agents/skills/developing-with-streamlit/skills/displaying-streamlit-data/SKILL.md +199 -0
- package/.agents/skills/developing-with-streamlit/skills/improving-streamlit-design/SKILL.md +191 -0
- package/.agents/skills/developing-with-streamlit/skills/optimizing-streamlit-performance/SKILL.md +323 -0
- package/.agents/skills/developing-with-streamlit/skills/organizing-streamlit-code/SKILL.md +91 -0
- package/.agents/skills/developing-with-streamlit/skills/setting-up-streamlit-environment/SKILL.md +128 -0
- package/.agents/skills/developing-with-streamlit/skills/using-streamlit-cli/SKILL.md +165 -0
- package/.agents/skills/developing-with-streamlit/skills/using-streamlit-custom-components/SKILL.md +170 -0
- package/.agents/skills/developing-with-streamlit/skills/using-streamlit-layouts/SKILL.md +229 -0
- package/.agents/skills/developing-with-streamlit/skills/using-streamlit-markdown/SKILL.md +207 -0
- package/.agents/skills/developing-with-streamlit/skills/using-streamlit-session-state/SKILL.md +144 -0
- package/.agents/skills/developing-with-streamlit/templates/.gitattributes +3 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/README.md +188 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-companies/pyproject.toml +12 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-companies/streamlit_app.py +365 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute/pyproject.toml +12 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute/streamlit_app.py +461 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/.streamlit/secrets.toml.example +20 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/pyproject.toml +11 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/snowflake.yml +18 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/streamlit_app.py +527 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-feature-usage/pyproject.toml +12 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-feature-usage/streamlit_app.py +307 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics/pyproject.toml +12 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics/streamlit_app.py +426 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/.streamlit/secrets.toml.example +20 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/pyproject.toml +11 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/snowflake.yml +18 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/streamlit_app.py +463 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-seattle-weather/pyproject.toml +12 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-seattle-weather/streamlit_app.py +252 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers/pyproject.toml +12 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers/streamlit_app.py +342 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/.streamlit/secrets.toml.example +20 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/pyproject.toml +11 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/snowflake.yml +18 -0
- package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/streamlit_app.py +384 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/README.md +128 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/dracula.toml +39 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/github.toml +37 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/minimal.toml +39 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/nord.toml +39 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/snowflake.toml +42 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/solarized-light.toml +38 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/spotify.toml +34 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_configs/stripe.toml +35 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_shared/streamlit_app.py +336 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/_templates/pyproject.toml.tmpl +12 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/dracula/.streamlit/config.toml +39 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/dracula/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/dracula/streamlit_app.py +337 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/github/.streamlit/config.toml +37 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/github/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/github/streamlit_app.py +337 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/manage.py +332 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/minimal/.streamlit/config.toml +39 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/minimal/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/minimal/streamlit_app.py +337 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/nord/.streamlit/config.toml +39 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/nord/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/nord/streamlit_app.py +337 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/snowflake/.streamlit/config.toml +42 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/snowflake/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/snowflake/streamlit_app.py +337 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/solarized-light/.streamlit/config.toml +38 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/solarized-light/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/solarized-light/streamlit_app.py +337 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/spotify/.streamlit/config.toml +34 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/spotify/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/spotify/streamlit_app.py +337 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/stripe/.streamlit/config.toml +35 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/stripe/pyproject.toml +10 -0
- package/.agents/skills/developing-with-streamlit/templates/themes/stripe/streamlit_app.py +337 -0
- package/.agents/skills/fastapi/SKILL.md +436 -0
- package/.agents/skills/fastapi/references/dependencies.md +142 -0
- package/.agents/skills/fastapi/references/other-tools.md +76 -0
- package/.agents/skills/fastapi/references/streaming.md +105 -0
- package/.agents/skills/frontend-design/LICENSE.txt +177 -0
- package/.agents/skills/frontend-design/SKILL.md +42 -0
- package/.agents/skills/gradio/SKILL.md +84 -0
- package/.agents/skills/gradio/references/api-signatures.md +115 -0
- package/.agents/skills/gradio/references/event-listeners.md +130 -0
- package/.agents/skills/gradio/references/examples.md +613 -0
- package/.agents/skills/ui-ux-pro-max/SKILL.md +659 -0
- package/.agents/skills/ui-ux-pro-max/data +1 -0
- package/.agents/skills/ui-ux-pro-max/scripts +1 -0
- package/.env.axiom +8 -0
- package/AGENTS.md +2 -1
- package/README.md +19 -3
- package/bin/cli.js +11 -1
- package/opencode.json +7 -4
- package/package.json +1 -1
- package/skills-lock.json +36 -0
- package/.agents/skills/n8n-patterns/SKILL.md +0 -272
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Streamlit Element Explorer - Theme Demo
|
|
3
|
+
|
|
4
|
+
A comprehensive single-page app showcasing all major Streamlit components
|
|
5
|
+
with custom theming. Use this to preview how your theme looks across
|
|
6
|
+
different element types.
|
|
7
|
+
"""
|
|
8
|
+
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
import pandas as pd
|
|
12
|
+
import streamlit as st
|
|
13
|
+
|
|
14
|
+
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
|
|
15
|
+
|
|
16
|
+
# Initialize sample data in session state
|
|
17
|
+
if "chart_data" not in st.session_state:
|
|
18
|
+
np.random.seed(42)
|
|
19
|
+
st.session_state.chart_data = pd.DataFrame(
|
|
20
|
+
np.random.randn(20, 3), columns=["a", "b", "c"]
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
chart_data = st.session_state.chart_data
|
|
24
|
+
|
|
25
|
+
st.title("Streamlit Element Explorer")
|
|
26
|
+
st.markdown(
|
|
27
|
+
"Explore how Streamlit's built-in elements look with this theme. "
|
|
28
|
+
"Select a category below to preview different components."
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Navigation using segmented_control for better performance
|
|
32
|
+
section = st.segmented_control(
|
|
33
|
+
"Section",
|
|
34
|
+
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
|
|
35
|
+
default="Widgets",
|
|
36
|
+
label_visibility="collapsed",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
st.divider()
|
|
40
|
+
|
|
41
|
+
# -----------------------------------------------------------------------------
|
|
42
|
+
# WIDGETS SECTION
|
|
43
|
+
# -----------------------------------------------------------------------------
|
|
44
|
+
if section == "Widgets":
|
|
45
|
+
st.header("Widgets")
|
|
46
|
+
|
|
47
|
+
# Buttons
|
|
48
|
+
st.subheader("Buttons")
|
|
49
|
+
cols = st.columns(4)
|
|
50
|
+
cols[0].button("Primary", type="primary")
|
|
51
|
+
cols[1].button("Secondary", type="secondary")
|
|
52
|
+
cols[2].button("Tertiary", type="tertiary")
|
|
53
|
+
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
|
|
54
|
+
|
|
55
|
+
# Form
|
|
56
|
+
with st.form(key="demo_form"):
|
|
57
|
+
st.subheader("Form")
|
|
58
|
+
form_cols = st.columns(2)
|
|
59
|
+
form_cols[0].text_input("Name", placeholder="Enter your name")
|
|
60
|
+
form_cols[1].text_input("Email", placeholder="you@example.com")
|
|
61
|
+
st.form_submit_button("Submit", type="primary")
|
|
62
|
+
|
|
63
|
+
# Selection widgets
|
|
64
|
+
st.subheader("Selection Widgets")
|
|
65
|
+
sel_cols = st.columns(2)
|
|
66
|
+
|
|
67
|
+
with sel_cols[0]:
|
|
68
|
+
st.checkbox("Checkbox option")
|
|
69
|
+
st.toggle("Toggle switch")
|
|
70
|
+
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
|
|
71
|
+
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
|
|
72
|
+
|
|
73
|
+
with sel_cols[1]:
|
|
74
|
+
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
|
|
75
|
+
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
|
|
76
|
+
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
|
|
77
|
+
st.caption("Feedback widget")
|
|
78
|
+
st.feedback("stars")
|
|
79
|
+
|
|
80
|
+
# Numeric & Sliders
|
|
81
|
+
st.subheader("Numeric Inputs")
|
|
82
|
+
num_cols = st.columns(3)
|
|
83
|
+
num_cols[0].number_input("Number input", value=42)
|
|
84
|
+
num_cols[1].slider("Slider", 0, 100, 50)
|
|
85
|
+
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
|
|
86
|
+
|
|
87
|
+
# Date/Time
|
|
88
|
+
st.subheader("Date & Time")
|
|
89
|
+
dt_cols = st.columns(2)
|
|
90
|
+
dt_cols[0].date_input("Date input")
|
|
91
|
+
dt_cols[1].time_input("Time input")
|
|
92
|
+
|
|
93
|
+
# Text inputs
|
|
94
|
+
st.subheader("Text Inputs")
|
|
95
|
+
txt_cols = st.columns(2)
|
|
96
|
+
txt_cols[0].text_input("Text input", placeholder="Type something...")
|
|
97
|
+
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
|
|
98
|
+
|
|
99
|
+
# File upload
|
|
100
|
+
st.subheader("File Upload")
|
|
101
|
+
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
|
|
102
|
+
|
|
103
|
+
# -----------------------------------------------------------------------------
|
|
104
|
+
# DATA SECTION
|
|
105
|
+
# -----------------------------------------------------------------------------
|
|
106
|
+
elif section == "Data":
|
|
107
|
+
st.header("Data Display")
|
|
108
|
+
|
|
109
|
+
# Metrics
|
|
110
|
+
st.subheader("Metrics")
|
|
111
|
+
m_cols = st.columns(4)
|
|
112
|
+
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
|
|
113
|
+
m_cols[1].metric("Users", "2,847", "+8.2%")
|
|
114
|
+
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
|
|
115
|
+
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
|
|
116
|
+
|
|
117
|
+
st.divider()
|
|
118
|
+
|
|
119
|
+
# Dataframe
|
|
120
|
+
st.subheader("Dataframe")
|
|
121
|
+
df = pd.DataFrame({
|
|
122
|
+
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
|
|
123
|
+
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
|
|
124
|
+
"Salary": [95000, 78000, 82000, 105000, 71000],
|
|
125
|
+
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
|
|
126
|
+
"Active": [True, True, False, True, True],
|
|
127
|
+
})
|
|
128
|
+
st.dataframe(
|
|
129
|
+
df,
|
|
130
|
+
hide_index=True,
|
|
131
|
+
column_config={
|
|
132
|
+
"Salary": st.column_config.NumberColumn(format="$%d"),
|
|
133
|
+
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
|
|
134
|
+
"Active": st.column_config.CheckboxColumn("Active?"),
|
|
135
|
+
},
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Table
|
|
139
|
+
st.subheader("Static Table")
|
|
140
|
+
st.table(chart_data.head(5))
|
|
141
|
+
|
|
142
|
+
# JSON
|
|
143
|
+
st.subheader("JSON Display")
|
|
144
|
+
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
|
|
145
|
+
|
|
146
|
+
# -----------------------------------------------------------------------------
|
|
147
|
+
# CHARTS SECTION
|
|
148
|
+
# -----------------------------------------------------------------------------
|
|
149
|
+
elif section == "Charts":
|
|
150
|
+
st.header("Charts")
|
|
151
|
+
|
|
152
|
+
chart_cols = st.columns(2)
|
|
153
|
+
|
|
154
|
+
with chart_cols[0]:
|
|
155
|
+
st.subheader("Line Chart")
|
|
156
|
+
st.line_chart(chart_data, height=250)
|
|
157
|
+
|
|
158
|
+
st.subheader("Bar Chart")
|
|
159
|
+
st.bar_chart(chart_data, height=250)
|
|
160
|
+
|
|
161
|
+
with chart_cols[1]:
|
|
162
|
+
st.subheader("Area Chart")
|
|
163
|
+
st.area_chart(chart_data, height=250)
|
|
164
|
+
|
|
165
|
+
st.subheader("Scatter Chart")
|
|
166
|
+
st.scatter_chart(chart_data, height=250)
|
|
167
|
+
|
|
168
|
+
# -----------------------------------------------------------------------------
|
|
169
|
+
# TEXT SECTION
|
|
170
|
+
# -----------------------------------------------------------------------------
|
|
171
|
+
elif section == "Text":
|
|
172
|
+
st.header("Text Elements")
|
|
173
|
+
|
|
174
|
+
# Headers
|
|
175
|
+
st.subheader("Headers")
|
|
176
|
+
st.title("Title Element")
|
|
177
|
+
st.header("Header Element")
|
|
178
|
+
st.subheader("Subheader Element")
|
|
179
|
+
st.caption("Caption text - smaller, muted")
|
|
180
|
+
|
|
181
|
+
st.divider()
|
|
182
|
+
|
|
183
|
+
# Markdown
|
|
184
|
+
st.subheader("Markdown Formatting")
|
|
185
|
+
st.markdown(
|
|
186
|
+
"**Bold text**, *italic text*, ~~strikethrough~~, "
|
|
187
|
+
"`inline code`, [link](https://streamlit.io)"
|
|
188
|
+
)
|
|
189
|
+
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
|
|
190
|
+
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
|
|
191
|
+
|
|
192
|
+
# Colored text
|
|
193
|
+
st.subheader("Colored Text")
|
|
194
|
+
color_cols = st.columns(3)
|
|
195
|
+
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
|
|
196
|
+
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
|
|
197
|
+
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
|
|
198
|
+
|
|
199
|
+
# Code blocks
|
|
200
|
+
st.subheader("Code Block")
|
|
201
|
+
st.code(
|
|
202
|
+
'''import streamlit as st
|
|
203
|
+
|
|
204
|
+
# Create a themed dashboard
|
|
205
|
+
st.set_page_config(page_title="My App", layout="wide")
|
|
206
|
+
st.title("Hello, Streamlit!")
|
|
207
|
+
|
|
208
|
+
# Display metrics
|
|
209
|
+
col1, col2 = st.columns(2)
|
|
210
|
+
col1.metric("Users", "1,234", "+5%")
|
|
211
|
+
col2.metric("Revenue", "$56K", "+12%")''',
|
|
212
|
+
language="python",
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
# -----------------------------------------------------------------------------
|
|
216
|
+
# LAYOUTS SECTION
|
|
217
|
+
# -----------------------------------------------------------------------------
|
|
218
|
+
elif section == "Layouts":
|
|
219
|
+
st.header("Layout Elements")
|
|
220
|
+
|
|
221
|
+
# Columns
|
|
222
|
+
st.subheader("Columns with Borders")
|
|
223
|
+
layout_cols = st.columns(3, border=True)
|
|
224
|
+
layout_cols[0].write("**Column 1**\n\nFirst column content")
|
|
225
|
+
layout_cols[1].write("**Column 2**\n\nSecond column content")
|
|
226
|
+
layout_cols[2].write("**Column 3**\n\nThird column content")
|
|
227
|
+
|
|
228
|
+
# Tabs
|
|
229
|
+
st.subheader("Tabs")
|
|
230
|
+
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
|
|
231
|
+
with tab1:
|
|
232
|
+
st.write("Chart tab content")
|
|
233
|
+
st.line_chart(chart_data["a"], height=150)
|
|
234
|
+
with tab2:
|
|
235
|
+
st.write("Data tab content")
|
|
236
|
+
st.dataframe(chart_data.head(3))
|
|
237
|
+
with tab3:
|
|
238
|
+
st.write("Settings tab content")
|
|
239
|
+
st.checkbox("Enable feature X")
|
|
240
|
+
st.checkbox("Enable feature Y", value=True)
|
|
241
|
+
|
|
242
|
+
# Expander
|
|
243
|
+
st.subheader("Expander")
|
|
244
|
+
with st.expander("Click to expand"):
|
|
245
|
+
st.write("This content is hidden by default.")
|
|
246
|
+
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
|
|
247
|
+
|
|
248
|
+
# Popover
|
|
249
|
+
st.subheader("Popover")
|
|
250
|
+
pop_cols = st.columns(3)
|
|
251
|
+
with pop_cols[0].popover("Open popover", icon=":material/info:"):
|
|
252
|
+
st.write("Popover content here!")
|
|
253
|
+
st.slider("Popover slider", 0, 100, 50)
|
|
254
|
+
|
|
255
|
+
# Container
|
|
256
|
+
st.subheader("Container with Border")
|
|
257
|
+
with st.container(border=True):
|
|
258
|
+
st.write("**Bordered Container**")
|
|
259
|
+
st.write("Content inside a container with a visible border.")
|
|
260
|
+
st.button("Button inside container")
|
|
261
|
+
|
|
262
|
+
# -----------------------------------------------------------------------------
|
|
263
|
+
# CHAT SECTION
|
|
264
|
+
# -----------------------------------------------------------------------------
|
|
265
|
+
elif section == "Chat":
|
|
266
|
+
st.header("Chat Elements")
|
|
267
|
+
|
|
268
|
+
# Chat messages
|
|
269
|
+
st.subheader("Chat Messages")
|
|
270
|
+
with st.chat_message("user"):
|
|
271
|
+
st.write("Hello! How can I analyze my sales data?")
|
|
272
|
+
|
|
273
|
+
with st.chat_message("assistant"):
|
|
274
|
+
st.write("I can help you with that! Here are a few options:")
|
|
275
|
+
st.markdown("""
|
|
276
|
+
1. **Revenue trends** - View monthly/quarterly patterns
|
|
277
|
+
2. **Top products** - Identify best sellers
|
|
278
|
+
3. **Customer segments** - Analyze by region or category
|
|
279
|
+
""")
|
|
280
|
+
|
|
281
|
+
with st.chat_message("user"):
|
|
282
|
+
st.write("Show me the revenue trends please.")
|
|
283
|
+
|
|
284
|
+
with st.chat_message("assistant"):
|
|
285
|
+
st.write("Here's your revenue trend for the past 20 periods:")
|
|
286
|
+
st.line_chart(chart_data["a"], height=200)
|
|
287
|
+
|
|
288
|
+
# Chat input
|
|
289
|
+
st.chat_input("Type a message...")
|
|
290
|
+
|
|
291
|
+
# -----------------------------------------------------------------------------
|
|
292
|
+
# STATUS SECTION
|
|
293
|
+
# -----------------------------------------------------------------------------
|
|
294
|
+
elif section == "Status":
|
|
295
|
+
st.header("Status Elements")
|
|
296
|
+
|
|
297
|
+
# Alert messages
|
|
298
|
+
st.subheader("Alert Messages")
|
|
299
|
+
st.error("Error: Something went wrong with the data pipeline.")
|
|
300
|
+
st.warning("Warning: API rate limit approaching (80% used).")
|
|
301
|
+
st.info("Info: New features available in the latest release.")
|
|
302
|
+
st.success("Success: Data exported successfully to warehouse.")
|
|
303
|
+
|
|
304
|
+
# Exception
|
|
305
|
+
st.subheader("Exception Display")
|
|
306
|
+
try:
|
|
307
|
+
raise ValueError("This is an example exception for demonstration")
|
|
308
|
+
except ValueError as e:
|
|
309
|
+
st.exception(e)
|
|
310
|
+
|
|
311
|
+
# Interactive status
|
|
312
|
+
st.subheader("Interactive Status")
|
|
313
|
+
status_cols = st.columns(3)
|
|
314
|
+
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
|
|
315
|
+
st.toast("This is a toast notification!", icon="🔔")
|
|
316
|
+
if status_cols[1].button("Balloons", icon=":material/celebration:"):
|
|
317
|
+
st.balloons()
|
|
318
|
+
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
|
|
319
|
+
st.snow()
|
|
320
|
+
|
|
321
|
+
# Progress
|
|
322
|
+
st.subheader("Progress Indicators")
|
|
323
|
+
st.progress(0.7, text="70% complete")
|
|
324
|
+
with st.spinner("Loading..."):
|
|
325
|
+
st.write("Spinner is active (non-blocking in this demo)")
|
|
326
|
+
|
|
327
|
+
# -----------------------------------------------------------------------------
|
|
328
|
+
# SIDEBAR
|
|
329
|
+
# -----------------------------------------------------------------------------
|
|
330
|
+
with st.sidebar:
|
|
331
|
+
st.header("Settings")
|
|
332
|
+
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
|
|
333
|
+
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
|
|
334
|
+
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
|
|
335
|
+
st.divider()
|
|
336
|
+
st.caption("Element Explorer v1.0")
|
|
337
|
+
st.caption("Theme: **GitHub**")
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Manage theme template directories (fully generated from _configs/).
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python manage.py sync # Regenerate all theme directories
|
|
6
|
+
python manage.py check # Verify generated files haven't drifted
|
|
7
|
+
python manage.py new NAME # Scaffold a new theme config
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import ast
|
|
11
|
+
import re
|
|
12
|
+
import shutil
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
ROOT = Path(__file__).parent
|
|
17
|
+
SHARED = ROOT / "_shared"
|
|
18
|
+
TEMPLATES = ROOT / "_templates"
|
|
19
|
+
CONFIGS = ROOT / "_configs"
|
|
20
|
+
FONTS = SHARED / "fonts"
|
|
21
|
+
|
|
22
|
+
MANAGED_HEADER_PY = (
|
|
23
|
+
"# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead\n"
|
|
24
|
+
)
|
|
25
|
+
MANAGED_HEADER_TOML = (
|
|
26
|
+
"# DO NOT EDIT — managed by manage.py, edit _configs/{slug}.toml instead\n"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
GITATTR_START = "# BEGIN managed by manage.py"
|
|
30
|
+
GITATTR_END = "# END managed by manage.py"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
# Theme discovery
|
|
35
|
+
# ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
TITLE_OVERRIDES = {"github": "GitHub"}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def slug_to_title(slug):
|
|
41
|
+
"""Derive a display title from a directory slug: 'solarized-light' -> 'Solarized Light'."""
|
|
42
|
+
if slug in TITLE_OVERRIDES:
|
|
43
|
+
return TITLE_OVERRIDES[slug]
|
|
44
|
+
return " ".join(w.capitalize() for w in slug.split("-"))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def discover_themes():
|
|
48
|
+
"""Find themes by scanning _configs/*.toml."""
|
|
49
|
+
return [
|
|
50
|
+
{"slug": c.stem, "title": slug_to_title(c.stem)}
|
|
51
|
+
for c in sorted(CONFIGS.glob("*.toml"))
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# ---------------------------------------------------------------------------
|
|
56
|
+
# Font discovery from config content
|
|
57
|
+
# ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
def discover_fonts(config_text):
|
|
60
|
+
"""Extract font filenames referenced in config.toml content."""
|
|
61
|
+
return re.findall(r'url\s*=\s*["\']app/static/([^"\']+\.(?:ttf|otf|woff2?))["\']', config_text)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ---------------------------------------------------------------------------
|
|
65
|
+
# Content builders
|
|
66
|
+
# ---------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
def expected_app(title):
|
|
69
|
+
"""Build expected streamlit_app.py content for a theme."""
|
|
70
|
+
source = (SHARED / "streamlit_app.py").read_text()
|
|
71
|
+
body = source.replace("{{title}}", title)
|
|
72
|
+
# Insert managed header after the module docstring
|
|
73
|
+
tree = ast.parse(body)
|
|
74
|
+
if ast.get_docstring(tree) is not None:
|
|
75
|
+
# The docstring is the first statement; find end of its line
|
|
76
|
+
docstring_node = tree.body[0]
|
|
77
|
+
end_line = docstring_node.end_lineno # 1-indexed
|
|
78
|
+
lines = body.split("\n")
|
|
79
|
+
insert_pos = end_line
|
|
80
|
+
return "\n".join(lines[:insert_pos]) + "\n" + MANAGED_HEADER_PY + "\n".join(lines[insert_pos:])
|
|
81
|
+
return MANAGED_HEADER_PY + body
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def expected_config(slug):
|
|
85
|
+
"""Build expected .streamlit/config.toml content for a theme."""
|
|
86
|
+
source = (CONFIGS / f"{slug}.toml").read_text()
|
|
87
|
+
header = MANAGED_HEADER_TOML.replace("{slug}", slug)
|
|
88
|
+
return header + source
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def expected_from_template(tmpl_path, replacements):
|
|
92
|
+
"""Build expected file content from a .tmpl template."""
|
|
93
|
+
text = tmpl_path.read_text()
|
|
94
|
+
for key, value in replacements.items():
|
|
95
|
+
text = text.replace("{{" + key + "}}", value)
|
|
96
|
+
return text
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# ---------------------------------------------------------------------------
|
|
100
|
+
# Sync
|
|
101
|
+
# ---------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
def sync_theme(theme):
|
|
104
|
+
"""Regenerate all files for a single theme directory."""
|
|
105
|
+
slug = theme["slug"]
|
|
106
|
+
title = theme["title"]
|
|
107
|
+
identifier = slug.replace("-", "_")
|
|
108
|
+
theme_dir = ROOT / slug
|
|
109
|
+
|
|
110
|
+
# Create directories
|
|
111
|
+
theme_dir.mkdir(exist_ok=True)
|
|
112
|
+
(theme_dir / ".streamlit").mkdir(exist_ok=True)
|
|
113
|
+
(theme_dir / "static").mkdir(exist_ok=True)
|
|
114
|
+
|
|
115
|
+
# .streamlit/config.toml — from _configs/
|
|
116
|
+
(theme_dir / ".streamlit" / "config.toml").write_text(expected_config(slug))
|
|
117
|
+
|
|
118
|
+
# streamlit_app.py
|
|
119
|
+
(theme_dir / "streamlit_app.py").write_text(expected_app(title))
|
|
120
|
+
|
|
121
|
+
# pyproject.toml
|
|
122
|
+
(theme_dir / "pyproject.toml").write_text(
|
|
123
|
+
expected_from_template(
|
|
124
|
+
TEMPLATES / "pyproject.toml.tmpl",
|
|
125
|
+
{"slug": slug, "title": title},
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# snowflake.yml
|
|
130
|
+
(theme_dir / "snowflake.yml").write_text(
|
|
131
|
+
expected_from_template(
|
|
132
|
+
TEMPLATES / "snowflake.yml.tmpl",
|
|
133
|
+
{"slug": slug, "title": title, "identifier": identifier},
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Fonts — copy from _shared/fonts/ based on config references
|
|
138
|
+
config_text = (CONFIGS / f"{slug}.toml").read_text()
|
|
139
|
+
font_names = discover_fonts(config_text)
|
|
140
|
+
static_dir = theme_dir / "static"
|
|
141
|
+
for fname in font_names:
|
|
142
|
+
src = FONTS / fname
|
|
143
|
+
if not src.exists():
|
|
144
|
+
print(f" Warning: font {fname} referenced in _configs/{slug}.toml not found in _shared/fonts/", file=sys.stderr)
|
|
145
|
+
continue
|
|
146
|
+
shutil.copy2(src, static_dir / fname)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def update_gitattributes():
|
|
150
|
+
"""Update .gitattributes with entries for generated theme files."""
|
|
151
|
+
gitattr_path = ROOT / ".gitattributes"
|
|
152
|
+
|
|
153
|
+
new_section = "\n".join([
|
|
154
|
+
GITATTR_START,
|
|
155
|
+
"*/.streamlit/config.toml linguist-generated",
|
|
156
|
+
"*/streamlit_app.py linguist-generated",
|
|
157
|
+
"*/pyproject.toml linguist-generated",
|
|
158
|
+
"*/snowflake.yml linguist-generated",
|
|
159
|
+
"*/static/*.ttf linguist-generated",
|
|
160
|
+
GITATTR_END,
|
|
161
|
+
])
|
|
162
|
+
|
|
163
|
+
if gitattr_path.exists():
|
|
164
|
+
content = gitattr_path.read_text()
|
|
165
|
+
if GITATTR_START in content:
|
|
166
|
+
start = content.index(GITATTR_START)
|
|
167
|
+
end = content.index(GITATTR_END) + len(GITATTR_END)
|
|
168
|
+
content = content[:start] + new_section + content[end:]
|
|
169
|
+
else:
|
|
170
|
+
content = content.rstrip() + "\n\n" + new_section + "\n"
|
|
171
|
+
else:
|
|
172
|
+
content = new_section + "\n"
|
|
173
|
+
|
|
174
|
+
gitattr_path.write_text(content)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def cmd_sync():
|
|
178
|
+
themes = discover_themes()
|
|
179
|
+
for t in themes:
|
|
180
|
+
sync_theme(t)
|
|
181
|
+
print(f" Synced {t['slug']}/")
|
|
182
|
+
|
|
183
|
+
# Remove orphaned theme directories (directories not matching any config)
|
|
184
|
+
config_slugs = {t["slug"] for t in themes}
|
|
185
|
+
orphans = [
|
|
186
|
+
d for d in sorted(ROOT.iterdir())
|
|
187
|
+
if d.is_dir() and not d.name.startswith("_") and d.name not in config_slugs
|
|
188
|
+
]
|
|
189
|
+
if orphans:
|
|
190
|
+
print("\nOrphaned directories (no matching config):")
|
|
191
|
+
for d in orphans:
|
|
192
|
+
print(f" {d.name}/")
|
|
193
|
+
answer = input("Remove these directories? [y/N] ").strip().lower()
|
|
194
|
+
if answer == "y":
|
|
195
|
+
for d in orphans:
|
|
196
|
+
shutil.rmtree(d)
|
|
197
|
+
print(f" Removed {d.name}/")
|
|
198
|
+
else:
|
|
199
|
+
print(" Skipped orphan removal.")
|
|
200
|
+
|
|
201
|
+
update_gitattributes()
|
|
202
|
+
print(f"\nSynced {len(themes)} theme directories.")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# ---------------------------------------------------------------------------
|
|
206
|
+
# Check
|
|
207
|
+
# ---------------------------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
def cmd_check():
|
|
210
|
+
themes = discover_themes()
|
|
211
|
+
drifted = []
|
|
212
|
+
missing = []
|
|
213
|
+
|
|
214
|
+
for theme in themes:
|
|
215
|
+
slug = theme["slug"]
|
|
216
|
+
title = theme["title"]
|
|
217
|
+
identifier = slug.replace("-", "_")
|
|
218
|
+
theme_dir = ROOT / slug
|
|
219
|
+
|
|
220
|
+
# .streamlit/config.toml
|
|
221
|
+
target = theme_dir / ".streamlit" / "config.toml"
|
|
222
|
+
expected = expected_config(slug)
|
|
223
|
+
if not target.exists():
|
|
224
|
+
missing.append(f"{slug}/.streamlit/config.toml")
|
|
225
|
+
elif target.read_text() != expected:
|
|
226
|
+
drifted.append(f"{slug}/.streamlit/config.toml")
|
|
227
|
+
|
|
228
|
+
# streamlit_app.py
|
|
229
|
+
target = theme_dir / "streamlit_app.py"
|
|
230
|
+
if not target.exists():
|
|
231
|
+
missing.append(f"{slug}/streamlit_app.py")
|
|
232
|
+
elif target.read_text() != expected_app(title):
|
|
233
|
+
drifted.append(f"{slug}/streamlit_app.py")
|
|
234
|
+
|
|
235
|
+
# pyproject.toml
|
|
236
|
+
target = theme_dir / "pyproject.toml"
|
|
237
|
+
expected = expected_from_template(
|
|
238
|
+
TEMPLATES / "pyproject.toml.tmpl",
|
|
239
|
+
{"slug": slug, "title": title},
|
|
240
|
+
)
|
|
241
|
+
if not target.exists():
|
|
242
|
+
missing.append(f"{slug}/pyproject.toml")
|
|
243
|
+
elif target.read_text() != expected:
|
|
244
|
+
drifted.append(f"{slug}/pyproject.toml")
|
|
245
|
+
|
|
246
|
+
# snowflake.yml
|
|
247
|
+
target = theme_dir / "snowflake.yml"
|
|
248
|
+
expected = expected_from_template(
|
|
249
|
+
TEMPLATES / "snowflake.yml.tmpl",
|
|
250
|
+
{"slug": slug, "title": title, "identifier": identifier},
|
|
251
|
+
)
|
|
252
|
+
if not target.exists():
|
|
253
|
+
missing.append(f"{slug}/snowflake.yml")
|
|
254
|
+
elif target.read_text() != expected:
|
|
255
|
+
drifted.append(f"{slug}/snowflake.yml")
|
|
256
|
+
|
|
257
|
+
# Fonts
|
|
258
|
+
config_text = (CONFIGS / f"{slug}.toml").read_text()
|
|
259
|
+
font_names = discover_fonts(config_text)
|
|
260
|
+
for fname in font_names:
|
|
261
|
+
src = FONTS / fname
|
|
262
|
+
dest = theme_dir / "static" / fname
|
|
263
|
+
if not dest.exists():
|
|
264
|
+
missing.append(f"{slug}/static/{fname}")
|
|
265
|
+
elif src.exists() and src.read_bytes() != dest.read_bytes():
|
|
266
|
+
drifted.append(f"{slug}/static/{fname}")
|
|
267
|
+
|
|
268
|
+
ok = True
|
|
269
|
+
if missing:
|
|
270
|
+
print("Missing files (run 'python manage.py sync' to fix):")
|
|
271
|
+
for f in missing:
|
|
272
|
+
print(f" {f}")
|
|
273
|
+
ok = False
|
|
274
|
+
if drifted:
|
|
275
|
+
print("Drifted files (run 'python manage.py sync' to fix):")
|
|
276
|
+
for f in drifted:
|
|
277
|
+
print(f" {f}")
|
|
278
|
+
ok = False
|
|
279
|
+
if ok:
|
|
280
|
+
print(f"All generated files in sync across {len(themes)} theme directories.")
|
|
281
|
+
else:
|
|
282
|
+
sys.exit(1)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
# ---------------------------------------------------------------------------
|
|
286
|
+
# New
|
|
287
|
+
# ---------------------------------------------------------------------------
|
|
288
|
+
|
|
289
|
+
def cmd_new(name):
|
|
290
|
+
config_path = CONFIGS / f"{name}.toml"
|
|
291
|
+
if config_path.exists():
|
|
292
|
+
print(f"Error: _configs/{name}.toml already exists", file=sys.stderr)
|
|
293
|
+
sys.exit(1)
|
|
294
|
+
|
|
295
|
+
config_path.write_text(
|
|
296
|
+
f"[server]\nenableStaticServing = true\n\n"
|
|
297
|
+
f"# {name} theme\n[theme]\nbase = \"dark\"\n"
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
print(f"Created _configs/{name}.toml — edit it, then run 'python manage.py sync'")
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# ---------------------------------------------------------------------------
|
|
304
|
+
# CLI
|
|
305
|
+
# ---------------------------------------------------------------------------
|
|
306
|
+
|
|
307
|
+
if __name__ == "__main__":
|
|
308
|
+
if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help"):
|
|
309
|
+
print(__doc__.strip())
|
|
310
|
+
sys.exit(0 if len(sys.argv) > 1 else 1)
|
|
311
|
+
|
|
312
|
+
if not SHARED.is_dir():
|
|
313
|
+
print(f"Error: {SHARED} not found", file=sys.stderr)
|
|
314
|
+
sys.exit(1)
|
|
315
|
+
|
|
316
|
+
if not CONFIGS.is_dir():
|
|
317
|
+
print(f"Error: {CONFIGS} not found", file=sys.stderr)
|
|
318
|
+
sys.exit(1)
|
|
319
|
+
|
|
320
|
+
cmd = sys.argv[1]
|
|
321
|
+
if cmd == "sync":
|
|
322
|
+
cmd_sync()
|
|
323
|
+
elif cmd == "new":
|
|
324
|
+
if len(sys.argv) < 3:
|
|
325
|
+
print("Usage: python manage.py new NAME", file=sys.stderr)
|
|
326
|
+
sys.exit(1)
|
|
327
|
+
cmd_new(sys.argv[2])
|
|
328
|
+
elif cmd == "check":
|
|
329
|
+
cmd_check()
|
|
330
|
+
else:
|
|
331
|
+
print(f"Unknown command: {cmd}", file=sys.stderr)
|
|
332
|
+
sys.exit(1)
|