Skip to content

Commit 35e895a

Browse files
committed
add more theme
1 parent c13ae6d commit 35e895a

File tree

14 files changed

+431
-36
lines changed

14 files changed

+431
-36
lines changed

demos/theme.py

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
from functools import partial
2+
3+
from pywebio import start_server, config
4+
from pywebio.input import *
5+
from pywebio.output import *
6+
from pywebio.pin import *
7+
from pywebio.session import *
8+
9+
10+
def pin_widgets():
11+
put_markdown("# Pin widget")
12+
options = [
13+
{
14+
"label": "Option one",
15+
"value": 1,
16+
"selected": True,
17+
},
18+
{
19+
"label": "Option two",
20+
"value": 2,
21+
},
22+
{
23+
"label": "Disabled option",
24+
"value": 3,
25+
"disabled": True
26+
}
27+
]
28+
put_input('input', label='Text input', placeholder="Enter email",
29+
help_text="We'll never share your email with anyone else.")
30+
put_input('valid_input', label="Valid input", value="correct value")
31+
put_input('invalid_input', label="Invalid input", value="wrong value")
32+
put_textarea('textarea', label='Textarea', rows=3, maxlength=10, minlength=20, value=None,
33+
placeholder='This is placeholder message', readonly=False)
34+
put_textarea('code', label='Code area', rows=4, code={'mode': 'python'},
35+
value='import pywebio\npywebio.output.put_text("hello world")')
36+
put_select('select', options=options, label='Select')
37+
put_select('select_multiple', options=options, label='Multiple select', multiple=True, value=None)
38+
put_checkbox('checkbox', options=options, label='Checkbox', inline=False, value=None)
39+
put_checkbox('checkbox_inline', options=options, label='Inline checkbox', inline=True, value=None)
40+
put_radio('radio', options=options, label='Radio', inline=False, value=None)
41+
put_radio('radio_inline', options=options, label='Inline radio', inline=True, value='B')
42+
put_slider('slider', label='Slider')
43+
put_actions('actions', buttons=[
44+
{'label': 'Submit', 'value': '1'},
45+
{'label': 'Warning', 'value': '2', 'color': 'warning'},
46+
{'label': 'Danger', 'value': '3', 'color': 'danger'},
47+
], label='Actions')
48+
49+
pin_update('valid_input', valid_status=True, valid_feedback="Success! You've done it.")
50+
pin_update('invalid_input', valid_status=False, invalid_feedback="Sorry, that username's taken. Try another?")
51+
52+
53+
def form():
54+
options = [
55+
{
56+
"label": "Option one",
57+
"value": 1,
58+
"selected": True,
59+
},
60+
{
61+
"label": "Option two",
62+
"value": 2,
63+
},
64+
{
65+
"label": "Disabled option",
66+
"value": 3,
67+
"disabled": True
68+
}
69+
]
70+
71+
input_group('Input group', [
72+
input('Text', type=TEXT, datalist=['candidate-%s' % i for i in range(10)], name='text', required=True,
73+
help_text='Required'),
74+
input('Number', type=NUMBER, value="42", name='number'),
75+
input('Float', type=FLOAT, name='float'),
76+
input('Password', type=PASSWORD, name='password'),
77+
78+
textarea('Textarea', rows=3, maxlength=20, name='textarea',
79+
placeholder="The maximum number of characters you can input is 20"),
80+
81+
textarea('Code', name='code', code={'mode': 'python'},
82+
value='import pywebio\npywebio.output.put_text("hello world")'),
83+
84+
select('Multiple select', options, name='select-multiple', multiple=True),
85+
86+
select('Select', options, name='select'),
87+
88+
checkbox('Inline checkbox', options, inline=True, name='checkbox-inline'),
89+
90+
checkbox('Checkbox', options, name='checkbox'),
91+
92+
radio('Inline radio', options, inline=True, name='radio-inline'),
93+
94+
radio('Radio', options, inline=False, name='radio'),
95+
96+
file_upload('File upload', name='file_upload', max_size='10m'),
97+
98+
actions('Actions', [
99+
{'label': 'Submit', 'value': 'submit'},
100+
{'label': 'Disabled', 'disabled': True},
101+
{'label': 'Reset', 'type': 'reset', 'color': 'warning'},
102+
{'label': 'Cancel', 'type': 'cancel', 'color': 'danger'},
103+
], name='actions'),
104+
])
105+
106+
107+
def output_widgets():
108+
###########################################################################################
109+
put_markdown("# Typography")
110+
put_row([
111+
put_markdown("""
112+
## Heading 2
113+
### Heading 3
114+
#### Heading 4
115+
##### Heading 5
116+
117+
[PyWebIO](https://github.com/pywebio/PyWebIO) is awesome!
118+
119+
*This text will be italic*
120+
**This text will be bold**
121+
_You **can** combine them_
122+
~~Strikethrough~~
123+
This is `inline code`
124+
125+
As Kanye West said:
126+
127+
> We're living the future so
128+
> the present is our past.
129+
""", strip_indent=8),
130+
131+
put_markdown("""
132+
### Lists
133+
* Item 1
134+
* Item 2
135+
* Item 2a
136+
* Item 2b
137+
138+
1. Item 1
139+
1. Item 2
140+
1. Item 2a
141+
1. Item 2b
142+
143+
### Task Lists
144+
- [x] [links](), **formatting**, and <del>tags</del> supported
145+
- [x] list syntax required (any unordered or ordered list supported)
146+
- [x] this is a complete item
147+
- [ ] this is an incomplete item
148+
""", strip_indent=8)
149+
])
150+
151+
###########################################################################################
152+
put_markdown("""
153+
# Code
154+
```python
155+
from pywebio import *
156+
157+
def main(): # PyWebIO application function
158+
name = input.input("what's your name")
159+
output.put_text("hello", name)
160+
161+
start_server(main, port=8080, debug=True)
162+
```
163+
""", strip_indent=4)
164+
###########################################################################################
165+
put_markdown('# Image')
166+
with use_scope('image'):
167+
put_image(
168+
"https://opengraph.githubassets.com/6bcea5272d0b5901f48a67d9d05da6c7a7c7c68da32a5327943070ff9c9a3dfb/pywebio/PyWebIO").style("""
169+
max-height: 250px;
170+
border: 2px solid #fff;
171+
border-radius: 25px;
172+
""")
173+
###########################################################################################
174+
put_markdown("# Buttons")
175+
# small=None, link_style=False, outline=False, group=False
176+
put_buttons([
177+
dict(label=i, value=i, color=i)
178+
for i in ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark']
179+
], onclick=lambda b: toast(f'Clicked {b} button'))
180+
181+
put_buttons([
182+
dict(label=i, value=i, color=i)
183+
for i in ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark']
184+
], onclick=lambda b: toast(f'Clicked {b} button'), small=True)
185+
186+
put_buttons([
187+
dict(label=i, value=i, color=i)
188+
for i in ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark']
189+
], onclick=lambda b: toast(f'Clicked {b} button'), link_style=True)
190+
191+
put_buttons([
192+
dict(label=i, value=i, color=i)
193+
for i in ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark']
194+
], onclick=lambda b: toast(f'Clicked {b} button'), outline=True)
195+
196+
put_buttons([
197+
dict(label=i, value=i, color=i)
198+
for i in ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark']
199+
], onclick=lambda b: toast(f'Clicked {b} button'), group=True)
200+
###########################################################################################
201+
put_markdown('# Tables')
202+
put_markdown("""
203+
First Header | Second Header
204+
------------ | -------------
205+
Content from cell 1 | Content from cell 2
206+
Content in the first column | Content in the second column
207+
""", strip_indent=4)
208+
209+
put_table([
210+
['Type', 'Content'],
211+
['text', '<hr/>'],
212+
['html', put_html('X<sup>2</sup>')],
213+
['buttons', put_buttons(['A', 'B'], onclick=toast, small=True)],
214+
['markdown', put_markdown('`awesome PyWebIO!`\n - 1\n - 2\n - 3')],
215+
['file', put_file('hello.text', b'')],
216+
['table', put_table([
217+
['A', 'B'],
218+
[put_markdown('`C`'), put_markdown('`D`')]
219+
])]
220+
])
221+
###########################################################################################
222+
put_markdown('# Popup')
223+
224+
def show_popup():
225+
popup('Popup title', [
226+
'Popup body text goes here.',
227+
put_table([
228+
['Type', 'Content'],
229+
['html', put_html('X<sup>2</sup>')],
230+
['text', '<hr/>'],
231+
['buttons', put_buttons(['A', 'B'], onclick=toast)],
232+
['markdown', put_markdown('`Awesome PyWebIO!`')],
233+
['file', put_file('hello.text', b'')],
234+
['table', put_table([['A', 'B'], ['C', 'D']])]
235+
]),
236+
put_button('Close', onclick=close_popup, outline=True)
237+
], size=PopupSize.NORMAL)
238+
239+
put_button("Click me to show a popup", onclick=show_popup)
240+
241+
###########################################################################################
242+
put_markdown('# Layout')
243+
put_row([
244+
put_column([
245+
put_code('A'),
246+
put_row([
247+
put_code('B1'), None,
248+
put_code('B2'), None,
249+
put_code('B3'),
250+
]),
251+
put_code('C'),
252+
]), None,
253+
put_code('python'), None,
254+
put_code('python\n' * 20).style('max-height:200px;'),
255+
])
256+
257+
###########################################################################################
258+
put_markdown('# Loading')
259+
put_processbar('processbar', 0.3)
260+
put_text()
261+
put_grid([
262+
[
263+
put_loading(shape=shape, color=color)
264+
for color in ('primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark')
265+
]
266+
for shape in ('border', 'grow')
267+
], cell_width='50px', cell_height='50px')
268+
###########################################################################################
269+
put_markdown('# Tabs')
270+
271+
put_tabs([
272+
{'title': 'Text', 'content': 'Hello world'},
273+
{'title': 'Markdown', 'content': put_markdown('~~Strikethrough~~')},
274+
{'title': 'More content', 'content': [
275+
put_table([
276+
['Commodity', 'Price'],
277+
['Apple', '5.5'],
278+
['Banana', '7'],
279+
]),
280+
put_link('pywebio', 'https://github.com/wang0618/PyWebIO')
281+
]},
282+
])
283+
###########################################################################################
284+
put_markdown('# Scrollable')
285+
286+
put_scrollable("Long text " * 200, height=200)
287+
###########################################################################################
288+
put_markdown('# Collapse')
289+
put_collapse('Click to expand', [
290+
'text',
291+
put_markdown('~~Strikethrough~~'),
292+
put_table([
293+
['Commodity', 'Price'],
294+
['Apple', '5.5'],
295+
])
296+
])
297+
###########################################################################################
298+
put_markdown('# Message')
299+
300+
put_warning(
301+
put_markdown('### Warning!'),
302+
"Best check yo self, you're not looking too good. Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.",
303+
closable=True)
304+
put_success("Well done! You successfully read this important alert message.")
305+
put_info("Heads up! This alert needs your attention, but it's not super important.")
306+
put_error("Oh snap! Change a few things up and try submitting again.")
307+
308+
309+
ALL_THEME = ('default', 'dark', 'sketchy', 'minty', 'yeti')
310+
311+
THEME_SUMMARY = {'default': 'The default theme', 'dark': 'A theme for night',
312+
'sketchy': 'A hand-drawn look for mockups and mirth', 'minty': 'A fresh feel',
313+
'yeti': 'A friendly foundation'}
314+
315+
style = """
316+
table img:hover {
317+
transition-duration: 400ms;
318+
transform: translateY(-2px);
319+
box-shadow: 0px 2px 9px 2px rgb(0 0 0 / 27%), 0 30px 50px -30px rgb(0 0 0 / 30%)
320+
}
321+
.page-header h1 {
322+
font-size: 3em;
323+
}
324+
#pywebio-scope-image img {
325+
box-shadow: rgb(204 204 204) 3px 3px 13px;
326+
}
327+
.webio-theme-dark #pywebio-scope-image img {
328+
box-shadow: none !important;
329+
}
330+
"""
331+
332+
333+
@config(css_style=style)
334+
def page():
335+
theme = eval_js("new URLSearchParams(window.location.search).get('app')")
336+
if theme not in ALL_THEME:
337+
theme = 'default'
338+
339+
put_html(f"""
340+
<div class="page-header">
341+
<div style="text-align: center">
342+
<h1>{theme[0].upper() + theme[1:]}</h1>
343+
<p class="lead">{THEME_SUMMARY.get(theme, '')}</p>
344+
</div>
345+
</div>
346+
""")
347+
348+
put_markdown('# Switch Themes')
349+
put_table(
350+
[
351+
[
352+
put_image(f"https://cdn.jsdelivr.net/gh/wang0618/PyWebIO/docs/assets/theme/{name}.png").onclick(
353+
partial(go_app, name=name, new_window=False))
354+
for name in ALL_THEME if name != theme],
355+
]
356+
)
357+
put_markdown("""
358+
### Credits
359+
360+
The dark theme is modified from ForEvolve's [bootstrap-dark](https://github.com/ForEvolve/bootstrap-dark).
361+
The sketchy, minty and yeti theme are from [bootswatch](https://bootswatch.com/4/).
362+
""", lstrip=True)
363+
364+
output_widgets()
365+
pin_widgets()
366+
form()
367+
368+
369+
# bind each theme to the app
370+
main = {
371+
theme: config(theme=theme, title=f"PyWebIO {theme} theme")(page)
372+
for theme in ALL_THEME if theme != 'default'
373+
}
374+
main['index'] = page
375+
376+
if __name__ == '__main__':
377+
start_server(main, debug=True, port=8080, cdn=False)

docs/assets/theme/dark.png

41.2 KB
Loading

docs/assets/theme/default.png

42.9 KB
Loading

docs/assets/theme/minty.png

37.6 KB
Loading

docs/assets/theme/sketchy.png

56.7 KB
Loading

docs/assets/theme/yeti.png

38.8 KB
Loading

0 commit comments

Comments
 (0)