Skip to content

Commit

Permalink
Update gallery
Browse files Browse the repository at this point in the history
- Introduce Streamlit Elements demo
- Rework how pages are handled and reorganize directories
- Remove discourse as it does not work anymore with Streamlit Cloud
  • Loading branch information
okld committed Mar 14, 2022
1 parent 1ed3920 commit c689dc4
Show file tree
Hide file tree
Showing 29 changed files with 586 additions and 62 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 🎉 Welcome to my Streamlit Gallery!
# 🎉 Streamlit Gallery

[![Open in Streamlit][share_badge]][share_link] [![GitHub][github_badge]][github_link]

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Core
streamlit==1.1.0
streamlit

# Streamlit components
streamlit-ace
Expand Down
59 changes: 13 additions & 46 deletions streamlit_app.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,26 @@
import streamlit as st
from typing import Callable
from streamlit_gallery import apps, components

PAGE_PARAM = "p"
CONTENT = {
"Applications": {
"Streamlit gallery": apps.gallery,
},
"Components": {
"Ace editor": components.ace_editor,
"Discourse": components.discourse,
"Disqus": components.disqus,
"Pandas profiling": components.pandas_profiling,
"Quill editor": components.quill_editor,
"React player": components.react_player,
},
}

from streamlit_gallery import apps, components
from streamlit_gallery.utils.page import page_group

def main():
query_params = st.experimental_get_query_params()
page_param = query_params[PAGE_PARAM][0] if PAGE_PARAM in query_params else "streamlit-gallery"
page_selected = None
page = page_group("p")

with st.sidebar:
st.title("🎈 Okld's Gallery")
st.write("")

for category_name, pages in CONTENT.items():
category_expander = st.sidebar.expander(category_name.upper(), expanded=True)

for page_name, page_function in pages.items():
page_key = page_name.replace(" ", "-").lower()

st.session_state[page_key] = (page_key == page_param)

if category_expander.checkbox(
page_name, False,
key=page_key,
on_change=select_page,
args=[page_key]
):
page_selected = page_function

if isinstance(page_selected, Callable):
page_selected()


def select_page(page_key):
if page_key in st.session_state and st.session_state[page_key]:
query_params = st.experimental_get_query_params()
query_params[PAGE_PARAM] = page_key
with st.expander("✨ APPS", True):
page.item("Streamlit gallery", apps.gallery, default=True)

st.experimental_set_query_params(**query_params)
with st.expander("🧩 COMPONENTS", True):
page.item("Ace editor", components.ace_editor)
page.item("Disqus", components.disqus)
page.item("Elements⭐", components.elements)
page.item("Pandas profiling", components.pandas_profiling)
page.item("Quill editor", components.quill_editor)
page.item("React player", components.react_player)

page.show()

if __name__ == "__main__":
st.set_page_config(page_title="Streamlit Gallery by Okld", page_icon="🎈", layout="wide")
Expand Down
13 changes: 7 additions & 6 deletions streamlit_gallery/components/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .ace_editor import main as ace_editor
from .discourse import main as discourse
from .disqus import main as disqus
from .pandas_profiling import main as pandas_profiling
from .quill_editor import main as quill_editor
from .react_player import main as react_player
from .ace_editor.streamlit_app import main as ace_editor
from .discourse.streamlit_app import main as discourse
from .disqus.streamlit_app import main as disqus
from .elements.streamlit_app import main as elements
from .pandas_profiling.streamlit_app import main as pandas_profiling
from .quill_editor.streamlit_app import main as quill_editor
from .react_player.streamlit_app import main as react_player
Empty file.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import streamlit as st

from streamlit_ace import st_ace, KEYBINDINGS, LANGUAGES, THEMES
from streamlit_gallery.utils import readme
from streamlit_gallery.utils.readme import readme


def main():
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import streamlit as st

from streamlit_discourse import st_discourse
from streamlit_gallery.utils import readme
from streamlit_gallery.utils.readme import readme


def main():
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import streamlit as st

from streamlit_disqus import st_disqus
from streamlit_gallery.utils import readme
from streamlit_gallery.utils.readme import readme


def main():
Expand Down
Empty file.
7 changes: 7 additions & 0 deletions streamlit_gallery/components/elements/dashboard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from .card import Card
from .dashboard import Dashboard
from .datagrid import DataGrid
from .editor import Editor
from .pie import Pie
from .player import Player
from .radar import Radar
34 changes: 34 additions & 0 deletions streamlit_gallery/components/elements/dashboard/card.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from streamlit_elements import mui
from .dashboard import Dashboard


class Card(Dashboard.Item):

DEFAULT_CONTENT = (
"This impressive paella is a perfect party dish and a fun meal to cook "
"together with your guests. Add 1 cup of frozen peas along with the mussels, "
"if you like."
)

def __call__(self, content):
with mui.card(key=self._key, sx={"display": "flex", "flexDirection": "column"}, elevation=3):
mui.card_header(
title="Shrimp and Chorizo Paella",
subheader="September 14, 2016",
avatar=mui.avatar("R", sx={"bgcolor": "red"}),
action=mui.icon_button(mui.icon.more_vert),
class_name=self._draggable_class,
)
mui.card_media(
component="img",
height=194,
image="https://mui.com/static/images/cards/paella.jpg",
alt="Paella dish",
)

with mui.card_content(sx={"flex": 1}):
mui.typography(content)

with mui.card_actions(disable_spacing=True):
mui.icon_button(mui.icon.favorite)
mui.icon_button(mui.icon.share)
56 changes: 56 additions & 0 deletions streamlit_gallery/components/elements/dashboard/dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from uuid import uuid4
from abc import ABC, abstractmethod
from streamlit_elements import dashboard, mui
from contextlib import contextmanager


class Dashboard:

DRAGGABLE_CLASS = "draggable"

_layout = []

@contextmanager
def __call__(self, **grid_props):
# Draggable classname query selector.
grid_props["draggable_handle"] = f".{Dashboard.DRAGGABLE_CLASS}"

with dashboard(Dashboard._layout, **grid_props):
yield

class Item(ABC):

def __init__(self, x, y, w, h, **item_props):
self._key = str(uuid4())
self._draggable_class = Dashboard.DRAGGABLE_CLASS
self._dark_mode = True
Dashboard._layout.append(dashboard.item(self._key, x, y, w, h, **item_props))

def _switch_theme(self):
self._dark_mode = not self._dark_mode

@contextmanager
def title_bar(self, padding="5px 15px 5px 15px", dark_switcher=True):
with mui.stack(
class_name=self._draggable_class,
align_items="center",
direction="row",
spacing=1,
sx={
"padding": padding,
"borderBottom": 1,
"borderColor": "divider",
},
):
yield

if dark_switcher:
if self._dark_mode:
mui.icon_button(mui.icon.dark_mode, on_click=self._switch_theme)
else:
mui.icon_button(mui.icon.light_mode, sx={"color": "#ffc107"}, on_click=self._switch_theme)

@abstractmethod
def __call__(self):
"""Show elements."""
raise NotImplementedError
47 changes: 47 additions & 0 deletions streamlit_gallery/components/elements/dashboard/datagrid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import json

from streamlit_elements import mui
from .dashboard import Dashboard


class DataGrid(Dashboard.Item):

DEFAULT_COLUMNS = [
{ "field": 'id', "headerName": 'ID', "width": 90 },
{ "field": 'firstName', "headerName": 'First name', "width": 150, "editable": True, },
{ "field": 'lastName', "headerName": 'Last name', "width": 150, "editable": True, },
{ "field": 'age', "headerName": 'Age', "type": 'number', "width": 110, "editable": True, },
]
DEFAULT_ROWS = [
{ "id": 1, "lastName": 'Snow', "firstName": 'Jon', "age": 35 },
{ "id": 2, "lastName": 'Lannister', "firstName": 'Cersei', "age": 42 },
{ "id": 3, "lastName": 'Lannister', "firstName": 'Jaime', "age": 45 },
{ "id": 4, "lastName": 'Stark', "firstName": 'Arya', "age": 16 },
{ "id": 5, "lastName": 'Targaryen', "firstName": 'Daenerys', "age": None },
{ "id": 6, "lastName": 'Melisandre', "firstName": None, "age": 150 },
{ "id": 7, "lastName": 'Clifford', "firstName": 'Ferrara', "age": 44 },
{ "id": 8, "lastName": 'Frances', "firstName": 'Rossini', "age": 36 },
{ "id": 9, "lastName": 'Roxie', "firstName": 'Harvey', "age": 65 },
]

def _handle_edit(self, params):
print(params)

def __call__(self, json_data):
data = json.loads(json_data)

with mui.paper(key=self._key, sx={"display": "flex", "flexDirection": "column"}, elevation=3):
with self.title_bar(padding="10px 15px 10px 15px", dark_switcher=False):
mui.icon.ondemand_video()
mui.typography("Data grid")

with mui.box(sx={"flex": 1, "minHeight": 0}):
mui.data_grid(
columns=self.DEFAULT_COLUMNS,
rows=data,
page_size=5,
rows_per_page_options=[5],
checkbox_selection=True,
disable_selection_on_click=True,
on_cell_edit_commit=self._handle_edit,
)
59 changes: 59 additions & 0 deletions streamlit_gallery/components/elements/dashboard/editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from functools import partial
from streamlit_elements import mui, monaco, sync, lazy
from .dashboard import Dashboard


class Editor(Dashboard.Item):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self._dark_theme = False
self._index = 0
self._tabs = {}
self._editor_box_style = {
"flex": 1,
"minHeight": 0,
"borderBottom": 1,
"borderTop": 1,
"borderColor": "divider"
}

def _change_tab(self, _, index):
self._index = index

def update_content(self, label, content):
self._tabs[label]["content"] = content

def add_tab(self, label, default_content, language):
self._tabs[label] = { "content": default_content, "language": language }

def get_content(self, label):
return self._tabs[label]["content"]

def __call__(self):
with mui.paper(key=self._key, sx={"display": "flex", "flexDirection": "column"}, elevation=3):

with self.title_bar("0px 15px 0px 15px"):
mui.icon.terminal()
mui.typography("Editor")

with mui.tabs(value=self._index, on_change=self._change_tab, scroll_buttons=True, variant="scrollable", sx={"flex": 1}):
for label in self._tabs.keys():
mui.tab(label=label)

for index, (label, tab) in enumerate(self._tabs.items()):
with mui.box(sx=self._editor_box_style, hidden=(index != self._index)):
monaco.editor(
default_value=tab["content"],
language=tab["language"],
on_change=lazy(partial(self.update_content, label)),
theme="vs-dark" if self._dark_mode else "light",
options={
"wordWrap": True
}
)

with mui.stack(direction="row", spacing=2, align_items="center", sx={"padding": "10px"}):
mui.button("Apply", variant="contained", on_click=sync())
mui.typography("Or press ctrl+s", sx={"flex": 1})
Loading

0 comments on commit c689dc4

Please sign in to comment.