solara-ui 1.40.0__py2.py3-none-any.whl → 1.42.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 (66) hide show
  1. solara/__init__.py +1 -1
  2. solara/__main__.py +30 -11
  3. solara/_stores.py +185 -0
  4. solara/components/component_vue.py +26 -2
  5. solara/components/echarts.py +5 -2
  6. solara/components/echarts.vue +22 -5
  7. solara/components/file_drop.py +20 -0
  8. solara/components/input.py +16 -0
  9. solara/components/markdown.py +22 -13
  10. solara/components/spinner-solara.vue +2 -2
  11. solara/components/spinner.py +17 -2
  12. solara/hooks/use_reactive.py +8 -1
  13. solara/reactive.py +9 -3
  14. solara/server/assets/style.css +2 -0
  15. solara/server/kernel.py +2 -1
  16. solara/server/qt.py +113 -0
  17. solara/server/settings.py +1 -0
  18. solara/server/starlette.py +2 -2
  19. solara/server/static/main-vuetify.js +10 -0
  20. solara/server/static/solara_bootstrap.py +1 -1
  21. solara/server/templates/loader-solara.html +1 -1
  22. solara/server/templates/solara.html.j2 +6 -1
  23. solara/settings.py +14 -0
  24. solara/template/portal/pyproject.toml +1 -1
  25. solara/test/pytest_plugin.py +3 -0
  26. solara/toestand.py +139 -16
  27. solara/util.py +22 -0
  28. solara/website/components/markdown.py +45 -1
  29. solara/website/components/sidebar.py +3 -1
  30. solara/website/pages/__init__.py +13 -7
  31. solara/website/pages/changelog/changelog.md +9 -0
  32. solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +17 -1
  33. solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +4 -5
  34. solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +3 -5
  35. solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +3 -5
  36. solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +3 -5
  37. solara/website/pages/documentation/api/hooks/use_cross_filter.py +3 -5
  38. solara/website/pages/documentation/api/hooks/use_exception.py +9 -11
  39. solara/website/pages/documentation/api/hooks/use_previous.py +6 -9
  40. solara/website/pages/documentation/api/hooks/use_state_or_update.py +23 -26
  41. solara/website/pages/documentation/api/hooks/use_thread.py +11 -13
  42. solara/website/pages/documentation/api/utilities/on_kernel_start.py +17 -0
  43. solara/website/pages/documentation/components/input/input.py +22 -0
  44. solara/website/pages/documentation/components/viz/echarts.py +3 -1
  45. solara/website/pages/documentation/examples/__init__.py +13 -21
  46. solara/website/pages/documentation/examples/ai/chatbot.py +1 -1
  47. solara/website/pages/documentation/examples/general/pokemon_search.py +3 -3
  48. solara/website/pages/documentation/examples/general/vue_component.py +1 -1
  49. solara/website/pages/documentation/examples/libraries/altair.py +1 -0
  50. solara/website/pages/documentation/examples/libraries/bqplot.py +1 -1
  51. solara/website/pages/documentation/examples/libraries/ipyleaflet.py +1 -1
  52. solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +1 -1
  53. solara/website/pages/documentation/examples/utilities/countdown_timer.py +18 -20
  54. solara/website/pages/documentation/examples/visualization/annotator.py +1 -3
  55. solara/website/pages/documentation/examples/visualization/linked_views.py +3 -6
  56. solara/website/pages/documentation/getting_started/content/00-quickstart.md +19 -1
  57. solara/website/pages/documentation/getting_started/content/01-introduction.md +1 -1
  58. solara/website/pages/roadmap/roadmap.md +3 -0
  59. solara/widgets/vue/navigator.vue +46 -16
  60. solara/widgets/vue/vegalite.vue +18 -0
  61. {solara_ui-1.40.0.dist-info → solara_ui-1.42.0.dist-info}/METADATA +8 -5
  62. {solara_ui-1.40.0.dist-info → solara_ui-1.42.0.dist-info}/RECORD +66 -64
  63. {solara_ui-1.40.0.dist-info → solara_ui-1.42.0.dist-info}/WHEEL +1 -1
  64. {solara_ui-1.40.0.data → solara_ui-1.42.0.data}/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -0
  65. {solara_ui-1.40.0.data → solara_ui-1.42.0.data}/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -0
  66. {solara_ui-1.40.0.dist-info → solara_ui-1.42.0.dist-info}/licenses/LICENSE +0 -0
solara/util.py CHANGED
@@ -31,6 +31,28 @@ except RuntimeError:
31
31
  has_threads = False
32
32
 
33
33
 
34
+ from reacton.utils import equals as equals_extra
35
+
36
+
37
+ def equals_pickle(a, b):
38
+ """Compare two values for equality.
39
+
40
+ Avoid false negative, e.g. when comparing dataframes, we want to compare
41
+ the data, not the object identity.
42
+
43
+ """
44
+ if equals_extra(a, b):
45
+ return True
46
+ import pickle
47
+
48
+ try:
49
+ if pickle.dumps(a) == pickle.dumps(b):
50
+ return True
51
+ except Exception:
52
+ pass
53
+ return False
54
+
55
+
34
56
  def github_url(file):
35
57
  rel_path = os.path.relpath(file, Path(solara.__file__).parent.parent)
36
58
  github_url = solara.github_url + f"/blob/{solara.git_branch}/" + rel_path
@@ -1,8 +1,12 @@
1
1
  from typing import Dict, List, Union
2
2
 
3
3
  import yaml
4
+ import markdown
5
+ import mkdocs_pycafe
6
+ import pymdownx.superfences
4
7
 
5
8
  import solara
9
+ from solara.components.markdown import formatter, _no_deep_copy_emojione
6
10
 
7
11
 
8
12
  # We want to separate metadata from the markdown files before rendering them, which solara.Markdown doesn't support
@@ -27,12 +31,52 @@ def MarkdownWithMetadata(content: str, unsafe_solara_execute=True):
27
31
  solara.Meta(property=key, content=value)
28
32
  else:
29
33
  solara.Meta(name=key, content=value)
34
+
35
+ def make_markdown_object():
36
+ return markdown.Markdown( # type: ignore
37
+ extensions=[
38
+ "pymdownx.highlight",
39
+ "pymdownx.superfences",
40
+ "pymdownx.emoji",
41
+ "toc", # so we get anchors for h1 h2 etc
42
+ "tables",
43
+ ],
44
+ extension_configs={
45
+ "pymdownx.emoji": {
46
+ "emoji_index": _no_deep_copy_emojione,
47
+ },
48
+ "pymdownx.superfences": {
49
+ "custom_fences": [
50
+ {
51
+ "name": "mermaid",
52
+ "class": "mermaid",
53
+ "format": pymdownx.superfences.fence_div_format,
54
+ },
55
+ {
56
+ "name": "solara",
57
+ "class": "",
58
+ "validator": mkdocs_pycafe.validator,
59
+ "format": mkdocs_pycafe.formatter(type="solara", next_formatter=formatter(unsafe_solara_execute), inside_last_div=False),
60
+ },
61
+ {
62
+ "name": "python",
63
+ "class": "highlight",
64
+ "validator": mkdocs_pycafe.validator,
65
+ "format": mkdocs_pycafe.formatter(type="solara", next_formatter=formatter(unsafe_solara_execute), inside_last_div=False),
66
+ },
67
+ ],
68
+ },
69
+ },
70
+ )
71
+
72
+ md_parser = solara.use_memo(make_markdown_object, dependencies=[unsafe_solara_execute])
73
+
30
74
  with solara.v.Html(
31
75
  tag="div",
32
76
  style_="display: flex; flex-direction: row; justify-content: center; gap: 15px; max-width: 90%; margin: 0 auto;",
33
77
  attributes={"id": "markdown-to-navigate"},
34
78
  ):
35
- solara.Markdown(content, unsafe_solara_execute=unsafe_solara_execute, style="flex-grow: 1; max-width: min(100%, 1024px);")
79
+ solara.Markdown(content, unsafe_solara_execute=unsafe_solara_execute, style="flex-grow: 1; max-width: min(100%, 1024px);", md_parser=md_parser)
36
80
  MarkdownNavigation(id="markdown-to-navigate").key("markdown-nav" + str(hash(content)))
37
81
 
38
82
 
@@ -15,7 +15,9 @@ def Sidebar():
15
15
  break
16
16
 
17
17
  with solara.v.List(
18
- expand=True, nav=True, style_="height: 100%; display: flex; flex-direction: column; background-color: var(--color-material-background);"
18
+ expand=True,
19
+ nav=True,
20
+ style_="height: 100%; max-height: 100vh; display: flex; flex-direction: column; background-color: var(--color-material-background); overflow-y: auto;",
19
21
  ) as main:
20
22
  with solara.v.ListItemGroup(v_model=router.path):
21
23
  # e.g. getting_started, examples, components, api, advanced, faq
@@ -280,13 +280,19 @@ def Layout(children=[]):
280
280
  justify="center" if route_current is not None and route_current.path in ["documentation", "showcase"] else "start",
281
281
  ):
282
282
  if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
283
- with solara.v.NavigationDrawer(
284
- clipped=True,
285
- class_="d-none d-md-block",
286
- height="unset",
287
- style_="min-height: calc(100vh - 64px);",
288
- width="20rem",
289
- v_model=True, # Forces menu to display even if it had somehow been closed
283
+ with solara.v.Sheet(
284
+ style_="""
285
+ height: 100vh;
286
+ width: 20rem;
287
+ overflow: auto;
288
+ border-right: 1px solid var(--color-border-appbar);
289
+ position: sticky;
290
+ top: 0;
291
+ flex-direction: column;
292
+ gap: 0;
293
+ """,
294
+ class_="d-md-flex d-none",
295
+ elevation=0,
290
296
  ):
291
297
  route_current.module.Sidebar()
292
298
  with rv.Col(
@@ -1,5 +1,14 @@
1
1
  # Solara Changelog
2
2
 
3
+ ## Version 1.41.0
4
+ * Feature: Mutation detection is now available under the `SOLARA_STORAGE_MUTATION_DETECTION` environmental variable. [#595](https://github.com/widgetti/solara/pull/595).
5
+ * Feature: Autofocusing text inputs is now supported. [#788](https://github.com/widgetti/solara/pull/788).
6
+ * Feature: Custom colours are now supported for the Solara loading spinner. [#858](https://github.com/widgetti/solara/pull/858)
7
+ * Bug Fix: Echarts responsive size is now properly supported. [#273](https://github.com/widgetti/solara/pull/273).
8
+ * Bug Fix: Some version checks would prevent Solara from starting. [#904](https://github.com/widgetti/solara/pull/904).
9
+ * Bug Fix: Solara apps running in qt mode (`--qt`) should now always work correctly. [#856](https://github.com/widgetti/solara/pull/856).
10
+ * Bug Fix: Hot reloading of files outside working directory would crash app. [069a205](https://github.com/widgetti/solara/commit/069a205c88a8cbcb0b0ca23f4d56889c8ad6134a) and [#869](https://github.com/widgetti/solara/pull/869).
11
+
3
12
  ## Version 1.40.0
4
13
  * Feature: In Jupyter Notebook and Lab, Solara (server) now renders the [ipypopout](https://github.com/widgetti/ipypopout) window instead of Voila [#805](render ipypopout content in jupyter notebook and lab)
5
14
  * Feature: Support styling input field of [ChatInput component](https://solara.dev/documentation/components/lab/chat). [#800](https://github.com/widgetti/solara/pull/800).
@@ -196,7 +196,7 @@ Note that all routes are relative, since a component does not know if it is embe
196
196
 
197
197
 
198
198
  Therefore you should never use the `route.path` for navigation since the route object has no knowledge of the full url
199
- (e.g. `/docs/basics/ipywigets`) but only knows its small piece of the pathname (e.g. `ipywidgets`)
199
+ (e.g. `/docs/basics/ipywidgets`) but only knows its small piece of the pathname (e.g. `ipywidgets`)
200
200
 
201
201
  Using [`resolve_path`](/documentation/api/routing/resolve_path) we can request the full url for navigation.
202
202
 
@@ -219,6 +219,22 @@ def LinkToIpywidgets():
219
219
  return main
220
220
  ```
221
221
 
222
+ ### Linking to Sections of a Page
223
+
224
+ The `solara.Link` component also supports linking to HTML elements identified by id. Although most Solara components don't directly support the id attribute, you can assign ids to all ipyvuetify components, using the `attributes` argument:
225
+
226
+ ```python
227
+ solara.v.Btn(attributes={"id": "my-id"}, ...)
228
+ ```
229
+
230
+ You can then link to a particular element by appending `#` followed by its id to your link, i.e. `solara.Link(route_or_path="/page#my-id")`. If you want the page to smoothly scroll to the linked element, you should give an element that contains it (for instance the `html`-element) the following CSS rule:
231
+
232
+ ```css
233
+ html {
234
+ scroll-behaviour: smooth;
235
+ }
236
+ ```
237
+
222
238
  ## Fully manual routing
223
239
 
224
240
  If you want to do routing fully manually, you can use the [`solara.use_router`](/documentation/api/routing/use_router) hook, and use the `.path` attribute.
@@ -13,11 +13,10 @@ df = plotly.data.gapminder()
13
13
  @solara.component
14
14
  def Page():
15
15
  solara.provide_cross_filter()
16
- with solara.VBox() as main:
17
- solara.CrossFilterReport(df, classes=["py-2"])
18
- solara.CrossFilterSelect(df, "country")
19
- solara.CrossFilterDataFrame(df)
20
- return main
16
+
17
+ solara.CrossFilterReport(df, classes=["py-2"])
18
+ solara.CrossFilterSelect(df, "country")
19
+ solara.CrossFilterDataFrame(df)
21
20
 
22
21
 
23
22
  __doc__ += apidoc(solara.CrossFilterDataFrame.f) # type: ignore
@@ -12,11 +12,9 @@ df = plotly.data.gapminder()
12
12
  @solara.component
13
13
  def Page():
14
14
  solara.provide_cross_filter()
15
- with solara.VBox() as main:
16
- solara.CrossFilterReport(df, classes=["py-2"])
17
- solara.CrossFilterSelect(df, "country")
18
- solara.CrossFilterSlider(df, "gdpPercap", mode=">")
19
- return main
15
+ solara.CrossFilterReport(df, classes=["py-2"])
16
+ solara.CrossFilterSelect(df, "country")
17
+ solara.CrossFilterSlider(df, "gdpPercap", mode=">")
20
18
 
21
19
 
22
20
  __doc__ += apidoc(solara.CrossFilterReport.f) # type: ignore
@@ -12,11 +12,9 @@ df = plotly.data.tips()
12
12
  @solara.component
13
13
  def Page():
14
14
  solara.provide_cross_filter()
15
- with solara.VBox() as main:
16
- solara.CrossFilterReport(df, classes=["py-2"])
17
- solara.CrossFilterSelect(df, "sex")
18
- solara.CrossFilterSelect(df, "time")
19
- return main
15
+ solara.CrossFilterReport(df, classes=["py-2"])
16
+ solara.CrossFilterSelect(df, "sex")
17
+ solara.CrossFilterSelect(df, "time")
20
18
 
21
19
 
22
20
  __doc__ += apidoc(solara.CrossFilterSelect.f) # type: ignore
@@ -12,11 +12,9 @@ df = plotly.data.gapminder()
12
12
  @solara.component
13
13
  def Page():
14
14
  solara.provide_cross_filter()
15
- with solara.VBox() as main:
16
- solara.CrossFilterReport(df, classes=["py-2"])
17
- solara.CrossFilterSlider(df, "pop", mode=">")
18
- solara.CrossFilterSlider(df, "gdpPercap", mode="<")
19
- return main
15
+ solara.CrossFilterReport(df, classes=["py-2"])
16
+ solara.CrossFilterSlider(df, "pop", mode=">")
17
+ solara.CrossFilterSlider(df, "gdpPercap", mode="<")
20
18
 
21
19
 
22
20
  __doc__ += apidoc(solara.CrossFilterSlider.f) # type: ignore
@@ -15,11 +15,9 @@ df = plotly.data.gapminder()
15
15
  @solara.component
16
16
  def Page():
17
17
  solara.provide_cross_filter()
18
- with solara.VBox() as main:
19
- solara.CrossFilterReport(df, classes=["py-2"])
20
- solara.CrossFilterSelect(df, "continent")
21
- solara.CrossFilterSlider(df, "gdpPercap", mode=">")
22
- return main
18
+ solara.CrossFilterReport(df, classes=["py-2"])
19
+ solara.CrossFilterSelect(df, "continent")
20
+ solara.CrossFilterSlider(df, "gdpPercap", mode=">")
23
21
 
24
22
 
25
23
  __doc__ += apidoc(solara.use_cross_filter) # type: ignore
@@ -18,16 +18,14 @@ def Page():
18
18
  value_previous = solara.use_previous(value)
19
19
  exception, clear_exception = solara.use_exception()
20
20
  # print(exception)
21
- with solara.VBox() as main:
22
- if exception:
21
+ if exception:
23
22
 
24
- def reset():
25
- set_value(value_previous)
26
- clear_exception()
23
+ def reset():
24
+ set_value(value_previous)
25
+ clear_exception()
27
26
 
28
- solara.Text("Exception: " + str(exception))
29
- solara.Button(label="Go to previous state", on_click=reset)
30
- else:
31
- solara.IntSlider(value=value, min=0, max=10, on_value=set_value, label="Pick a number, except 3")
32
- UnstableComponent(value)
33
- return main
27
+ solara.Text("Exception: " + str(exception))
28
+ solara.Button(label="Go to previous state", on_click=reset)
29
+ else:
30
+ solara.IntSlider(value=value, min=0, max=10, on_value=set_value, label="Pick a number, except 3")
31
+ UnstableComponent(value)
@@ -20,14 +20,11 @@ title = "use_previous"
20
20
  def Page():
21
21
  value, set_value = solara.use_state(4)
22
22
  value_previous = solara.use_previous(value)
23
- with solara.VBox() as main:
24
- solara.IntSlider("value", value=value, on_value=set_value)
25
- solara.Markdown(
26
- f"""
27
- **Current**: `{value}`
23
+ solara.IntSlider("value", value=value, on_value=set_value)
24
+ solara.Markdown(
25
+ f"""
26
+ **Current**: `{value}`
28
27
 
29
- **Previous**: `{value_previous}`
28
+ **Previous**: `{value_previous}`
30
29
  """
31
- )
32
-
33
- return main
30
+ )
@@ -41,29 +41,26 @@ def Page():
41
41
  parent_value, set_parent_value = solara.use_state(4)
42
42
  # used to force rerenders
43
43
  rerender_counter, set_rerender_counter = solara.use_state(4)
44
- with solara.VBox() as main:
45
- with solara.Card("Parent value selection"):
46
- solara.Info("This slider value gets passed down to the child components")
47
- solara.IntSlider("parent value", value=parent_value, on_value=set_parent_value)
48
- solara.Button("Force redraw", on_click=lambda: set_rerender_counter(rerender_counter + 1))
49
-
50
- with solara.Card("Child without state"):
51
- solara.Info("This child will simply render the value passed into the argument, a redraw will reset it to its parent value.")
52
- SliderWithoutState(parent_value)
53
-
54
- with solara.Card("Child with state"):
55
- solara.Info("This child will not care about the value passed into the prop, it manages its own state.")
56
- SliderWithState(parent_value)
57
-
58
- with solara.Card("Child with state (or update)"):
59
- solara.Info("This child will update when the passes in a new value, but a redraw will not reset it.")
60
- SliderWithStateOrUpdate(parent_value)
61
-
62
- with solara.Card("Child with state + key"):
63
- solara.Info(
64
- "We can also use the `.key(...)` method to force the component to forget its state, this will however cause the widget to be re-created"
65
- "(a performance penalty)."
66
- )
67
- SliderWithState(parent_value).key(f"slider-{parent_value}")
68
-
69
- return main
44
+ with solara.Card("Parent value selection"):
45
+ solara.Info("This slider value gets passed down to the child components")
46
+ solara.IntSlider("parent value", value=parent_value, on_value=set_parent_value)
47
+ solara.Button("Force redraw", on_click=lambda: set_rerender_counter(rerender_counter + 1))
48
+
49
+ with solara.Card("Child without state"):
50
+ solara.Info("This child will simply render the value passed into the argument, a redraw will reset it to its parent value.")
51
+ SliderWithoutState(parent_value)
52
+
53
+ with solara.Card("Child with state"):
54
+ solara.Info("This child will not care about the value passed into the prop, it manages its own state.")
55
+ SliderWithState(parent_value)
56
+
57
+ with solara.Card("Child with state (or update)"):
58
+ solara.Info("This child will update when the passes in a new value, but a redraw will not reset it.")
59
+ SliderWithStateOrUpdate(parent_value)
60
+
61
+ with solara.Card("Child with state + key"):
62
+ solara.Info(
63
+ "We can also use the `.key(...)` method to force the component to forget its state, this will however cause the widget to be re-created"
64
+ "(a performance penalty)."
65
+ )
66
+ SliderWithState(parent_value).key(f"slider-{parent_value}")
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  from typing import Optional, cast
4
4
 
5
5
  import solara
6
- from solara.alias import rv, rw
6
+ from solara.alias import rw
7
7
 
8
8
  HERE = Path(__file__).parent
9
9
  title = "use_thread"
@@ -29,16 +29,14 @@ def Page():
29
29
  # work will be cancelled/restarted every time the dependency changes
30
30
  result: solara.Result[bool] = solara.use_thread(work, dependencies=[number])
31
31
 
32
- with solara.VBox() as main:
33
- rw.IntText(value=number, on_value=set_number)
34
- if result.state == solara.ResultState.FINISHED:
35
- if result.value:
36
- solara.Success(f"{number} is a prime!")
37
- else:
38
- solara.Error(f"{number} is not a prime, it can be divided by {proof} ")
39
- elif result.state == solara.ResultState.ERROR:
40
- solara.Error(f"Error occurred: {result.error}")
32
+ rw.IntText(value=number, on_value=set_number)
33
+ if result.state == solara.ResultState.FINISHED:
34
+ if result.value:
35
+ solara.Success(f"{number} is a prime!")
41
36
  else:
42
- solara.Info(f"Running... (status = {result.state})")
43
- rv.ProgressLinear(indeterminate=True)
44
- return main
37
+ solara.Error(f"{number} is not a prime, it can be divided by {proof} ")
38
+ elif result.state == solara.ResultState.ERROR:
39
+ solara.Error(f"Error occurred: {result.error}")
40
+ else:
41
+ solara.Info(f"Running... (status = {result.state})")
42
+ solara.v.ProgressLinear(indeterminate=True)
@@ -19,6 +19,23 @@ The return value of on_kernel_start is a cleanup function that will remove the c
19
19
 
20
20
  During hot reload, the callbacks that are added from scripts or modules that will be reloaded will be removed before the app is loaded
21
21
  again. This can cause the order of the callbacks to be different than at first run.
22
+
23
+ ## Example
24
+
25
+ ```
26
+ import solara
27
+ import solara.lab
28
+
29
+
30
+ @solara.lab.on_kernel_start
31
+ def on_kernel_start():
32
+ id = solara.get_kernel_id()
33
+ print("Kernel started", id)
34
+ def cleanup():
35
+ print("Kernel stopped", id)
36
+ return cleanup # this function will be called on kernel shutdown
37
+ ```
38
+
22
39
  """
23
40
 
24
41
  from solara.website.components import NoPage
@@ -19,3 +19,25 @@ __doc__ += "# InputFloat"
19
19
  __doc__ += apidoc(solara.InputFloat.f) # type: ignore
20
20
  __doc__ += "# InputInt"
21
21
  __doc__ += apidoc(solara.InputInt.f) # type: ignore
22
+
23
+ __doc__ += """
24
+ # Autofocus Example
25
+
26
+ ```solara
27
+ import solara
28
+ import solara.lab
29
+
30
+
31
+ @solara.component
32
+ def Page():
33
+ show_dialog = solara.use_reactive(False)
34
+ show_conditional = solara.use_reactive(False)
35
+ with solara.Row():
36
+ solara.Button("Show dialog", on_click=lambda: show_dialog.set(True))
37
+ solara.Button("Show conditionally rendered element", on_click=lambda: show_conditional.set(not show_conditional.value))
38
+ with solara.lab.ConfirmationDialog(open=show_dialog):
39
+ solara.InputFloat("Float here", autofocus=True)
40
+ if show_conditional.value:
41
+ solara.InputFloat("Float here", autofocus=True)
42
+ ```
43
+ """
@@ -63,7 +63,9 @@ def Page():
63
63
  with solara.ToggleButtonsSingle("bars", on_value=set_option):
64
64
  solara.Button("bars")
65
65
  solara.Button("pie")
66
- solara.FigureEcharts(option=options[option], on_click=set_click_data, on_mouseover=set_mouseover_data, on_mouseout=set_mouseout_data)
66
+ solara.FigureEcharts(
67
+ option=options[option], on_click=set_click_data, on_mouseover=set_mouseover_data, on_mouseout=set_mouseout_data, responsive=True
68
+ )
67
69
  with solara.Card("Event data"):
68
70
  solara.Markdown(f"**Click data**: {click_data}")
69
71
  solara.Markdown(f"**Mouseover data**: {mouseover_data}")
@@ -25,28 +25,20 @@ def Layout(children):
25
25
  assert module is not None
26
26
  github_url = solara.util.github_url(module.__file__)
27
27
 
28
- with solara.HBox(grow=False) as main:
29
- if route_current.path == "fullscreen":
30
- with solara.Padding(4, children=children):
31
- pass
32
- else:
33
- with solara.VBox(grow=True, align_items="baseline"):
34
- doc = module.__doc__
35
- if doc:
36
- with solara.VBox(grow=True):
37
- MarkdownWithMetadata(doc)
38
- with solara.HBox():
39
- if route_current.path != "/":
40
- solara.Button("View source code on GitHub", icon_name="mdi-github-circle", href=github_url, class_="ma-2", target="_blank", text=True)
41
- # code = inspect.getsource(module)
42
-
43
- # code_quoted = urllib.parse.quote_plus(code)
44
- # url = f"https://test.solara.dev/try?code={code_quoted}"
45
- # solara.Button("Run on solara.dev", icon_name="mdi-pencil", href=url, class_="ma-2", target="_blank")
46
- # with solara.HBox():
28
+ if route_current.path == "fullscreen":
29
+ with solara.Padding(4, children=children):
30
+ pass
31
+ else:
32
+ with solara.Column(align="center", style={"max-width": "100%"}):
33
+ doc = module.__doc__
34
+ if doc:
35
+ with solara.Column():
36
+ MarkdownWithMetadata(doc)
37
+ with solara.Column(style={"max-width": "min(100%, 1024px)", "width": "100%"}):
38
+ if route_current.path != "/":
39
+ solara.Button("View source code on GitHub", icon_name="mdi-github-circle", href=github_url, class_="ma-2", target="_blank", text=True)
47
40
  if not hasattr(module, "Page"):
48
41
  solara.Error(f"No Page component found in {module}")
49
42
  else:
50
- with solara.Padding(4, children=children):
43
+ with solara.Div(children=children):
51
44
  pass
52
- return main
@@ -77,7 +77,7 @@ def Page():
77
77
  task = solara.lab.use_task(call_openai, dependencies=[user_message_count]) # type: ignore
78
78
 
79
79
  with solara.Column(
80
- style={"width": "700px", "height": "50vh"},
80
+ style={"width": "100%", "height": "50vh"},
81
81
  ):
82
82
  with solara.lab.ChatBox():
83
83
  for item in messages.value:
@@ -10,8 +10,8 @@ from solara import use_fetch
10
10
  from solara.alias import rv
11
11
 
12
12
  github_url = solara.util.github_url(__file__)
13
-
14
- json_url = "https://jherr-pokemon.s3.us-west-1.amazonaws.com/index.json"
13
+ pokemon_base_url = "https://raw.githubusercontent.com/jherr/pokemon/0722479d4153b1db0d0326956b08b37f44a95a5f"
14
+ json_url = f"{pokemon_base_url}/index.json"
15
15
 
16
16
 
17
17
  @solara.component
@@ -40,7 +40,7 @@ def Page():
40
40
  for pokemon in pokemons[:20]:
41
41
  with solara.Div():
42
42
  name = pokemon["name"]
43
- url = "https://jherr-pokemon.s3.us-west-1.amazonaws.com/" + pokemon["image"]
43
+ url = f'{pokemon_base_url}/{pokemon["image"]}'
44
44
  # TODO: how to do this with solara
45
45
  rv.Img(src=url, contain=True, max_height="200px")
46
46
  solara.Text(name)
@@ -35,7 +35,7 @@ def Page():
35
35
  sales_data = np.floor(np.cumsum(gen.random(7) - 0.5) * 100 + 100)
36
36
  show_report = solara.use_reactive(False)
37
37
 
38
- with solara.Column(style={"min-width": "600px"}):
38
+ with solara.Column():
39
39
  if show_report.value:
40
40
  with solara.Card("Report"):
41
41
  solara.Markdown("Lorum ipsum dolor sit amet")
@@ -38,6 +38,7 @@ def Page():
38
38
  )
39
39
  .configure_view(step=13, strokeWidth=0)
40
40
  .configure_axis(domain=False)
41
+ .properties(width="container")
41
42
  )
42
43
  with solara.Card("Annual Weather Heatmap for Seattle, WA"):
43
44
  solara.AltairChart(chart, on_click=on_click)
@@ -34,6 +34,6 @@ def Page(x=x0, ymax=5):
34
34
  lines = bqplot.Lines(x=x, y=y, scales={"x": x_scale, "y": y_scale}, stroke_width=3, colors=[color], display_legend=display_legend, labels=[label])
35
35
  x_axis = bqplot.Axis(scale=x_scale)
36
36
  y_axis = bqplot.Axis(scale=y_scale, orientation="vertical")
37
- bqplot.Figure(axes=[x_axis, y_axis], marks=[lines], scale_x=x_scale, scale_y=y_scale, layout={"min_width": "800px"})
37
+ bqplot.Figure(axes=[x_axis, y_axis], marks=[lines], scale_x=x_scale, scale_y=y_scale, layout={"max_width": "100%", "width": "100%"})
38
38
 
39
39
  # return main
@@ -15,7 +15,7 @@ bounds = solara.reactive(None)
15
15
  @solara.component
16
16
  def Page():
17
17
  # Isolation is required to prevent the map from overlapping navigation (when screen width < 960px)
18
- with solara.Column(style={"min-width": "500px", "height": "500px", "isolation": "isolate"}):
18
+ with solara.Column(style={"width": "100%", "height": "500px", "isolation": "isolate"}):
19
19
  # solara components support reactive variables
20
20
  solara.SliderInt(label="Zoom level", value=zoom, min=1, max=20)
21
21
  # using 3rd party widget library require wiring up the events manually
@@ -31,7 +31,7 @@ def Page():
31
31
  # do things with the location
32
32
  marker_location.set(location)
33
33
 
34
- with solara.Column(style={"min-width": "500px", "height": "500px"}):
34
+ with solara.Column(style={"width": "100%", "height": "500px"}):
35
35
  solara.Markdown(f"Market set to: {marker_location.value}", style={"color": "#6e6e6e"})
36
36
 
37
37
  map = maps[map_name.value]