Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Use shiny.ui.Theme #39

Merged
merged 29 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3a468dc
Update themes via `shiny.ui.Theme`, replacing R with Python script
gadenbuie Jun 24, 2024
40d0baa
chore: Use `theme` argument of `shiny.ui.page_*()`
gadenbuie Jun 24, 2024
ea1d3f9
feat: Update theme picker, deprecates `default` argument
gadenbuie Jun 24, 2024
8d1a8dc
chore: will require `shiny>=0.10.0` which introduced `theme` argument…
gadenbuie Jun 24, 2024
f89a92b
fix: avoid `ui.nav()` deprecation warnings
gadenbuie Jun 24, 2024
22f1644
tests: Add theme picker deprecation test
gadenbuie Jun 24, 2024
4ec9fc8
fix: Avoid call in function signature
gadenbuie Jun 24, 2024
509285a
fix: ignore type check in deprecation warning test
gadenbuie Jun 24, 2024
dc435fc
chore: Don't check `scripts/` with pyright
gadenbuie Jun 24, 2024
cfa08ee
feat: ShinyswatchTheme(shiny.ui.Theme)
gadenbuie Jun 24, 2024
9089b7f
chore: _theme_utils -> _theme_shinyswatch
gadenbuie Jun 24, 2024
7790cc5
docs: Update theme docs
gadenbuie Jun 24, 2024
8c35605
docs: remove `get_theme_deps()`
gadenbuie Jun 24, 2024
34af008
docs: mark initial theme as optional
gadenbuie Jun 24, 2024
6aee3e6
docs: Bump quartodoc, griffe
gadenbuie Jun 25, 2024
fc9b041
chore: Update to latest from posit-dev/py-shiny#1358
gadenbuie Jun 25, 2024
ae59e7d
feat: Improve theme-picker, adds `shiny`, `bootstrap` and initial the…
gadenbuie Jun 25, 2024
db1a3ed
docs: Showcase custom shiny thme
gadenbuie Jun 25, 2024
8a34733
docs: Update changelog
gadenbuie Jun 25, 2024
0ba667e
chore: fix pyright and black issues
gadenbuie Jun 25, 2024
4ee6d08
chore: fine, black, you win
gadenbuie Jun 25, 2024
a4a1c7f
chore: black broke me
gadenbuie Jun 25, 2024
058ab2d
fix: Assume initial theme name is "default"
gadenbuie Jun 26, 2024
abeb9a2
chore: Lint/format theme_picker.js
gadenbuie Jun 26, 2024
dae8e23
feat: return `self` instead of the htmldependency when called
gadenbuie Jun 26, 2024
e5bc9be
tests: Fix theme dependency test
gadenbuie Jun 26, 2024
34dadd8
Merged origin/main into feat/shiny-ui-theme
gadenbuie Jun 28, 2024
41cd0a4
chore: Use shiny from main
gadenbuie Jun 28, 2024
54199f4
ci: trigger test
gadenbuie Jun 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions examples/basic-darkly/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import shinyswatch

app_ui = ui.page_fluid(
# Theme code - start
shinyswatch.theme.darkly,
# Theme code - end
ui.input_slider("num", "Number:", min=10, max=100, value=30),
ui.output_text_verbatim("slider_val"),
theme=shinyswatch.theme.darkly,
)


Expand Down
7 changes: 1 addition & 6 deletions examples/big-sketchy/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
import shinyswatch

app_ui = ui.page_fluid(
# Theme code - start
# Add the Theme's HTML Dependency object in the UI code
shinyswatch.get_theme("sketchy"),
# # Equivalent to:
# shinyswatch.theme.sketchy,
# Theme code - end
ui.panel_title("Changing the values of inputs from the server"),
ui.row(
ui.column(
Expand Down Expand Up @@ -93,6 +87,7 @@
),
),
),
theme=shinyswatch.get_theme("sketchy"),
)


Expand Down
2 changes: 1 addition & 1 deletion examples/components/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
app_ui = ui.page_navbar(
ui.nav_panel(
"Navbar 1",
shinyswatch.theme.superhero,
ui.layout_sidebar(
ui.panel_sidebar(
ui.input_file("file", "File input:"),
Expand Down Expand Up @@ -42,6 +41,7 @@
ui.nav_panel("Plot", "Plot content"),
ui.nav_panel("Table", "Table content"),
title="shinyswatch",
theme=shinyswatch.theme.superhero,
)


Expand Down
13 changes: 9 additions & 4 deletions examples/page-sidebar/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
app_ui = ui.page_sidebar(
ui.sidebar(
ui.input_slider("n", "N", min=0, max=100, value=20),
shinyswatch.theme_picker_ui("zephyr"),
shinyswatch.theme_picker_ui(),
),
ui.card(ui.output_plot("plot")),
title="Shiny Sidebar Page",
Expand All @@ -21,19 +21,24 @@ def server(input):
@render.plot(alt="A histogram")
def plot():
req(input.shinyswatch_theme_picker())
theme = getattr(shinyswatch.theme, input.shinyswatch_theme_picker())
if input.shinyswatch_theme_picker() != "default":
theme = getattr(shinyswatch.theme, input.shinyswatch_theme_picker())
color_accent = theme.colors.primary
color_fg = theme.colors.body_color
else:
color_accent = "#007BC2"
color_fg = "#1D1F21"

np.random.seed(19680801)
x = 100 + 15 * np.random.randn(437)

fig, ax = plt.subplots()
ax.hist(x, input.n(), density=True, color=theme.colors.primary)
ax.hist(x, input.n(), density=True, color=color_accent)

# Theme the plot to match light/dark mode
fig.patch.set_facecolor("none")
ax.set_facecolor("none")

color_fg = theme.colors.body_color
ax.tick_params(axis="both", colors=color_fg)
ax.spines["bottom"].set_color(color_fg)
ax.spines["top"].set_color(color_fg)
Expand Down
23 changes: 11 additions & 12 deletions examples/theme-picker/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@
import shinyswatch

app_ui = ui.page_navbar(
ui.nav(
ui.nav_panel(
"Navbar 1",
# !! DO NOT INCLUDE THEME in `app_ui` !!
# shinyswatch.theme.superhero(),
# !! !!
# Include theme_picker_ui UI module somewhere in your UI
shinyswatch.theme_picker_ui(),
ui.layout_sidebar(
ui.panel_sidebar(
ui.input_file("file", "File input:"),
Expand All @@ -25,7 +20,7 @@
),
ui.panel_main(
ui.navset_tab(
ui.nav(
ui.nav_panel(
"Tab 1",
ui.output_table("table"),
ui.tags.h4("Verbatim text output"),
Expand All @@ -36,17 +31,21 @@
ui.tags.h4("Header 4"),
ui.tags.h5("Header 5"),
),
ui.nav("Tab 2", "Tab 2 content"),
ui.nav("Tab 3", "Tab 3 content"),
ui.nav_panel("Tab 2", "Tab 2 content"),
ui.nav_panel("Tab 3", "Tab 3 content"),
)
),
),
),
ui.nav("Plot", "Plot content"),
ui.nav("Table", "Table content"),
sidebar=ui.sidebar("Sidebar content"),
ui.nav_panel("Plot", "Plot content"),
ui.nav_panel("Table", "Table content"),
sidebar=ui.sidebar(
"Sidebar content",
shinyswatch.theme_picker_ui(),
),
title="shinyswatch",
inverse=True,
theme=shinyswatch.theme.superhero,
)


Expand Down
7 changes: 2 additions & 5 deletions pyrightconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
{
"ignore": ["build", "docs"],
"ignore": ["build", "docs", "scripts"],
"typeCheckingMode": "basic",
"strict": [
"shinyswatch/",
"scripts/",
],
"strict": ["shinyswatch/"],
"reportImportCycles": false
}
45 changes: 45 additions & 0 deletions scripts/get_theme_values.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import json

import tinycss2
from shiny.ui import Theme


def get_theme_color_values(theme: Theme):
# If it matters, should copy the theme to avoid modifying the original
theme.add_rules(
"""
#values {
--value: {
"body_color": "#{$body-color}",
"body_bg": "#{$body-bg}",
"light": "#{$light}",
"dark": "#{$dark}",
"primary": "#{$primary}",
"secondary": "#{$secondary}",
"info": "#{$info}",
"success": "#{$success}",
"warning": "#{$warning}",
"danger": "#{$danger}"
}
}
"""
)

theme_css = theme.to_css()

rules = tinycss2.parse_stylesheet(theme_css)
value_rule = [rule for rule in rules if is_value_rule(rule)][0]
value = [
value
for value in value_rule.content
if isinstance(value, tinycss2.ast.CurlyBracketsBlock)
]
return json.loads(value[0].serialize())


def is_value_rule(rule):
return (
isinstance(rule, tinycss2.ast.QualifiedRule)
and isinstance(rule.prelude[0], tinycss2.ast.HashToken)
and rule.prelude[0].value == "values"
)
Loading
Loading