solara-ui 1.42.0__py2.py3-none-any.whl → 1.44.0__py2.py3-none-any.whl

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.
Files changed (71) hide show
  1. solara/__init__.py +1 -1
  2. solara/__main__.py +12 -7
  3. solara/_stores.py +128 -16
  4. solara/cache.py +6 -4
  5. solara/checks.py +1 -1
  6. solara/components/__init__.py +18 -1
  7. solara/components/datatable.py +4 -4
  8. solara/components/input.py +5 -1
  9. solara/components/markdown.py +46 -10
  10. solara/components/misc.py +2 -2
  11. solara/components/select.py +1 -1
  12. solara/components/style.py +1 -1
  13. solara/hooks/use_reactive.py +16 -1
  14. solara/lab/components/__init__.py +1 -0
  15. solara/lab/components/chat.py +15 -9
  16. solara/lab/components/input_time.py +133 -0
  17. solara/lab/hooks/dataframe.py +1 -0
  18. solara/lab/utils/dataframe.py +11 -1
  19. solara/server/app.py +66 -30
  20. solara/server/flask.py +12 -2
  21. solara/server/jupyter/server_extension.py +1 -0
  22. solara/server/kernel.py +50 -3
  23. solara/server/kernel_context.py +68 -9
  24. solara/server/patch.py +28 -30
  25. solara/server/server.py +16 -6
  26. solara/server/settings.py +11 -0
  27. solara/server/shell.py +19 -1
  28. solara/server/starlette.py +72 -14
  29. solara/server/static/solara_bootstrap.py +1 -1
  30. solara/settings.py +3 -0
  31. solara/tasks.py +30 -9
  32. solara/test/pytest_plugin.py +4 -2
  33. solara/toestand.py +119 -28
  34. solara/util.py +18 -0
  35. solara/website/components/docs.py +24 -1
  36. solara/website/components/markdown.py +17 -3
  37. solara/website/pages/changelog/changelog.md +26 -1
  38. solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +1 -1
  39. solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +10 -0
  40. solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +4 -2
  41. solara/website/pages/documentation/api/routing/route.py +10 -12
  42. solara/website/pages/documentation/api/routing/use_route.py +26 -30
  43. solara/website/pages/documentation/components/advanced/link.py +6 -8
  44. solara/website/pages/documentation/components/advanced/meta.py +6 -9
  45. solara/website/pages/documentation/components/advanced/style.py +7 -9
  46. solara/website/pages/documentation/components/input/file_browser.py +12 -14
  47. solara/website/pages/documentation/components/lab/input_time.py +15 -0
  48. solara/website/pages/documentation/components/lab/theming.py +6 -4
  49. solara/website/pages/documentation/components/layout/columns_responsive.py +37 -39
  50. solara/website/pages/documentation/components/layout/gridfixed.py +4 -6
  51. solara/website/pages/documentation/components/output/html.py +1 -3
  52. solara/website/pages/documentation/components/output/sql_code.py +23 -25
  53. solara/website/pages/documentation/components/page/head.py +4 -7
  54. solara/website/pages/documentation/components/page/title.py +12 -14
  55. solara/website/pages/documentation/components/status/error.py +17 -18
  56. solara/website/pages/documentation/components/status/info.py +17 -18
  57. solara/website/pages/documentation/examples/__init__.py +10 -0
  58. solara/website/pages/documentation/examples/ai/chatbot.py +62 -44
  59. solara/website/pages/documentation/examples/general/live_update.py +22 -28
  60. solara/website/pages/documentation/examples/general/pokemon_search.py +1 -1
  61. solara/website/pages/documentation/faq/content/99-faq.md +9 -0
  62. solara/website/pages/documentation/getting_started/content/00-quickstart.md +1 -1
  63. solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +23 -19
  64. solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +2 -2
  65. solara/website/pages/roadmap/roadmap.md +3 -0
  66. {solara_ui-1.42.0.dist-info → solara_ui-1.44.0.dist-info}/METADATA +2 -2
  67. {solara_ui-1.42.0.dist-info → solara_ui-1.44.0.dist-info}/RECORD +71 -69
  68. {solara_ui-1.42.0.data → solara_ui-1.44.0.data}/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -0
  69. {solara_ui-1.42.0.data → solara_ui-1.44.0.data}/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -0
  70. {solara_ui-1.42.0.dist-info → solara_ui-1.44.0.dist-info}/WHEEL +0 -0
  71. {solara_ui-1.42.0.dist-info → solara_ui-1.44.0.dist-info}/licenses/LICENSE +0 -0
@@ -14,18 +14,16 @@ routes = [
14
14
  @solara.component
15
15
  def Page():
16
16
  route_current, routes = solara.use_route()
17
- with solara.VBox() as main:
18
- # solara.Warning("Note the address bar in the browser. It should change to the path of the link.")
19
- solara.Markdown("*Click on one of the links below to change the route and see the url in your browser change, and match the route.*")
20
- with solara.VBox():
21
- for route in routes:
22
- with solara.Link(route):
23
- current = route_current is route
24
- if current:
25
- solara.Success(f"You are at solara.Route(path={route.path!r})")
26
- else:
27
- solara.Info(f"Go to solara.Route(path={route.path!r})")
28
- return main
17
+
18
+ solara.Markdown("*Click on one of the links below to change the route and see the url in your browser change, and match the route.*")
19
+ with solara.VBox():
20
+ for route in routes:
21
+ with solara.Link(route):
22
+ current = route_current is route
23
+ if current:
24
+ solara.Success(f"You are at solara.Route(path={route.path!r})")
25
+ else:
26
+ solara.Info(f"Go to solara.Route(path={route.path!r})")
29
27
 
30
28
 
31
29
  __doc__ += apidoc(solara.Route, full=True) # type: ignore
@@ -23,43 +23,39 @@ def Fruit():
23
23
  solara.Button("Choose a fruit, I recomment banana")
24
24
  return main
25
25
 
26
- with solara.VBox() as main:
27
- with solara.HBox():
28
- for route_fruit in routes[1:]:
29
- with solara.Link(solara.resolve_path(route_fruit)):
30
- solara.Button(route_fruit.path)
26
+ with solara.Row():
27
+ for route_fruit in routes[1:]:
28
+ with solara.Link(solara.resolve_path(route_fruit)):
29
+ solara.Button(route_fruit.path)
31
30
 
32
- with solara.Link("/documentation/api/routing/use_route/fruit/nofruit", nofollow=True):
33
- solara.Button("Wrong fruit")
34
- with solara.Link("/documentation/api/routing/use_route/not-routed", nofollow=True):
35
- solara.Button("Wrong url")
36
- solara.Success(f"You chose {route.path}")
37
- return main
31
+ with solara.Link("/documentation/api/routing/use_route/fruit/nofruit", nofollow=True):
32
+ solara.Button("Wrong fruit")
33
+ with solara.Link("/documentation/api/routing/use_route/not-routed", nofollow=True):
34
+ solara.Button("Wrong url")
35
+ solara.Success(f"You chose {route.path}")
38
36
 
39
37
 
40
38
  @solara.component
41
39
  def Page():
42
40
  # this gets the top level routes, '/' and 'fruit'
43
41
  route_current, routes_all = solara.use_route()
44
- with solara.VBox() as main:
45
- with solara.Card("Navigation using buttons"):
46
- with solara.HBox():
47
- for route in routes_all:
48
- with solara.Link(route):
49
- solara.Button(route.path, color="red" if route_current == route else None)
50
- with solara.Card("Content decided by route:"):
51
- if route_current is None:
52
- solara.Error("Page does not exist")
53
- with solara.Link("fruit/kiwi"):
54
- solara.Button("Go to fruit/kiwi")
55
- elif route_current.path == "/":
56
- with solara.Link("fruit/banana"):
57
- solara.Button("Go to fruit/banana")
58
- elif route_current.path == "fruit":
59
- Fruit()
60
- else:
61
- solara.Error(f"Unknown route: {route_current.path}")
62
- return main
42
+ with solara.Card("Navigation using buttons"):
43
+ with solara.Row():
44
+ for route in routes_all:
45
+ with solara.Link(route):
46
+ solara.Button(route.path, color="red" if route_current == route else None)
47
+ with solara.Card("Content decided by route:"):
48
+ if route_current is None:
49
+ solara.Error("Page does not exist")
50
+ with solara.Link("fruit/kiwi"):
51
+ solara.Button("Go to fruit/kiwi")
52
+ elif route_current.path == "/":
53
+ with solara.Link("fruit/banana"):
54
+ solara.Button("Go to fruit/banana")
55
+ elif route_current.path == "fruit":
56
+ Fruit()
57
+ else:
58
+ solara.Error(f"Unknown route: {route_current.path}")
63
59
 
64
60
 
65
61
  routes = [
@@ -14,14 +14,12 @@ routes = [
14
14
  @solara.component
15
15
  def Page():
16
16
  route_current, routes = solara.use_route()
17
- with solara.VBox() as main:
18
- solara.Info("Note the address bar in the browser. It should change to the path of the link.")
19
- with solara.HBox():
20
- for route in routes:
21
- with solara.Link(route):
22
- current = route_current is route
23
- solara.Button(f"Go to {route.path}", color="red" if current else None)
24
- return main
17
+ solara.Info("Note the address bar in the browser. It should change to the path of the link.")
18
+ with solara.Row():
19
+ for route in routes:
20
+ with solara.Link(route):
21
+ current = route_current is route
22
+ solara.Button(f"Go to {route.path}", color="red" if current else None)
25
23
 
26
24
 
27
25
  __doc__ += apidoc(solara.Link.f) # type: ignore
@@ -6,15 +6,12 @@ from solara.website.utils import apidoc
6
6
 
7
7
  @solara.component
8
8
  def Page():
9
- with solara.VBox() as main:
10
- solara.Info("Nothing to see here, only in this page's source code, or by looking at the google search results for this page.")
11
- with solara.Head():
12
- solara.Meta(
13
- name="description",
14
- content="The Meta component can be used to set the description of a page. This is useful for SEO, or crawlers that index your page.",
15
- )
16
-
17
- return main
9
+ solara.Info("Nothing to see here, only in this page's source code, or by looking at the google search results for this page.")
10
+ with solara.Head():
11
+ solara.Meta(
12
+ name="description",
13
+ content="The Meta component can be used to set the description of a page. This is useful for SEO, or crawlers that index your page.",
14
+ )
18
15
 
19
16
 
20
17
  __doc__ += apidoc(solara.Meta.f) # type: ignore
@@ -26,20 +26,18 @@ def Page():
26
26
  }
27
27
  """
28
28
 
29
- with solara.VBox() as main:
30
- solara.Checkbox(label="Use CSS", value=insert_css, on_value=set_insert_css)
31
- solara.Markdown(
32
- f"""
29
+ solara.Checkbox(label="Use CSS", value=insert_css, on_value=set_insert_css)
30
+ solara.Markdown(
31
+ f"""
33
32
  ## CSS Example that styles the button below
34
33
  ```css
35
34
  {css}
36
35
  ```
37
36
  """
38
- )
39
- if insert_css:
40
- solara.Style(css)
41
- solara.Button(label="Advanced users might want to style this", icon_name="mdi-thumb-up", classes=["mybutton"])
42
- return main
37
+ )
38
+ if insert_css:
39
+ solara.Style(css)
40
+ solara.Button(label="Advanced users might want to style this", icon_name="mdi-thumb-up", classes=["mybutton"])
43
41
 
44
42
 
45
43
  __doc__ += apidoc(solara.Style.f) # type: ignore
@@ -13,20 +13,18 @@ def Page():
13
13
  path, set_path = solara.use_state(cast(Optional[Path], None))
14
14
  directory, set_directory = solara.use_state(Path("~").expanduser())
15
15
 
16
- with solara.VBox() as main:
17
- can_select = solara.ui_checkbox("Enable select")
18
-
19
- def reset_path():
20
- set_path(None)
21
- set_file(None)
22
-
23
- # reset path and file when can_select changes
24
- solara.use_memo(reset_path, [can_select])
25
- solara.FileBrowser(directory, on_directory_change=set_directory, on_path_select=set_path, on_file_open=set_file, can_select=can_select)
26
- solara.Info(f"You are in directory: {directory}")
27
- solara.Info(f"You selected path: {path}")
28
- solara.Info(f"You opened file: {file}")
29
- return main
16
+ can_select = solara.ui_checkbox("Enable select")
17
+
18
+ def reset_path():
19
+ set_path(None)
20
+ set_file(None)
21
+
22
+ # reset path and file when can_select changes
23
+ solara.use_memo(reset_path, [can_select])
24
+ solara.FileBrowser(directory, on_directory_change=set_directory, on_path_select=set_path, on_file_open=set_file, can_select=can_select)
25
+ solara.Info(f"You are in directory: {directory}")
26
+ solara.Info(f"You selected path: {path}")
27
+ solara.Info(f"You opened file: {file}")
30
28
 
31
29
 
32
30
  __doc__ += apidoc(solara.FileBrowser.f) # type: ignore
@@ -0,0 +1,15 @@
1
+ """
2
+ # InputTime
3
+ """
4
+
5
+ import solara
6
+ from solara.website.components import NoPage
7
+ from solara.website.utils import apidoc
8
+
9
+ title = "InputTime"
10
+
11
+
12
+ __doc__ += apidoc(solara.lab.components.input_time.InputTime.f) # type: ignore
13
+
14
+
15
+ Page = NoPage
@@ -27,6 +27,8 @@ whether dark theme is enabled or not.
27
27
 
28
28
  ## Example
29
29
 
30
+ **Note**: Light and dark theme colors have to be set separately.
31
+
30
32
  ```solara
31
33
  import solara
32
34
  import solara.lab
@@ -35,14 +37,14 @@ from solara.lab import theme as theme
35
37
 
36
38
  def change_color(colors):
37
39
  if "purple" in colors:
38
- theme.themes.light.info = "#8617c2"
40
+ theme.themes.light.info = theme.themes.dark.info = "#8617c2"
39
41
  else:
40
- theme.themes.light.info = "#2196f3"
42
+ theme.themes.light.info = theme.themes.dark.info = "#2196f3"
41
43
 
42
44
  if "green" in colors:
43
- theme.themes.light.error = "#33bd65"
45
+ theme.themes.light.error = theme.themes.dark.error = "#33bd65"
44
46
  else:
45
- theme.themes.light.error = "#ff5252"
47
+ theme.themes.light.error = theme.themes.dark.error = "#ff5252"
46
48
 
47
49
 
48
50
  @solara.component
@@ -23,46 +23,44 @@ columns_xlarge = solara.reactive(1)
23
23
 
24
24
  @solara.component
25
25
  def Page():
26
- with solara.VBox() as main:
27
- with solara.Card("Controls"):
28
- solara.Checkbox(label="Wrap").connect(wrap)
29
- solara.Checkbox(label="Gutters").connect(gutters)
30
- solara.Checkbox(label="Dense gutters").connect(gutters_dense)
31
- solara.IntSlider("Children", max=20).connect(children_count)
26
+ with solara.Card("Controls"):
27
+ solara.Checkbox(label="Wrap").connect(wrap)
28
+ solara.Checkbox(label="Gutters").connect(gutters)
29
+ solara.Checkbox(label="Dense gutters").connect(gutters_dense)
30
+ solara.IntSlider("Children", max=20).connect(children_count)
32
31
 
33
- solara.Select("columns default", values=[1, 2, 3, 4, 6, 12]).connect(columns_default) # type: ignore
34
- solara.Select("columns small", values=[1, 2, 3, 4, 6, 12]).connect(columns_small) # type: ignore
35
- solara.Select("columns medium", values=[1, 2, 3, 4, 6, 12]).connect(columns_medium) # type: ignore
36
- solara.Select("columns large", values=[1, 2, 3, 4, 6, 12]).connect(columns_large) # type: ignore
37
- solara.Select("columns xlarge", values=[1, 2, 3, 4, 6, 12]).connect(columns_xlarge) # type: ignore
38
- # taken from https://v2.vuetifyjs.com/en/styles/display/#display
39
- solara.HTML(
40
- "h2", unsafe_innerHTML=f"Current screensize is xsmall/default, each child is {columns_default.value} points wide", class_="ma-2 d-flex d-sm-none ma"
41
- )
42
- solara.HTML(
43
- "h2", unsafe_innerHTML=f"Current screensize is small, each child is {columns_small.value} points wide", class_="ma-2 d-none d-sm-flex d-md-none"
44
- )
45
- solara.HTML(
46
- "h2", unsafe_innerHTML=f"Current screensize is medium, each child is {columns_medium.value} points wide", class_="ma-2 d-none d-md-flex d-lg-none"
47
- )
48
- solara.HTML(
49
- "h2", unsafe_innerHTML=f"Current screensize is large, each child is {columns_large.value} points wide", class_="ma-2 d-none d-lg-flex d-xl-none"
50
- )
51
- solara.HTML("h2", unsafe_innerHTML=f"Current screensize is xlarge, each child is {columns_xlarge.value} points wide", class_="ma-2 d-none d-xl-flex")
52
- solara.Markdown("Change the screen size to see the effect of the different columns sizes.")
53
- with solara.ColumnsResponsive(
54
- default=columns_default.value,
55
- small=columns_small.value,
56
- medium=columns_medium.value,
57
- large=columns_large.value,
58
- xlarge=columns_xlarge.value,
59
- wrap=wrap.value,
60
- gutters=gutters.value,
61
- gutters_dense=gutters_dense.value,
62
- ):
63
- for i in range(children_count.value):
64
- solara.Text(f"{i}")
65
- return main
32
+ solara.Select("columns default", values=[1, 2, 3, 4, 6, 12]).connect(columns_default) # type: ignore
33
+ solara.Select("columns small", values=[1, 2, 3, 4, 6, 12]).connect(columns_small) # type: ignore
34
+ solara.Select("columns medium", values=[1, 2, 3, 4, 6, 12]).connect(columns_medium) # type: ignore
35
+ solara.Select("columns large", values=[1, 2, 3, 4, 6, 12]).connect(columns_large) # type: ignore
36
+ solara.Select("columns xlarge", values=[1, 2, 3, 4, 6, 12]).connect(columns_xlarge) # type: ignore
37
+ # taken from https://v2.vuetifyjs.com/en/styles/display/#display
38
+ solara.HTML(
39
+ "h2", unsafe_innerHTML=f"Current screensize is xsmall/default, each child is {columns_default.value} points wide", class_="ma-2 d-flex d-sm-none ma"
40
+ )
41
+ solara.HTML(
42
+ "h2", unsafe_innerHTML=f"Current screensize is small, each child is {columns_small.value} points wide", class_="ma-2 d-none d-sm-flex d-md-none"
43
+ )
44
+ solara.HTML(
45
+ "h2", unsafe_innerHTML=f"Current screensize is medium, each child is {columns_medium.value} points wide", class_="ma-2 d-none d-md-flex d-lg-none"
46
+ )
47
+ solara.HTML(
48
+ "h2", unsafe_innerHTML=f"Current screensize is large, each child is {columns_large.value} points wide", class_="ma-2 d-none d-lg-flex d-xl-none"
49
+ )
50
+ solara.HTML("h2", unsafe_innerHTML=f"Current screensize is xlarge, each child is {columns_xlarge.value} points wide", class_="ma-2 d-none d-xl-flex")
51
+ solara.Markdown("Change the screen size to see the effect of the different columns sizes.")
52
+ with solara.ColumnsResponsive(
53
+ default=columns_default.value,
54
+ small=columns_small.value,
55
+ medium=columns_medium.value,
56
+ large=columns_large.value,
57
+ xlarge=columns_xlarge.value,
58
+ wrap=wrap.value,
59
+ gutters=gutters.value,
60
+ gutters_dense=gutters_dense.value,
61
+ ):
62
+ for i in range(children_count.value):
63
+ solara.Text(f"{i}")
66
64
 
67
65
 
68
66
  __doc__ += apidoc(solara.ColumnsResponsive.f) # type: ignore
@@ -13,9 +13,7 @@ title = "GridFixed"
13
13
 
14
14
  @solara.component
15
15
  def Page():
16
- with solara.VBox() as main:
17
- colors = "green red orange brown yellow pink".split()
18
- with solara.GridFixed(columns=3):
19
- for color in colors:
20
- ColorCard(color, color)
21
- return main
16
+ colors = "green red orange brown yellow pink".split()
17
+ with solara.GridFixed(columns=3):
18
+ for color in colors:
19
+ ColorCard(color, color)
@@ -13,9 +13,7 @@ def Page():
13
13
  <li>Item 2
14
14
  </ul>
15
15
  """
16
- with solara.VBox() as main:
17
- solara.HTML(tag="div", unsafe_innerHTML=html)
18
- return main
16
+ solara.HTML(tag="div", unsafe_innerHTML=html)
19
17
 
20
18
 
21
19
  __doc__ += apidoc(solara.HTML.f) # type: ignore
@@ -15,7 +15,6 @@ except ImportError:
15
15
  vaex = None
16
16
 
17
17
  import solara
18
- from solara.alias import rv
19
18
  from solara.website.utils import apidoc
20
19
 
21
20
  if vaex is not None:
@@ -56,30 +55,29 @@ def Page():
56
55
  return df
57
56
 
58
57
  result: solara.Result[pd.DataFrame] = solara.use_thread(run_query, dependencies=[query_executed]) # noqa: SH101
59
- with solara.VBox() as main:
60
- solara.SqlCode(query=query, tables=table_hints, on_query=set_query)
61
- enable_execute = (query != query_executed) or result.error is not None
62
-
63
- def execute():
64
- set_query_executed(query)
65
- if query == query_executed and result.error:
66
- result.retry() # type: ignore
67
-
68
- solara.Button("Execute", on_click=execute, disabled=not enable_execute)
69
- if result.error:
70
- solara.Error(f"Ooops {result.error}")
71
- elif not query:
72
- solara.Info("No query")
73
-
74
- elif result.value is not None:
75
- solara.Markdown(f"Result for query: `{query_executed}`")
76
- df = result.value
77
- solara.DataFrame(df)
78
- elif query_executed is not None:
79
- with solara.Div():
80
- solara.Text("Loading data...")
81
- rv.ProgressCircular(indeterminate=True, class_="solara-progress")
82
- return main
58
+
59
+ solara.SqlCode(query=query, tables=table_hints, on_query=set_query)
60
+ enable_execute = (query != query_executed) or result.error is not None
61
+
62
+ def execute():
63
+ set_query_executed(query)
64
+ if query == query_executed and result.error:
65
+ result.retry() # type: ignore
66
+
67
+ solara.Button("Execute", on_click=execute, disabled=not enable_execute)
68
+ if result.error:
69
+ solara.Error(f"Ooops {result.error}")
70
+ elif not query:
71
+ solara.Info("No query")
72
+
73
+ elif result.value is not None:
74
+ solara.Markdown(f"Result for query: `{query_executed}`")
75
+ df = result.value
76
+ solara.DataFrame(df)
77
+ elif query_executed is not None:
78
+ with solara.Div():
79
+ solara.Text("Loading data...")
80
+ solara.v.ProgressCircular(indeterminate=True, class_="solara-progress")
83
81
 
84
82
 
85
83
  __doc__ += apidoc(solara.SqlCode.f) # type: ignore
@@ -6,13 +6,10 @@ from solara.website.utils import apidoc
6
6
 
7
7
  @solara.component
8
8
  def Page():
9
- with solara.VBox() as main:
10
- solara.Info("A Head component does not render somesome visual on the page, but it is used to avoid duplicate tags, such as titles.")
11
- with solara.Head():
12
- # title should always occur inside a Head component
13
- solara.Title("Custom title")
14
-
15
- return main
9
+ solara.Info("A Head component does not render somesome visual on the page, but it is used to avoid duplicate tags, such as titles.")
10
+ with solara.Head():
11
+ # title should always occur inside a Head component
12
+ solara.Title("Custom title")
16
13
 
17
14
 
18
15
  __doc__ += apidoc(solara.Head.f) # type: ignore
@@ -8,20 +8,18 @@ from solara.website.utils import apidoc
8
8
 
9
9
  @solara.component
10
10
  def Page():
11
- title, set_title = solara.use_state(cast(Optional[str], "Custom title!"))
12
- with solara.VBox() as main:
13
- solara.ToggleButtonsSingle(value=title, values=[None, "Custom title!", "Different custom title"], on_value=set_title)
14
-
15
- if title is not None:
16
- # if the title is not set in a child component, the parent's title will be used
17
- with solara.Head():
18
- # title should always occur inside a Head component
19
- solara.Title(title)
20
- solara.Info(f"Your browser tab title should say {title}", classes=["mt-4"])
21
- else:
22
- solara.Warning("If no title is set, the parent title is used.", classes=["mt-4"])
23
-
24
- return main
11
+ title = solara.use_reactive(cast(Optional[str], "Custom title!"))
12
+
13
+ solara.ToggleButtonsSingle(value=title, values=[None, "Custom title!", "Different custom title"])
14
+
15
+ if title is not None:
16
+ # if the title is not set in a child component, the parent's title will be used
17
+ with solara.Head():
18
+ # title should always occur inside a Head component
19
+ solara.Title(title)
20
+ solara.Info(f"Your browser tab title should say {title}", classes=["mt-4"])
21
+ else:
22
+ solara.Warning("If no title is set, the parent title is used.", classes=["mt-4"])
25
23
 
26
24
 
27
25
  __doc__ += apidoc(solara.Title.f) # type: ignore
@@ -17,24 +17,23 @@ from solara.website.utils import apidoc
17
17
 
18
18
  @solara.component
19
19
  def Page():
20
- icon, set_icon = solara.use_state(True)
21
- dense, set_dense = solara.use_state(False)
22
- outlined, set_outlined = solara.use_state(True)
23
- text, set_text = solara.use_state(True)
24
- with solara.VBox() as main:
25
- with solara.GridFixed(4):
26
- solara.Checkbox(label="Use icon", value=icon, on_value=set_icon)
27
- solara.Checkbox(label="Show dense", value=dense, on_value=set_dense)
28
- solara.Checkbox(label="Show as text", value=text, on_value=set_text)
29
- solara.Checkbox(label="Show outlined", value=outlined, on_value=set_outlined)
30
- solara.Error(
31
- f"This is solara.Error(label='...', text={text}, dense={dense}, outlined={outlined}, icon={icon})",
32
- text=text,
33
- dense=dense,
34
- outlined=outlined,
35
- icon=icon,
36
- )
37
- return main
20
+ icon = solara.use_reactive(True)
21
+ dense = solara.use_reactive(False)
22
+ outlined = solara.use_reactive(True)
23
+ text = solara.use_reactive(True)
24
+
25
+ with solara.GridFixed(4):
26
+ solara.Checkbox(label="Use icon", value=icon)
27
+ solara.Checkbox(label="Show dense", value=dense)
28
+ solara.Checkbox(label="Show as text", value=text)
29
+ solara.Checkbox(label="Show outlined", value=outlined)
30
+ solara.Error(
31
+ f"This is solara.Error(label='...', text={text.value}, dense={dense.value}, outlined={outlined.value}, icon={icon.value})",
32
+ text=text.value,
33
+ dense=dense.value,
34
+ outlined=outlined.value,
35
+ icon=icon.value,
36
+ )
38
37
 
39
38
 
40
39
  __doc__ += apidoc(solara.Error.f) # type: ignore
@@ -17,24 +17,23 @@ from solara.website.utils import apidoc
17
17
 
18
18
  @solara.component
19
19
  def Page():
20
- icon, set_icon = solara.use_state(True)
21
- dense, set_dense = solara.use_state(False)
22
- outlined, set_outlined = solara.use_state(True)
23
- text, set_text = solara.use_state(True)
24
- with solara.VBox() as main:
25
- with solara.GridFixed(4):
26
- solara.Checkbox(label="Use icon", value=icon, on_value=set_icon)
27
- solara.Checkbox(label="Show dense", value=dense, on_value=set_dense)
28
- solara.Checkbox(label="Show as text", value=text, on_value=set_text)
29
- solara.Checkbox(label="Show outlined", value=outlined, on_value=set_outlined)
30
- solara.Info(
31
- f"This is solara.Info(label='...', text={text}, dense={dense}, outlined={outlined}, icon={icon})",
32
- text=text,
33
- dense=dense,
34
- outlined=outlined,
35
- icon=icon,
36
- )
37
- return main
20
+ icon = solara.use_reactive(True)
21
+ dense = solara.use_reactive(False)
22
+ outlined = solara.use_reactive(True)
23
+ text = solara.use_reactive(True)
24
+
25
+ with solara.GridFixed(4):
26
+ solara.Checkbox(label="Use icon", value=icon)
27
+ solara.Checkbox(label="Show dense", value=dense)
28
+ solara.Checkbox(label="Show as text", value=text)
29
+ solara.Checkbox(label="Show outlined", value=outlined)
30
+ solara.Info(
31
+ f"This is solara.Info(label='...', text={text.value}, dense={dense.value}, outlined={outlined.value}, icon={icon.value})",
32
+ text=text.value,
33
+ dense=dense.value,
34
+ outlined=outlined.value,
35
+ icon=icon.value,
36
+ )
38
37
 
39
38
 
40
39
  __doc__ += apidoc(solara.Info.f) # type: ignore
@@ -3,6 +3,11 @@ from solara.website.components import Gallery, MarkdownWithMetadata
3
3
 
4
4
  title = "Examples"
5
5
 
6
+ pycafe_projects = [
7
+ "chatbot",
8
+ "tokenizer",
9
+ ]
10
+
6
11
 
7
12
  @solara.component
8
13
  def Page(route_external=None):
@@ -37,6 +42,11 @@ def Layout(children):
37
42
  with solara.Column(style={"max-width": "min(100%, 1024px)", "width": "100%"}):
38
43
  if route_current.path != "/":
39
44
  solara.Button("View source code on GitHub", icon_name="mdi-github-circle", href=github_url, class_="ma-2", target="_blank", text=True)
45
+ if route_current.path in pycafe_projects:
46
+ pycafe_url = f"https://py.cafe/solara/{route_current.path}"
47
+ solara.Button(
48
+ "Run this example on PyCafe", icon_name="mdi-coffee-to-go-outline", href=pycafe_url, class_="ma-2", target="_blank", text=True
49
+ )
40
50
  if not hasattr(module, "Page"):
41
51
  solara.Error(f"No Page component found in {module}")
42
52
  else: