solara-ui 1.39.0__py2.py3-none-any.whl → 1.41.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 (85) hide show
  1. solara/__init__.py +1 -1
  2. solara/__main__.py +23 -10
  3. solara/components/__init__.py +1 -0
  4. solara/components/component_vue.py +3 -2
  5. solara/components/input_text_area.py +86 -0
  6. solara/components/markdown.py +1 -1
  7. solara/hooks/use_thread.py +4 -4
  8. solara/lab/components/chat.py +8 -2
  9. solara/server/assets/style.css +4 -1
  10. solara/server/flask.py +1 -1
  11. solara/server/jupyter/server_extension.py +11 -1
  12. solara/server/jupyter/solara.py +91 -0
  13. solara/server/patch.py +1 -0
  14. solara/server/pyinstaller/__init__.py +9 -0
  15. solara/server/pyinstaller/hook-ipyreact.py +5 -0
  16. solara/server/pyinstaller/hook-ipyvuetify.py +5 -0
  17. solara/server/pyinstaller/hook-solara.py +9 -0
  18. solara/server/qt.py +113 -0
  19. solara/server/server.py +6 -1
  20. solara/server/settings.py +1 -0
  21. solara/server/starlette.py +18 -6
  22. solara/server/static/highlight-dark.css +1 -1
  23. solara/server/static/main-vuetify.js +11 -1
  24. solara/server/static/solara_bootstrap.py +1 -1
  25. solara/server/templates/loader-solara.html +1 -1
  26. solara/server/templates/solara.html.j2 +36 -7
  27. solara/website/assets/custom.css +20 -57
  28. solara/website/components/__init__.py +2 -2
  29. solara/website/components/algolia_api.vue +23 -6
  30. solara/website/components/breadcrumbs.py +28 -0
  31. solara/website/components/contact.py +144 -0
  32. solara/website/components/docs.py +11 -9
  33. solara/website/components/header.py +31 -20
  34. solara/website/components/markdown.py +12 -1
  35. solara/website/components/markdown_nav.vue +34 -0
  36. solara/website/components/sidebar.py +9 -1
  37. solara/website/pages/__init__.py +93 -254
  38. solara/website/pages/about/__init__.py +9 -0
  39. solara/website/pages/about/about.md +3 -0
  40. solara/website/pages/careers/__init__.py +27 -0
  41. solara/website/pages/changelog/__init__.py +2 -2
  42. solara/website/pages/changelog/changelog.md +12 -0
  43. solara/website/pages/contact/__init__.py +30 -6
  44. solara/website/pages/documentation/__init__.py +25 -33
  45. solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +2 -1
  46. solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +1 -1
  47. solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +17 -1
  48. solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +2 -1
  49. solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +1 -1
  50. solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +5 -2
  51. solara/website/pages/documentation/api/hooks/use_thread.md +6 -0
  52. solara/website/pages/documentation/components/data/pivot_table.py +2 -2
  53. solara/website/pages/documentation/components/input/input.py +2 -0
  54. solara/website/pages/documentation/components/output/sql_code.py +3 -3
  55. solara/website/pages/documentation/examples/__init__.py +14 -22
  56. solara/website/pages/documentation/examples/ai/chatbot.py +1 -1
  57. solara/website/pages/documentation/examples/general/vue_component.py +1 -1
  58. solara/website/pages/documentation/examples/libraries/altair.py +1 -0
  59. solara/website/pages/documentation/examples/libraries/bqplot.py +1 -1
  60. solara/website/pages/documentation/examples/libraries/ipyleaflet.py +1 -1
  61. solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +1 -1
  62. solara/website/pages/documentation/examples/utilities/countdown_timer.py +18 -20
  63. solara/website/pages/documentation/examples/visualization/annotator.py +1 -3
  64. solara/website/pages/documentation/examples/visualization/linked_views.py +4 -4
  65. solara/website/pages/documentation/getting_started/content/00-quickstart.md +18 -0
  66. solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +2 -2
  67. solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +19 -14
  68. solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +205 -15
  69. solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +3 -1
  70. solara/website/pages/home.vue +1199 -0
  71. solara/website/pages/our_team/__init__.py +83 -0
  72. solara/website/pages/pricing/__init__.py +31 -0
  73. solara/website/pages/roadmap/__init__.py +11 -0
  74. solara/website/pages/roadmap/roadmap.md +41 -0
  75. solara/website/pages/scale_ipywidgets.py +45 -0
  76. solara/widgets/vue/navigator.vue +46 -16
  77. solara/widgets/vue/vegalite.vue +18 -0
  78. {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/METADATA +2 -2
  79. {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/RECORD +83 -66
  80. solara/website/components/hero.py +0 -15
  81. solara/website/pages/contact/contact.md +0 -17
  82. {solara_ui-1.39.0.data → solara_ui-1.41.0.data}/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -0
  83. {solara_ui-1.39.0.data → solara_ui-1.41.0.data}/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -0
  84. {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/WHEEL +0 -0
  85. {solara_ui-1.39.0.dist-info → solara_ui-1.41.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,6 @@
1
1
  import solara
2
- from solara.alias import rv
2
+ from .markdown import MarkdownWithMetadata
3
+ from .breadcrumbs import BreadCrumbs
3
4
 
4
5
 
5
6
  @solara.component
@@ -66,18 +67,19 @@ def NoPage():
66
67
 
67
68
 
68
69
  @solara.component
69
- def WithCode(module):
70
- component = getattr(module, "Page", None)
71
- with rv.Sheet() as main:
70
+ def WithCode(route_current):
71
+ component = getattr(route_current.module, "Page", None)
72
+ with solara.Column(style={"flex-grow": 1, "padding-top": "56px"}) as main:
73
+ BreadCrumbs()
72
74
  # It renders code better
73
- solara.Markdown(
74
- module.__doc__ or "# no docs yet",
75
+ MarkdownWithMetadata(
76
+ route_current.module.__doc__ or "# no docs yet",
75
77
  unsafe_solara_execute=True,
76
78
  )
77
79
  if component and component != NoPage:
78
80
  with solara.Card("Example", margin=0, classes=["mt-8"]):
79
81
  component()
80
- github_url = solara.util.github_url(module.__file__)
82
+ github_url = solara.util.github_url(route_current.module.__file__)
81
83
  solara.Button(
82
84
  label="View source",
83
85
  icon_name="mdi-github-circle",
@@ -97,7 +99,7 @@ def SubCategoryLayout(children=[]):
97
99
  elif route_current.path == "/":
98
100
  return solara.Error("Not supposed to be rendered")
99
101
  elif route_current.module:
100
- WithCode(route_current.module)
102
+ WithCode(route_current)
101
103
  else:
102
104
  with solara.Column(align="center", children=children, style={"flex-grow": 1, "padding": "0"}) as main:
103
105
  pass
@@ -113,6 +115,6 @@ def CategoryLayout(children=[]):
113
115
  if route_current.path == "/":
114
116
  return Gallery()
115
117
  else:
116
- with solara.Column(align="stretch", style={"width": "1024px", "flex-grow": 1}, children=children) as main:
118
+ with solara.Column(align="stretch", children=children, style={"max-width": "100%"}) as main:
117
119
  pass
118
120
  return main
@@ -20,34 +20,44 @@ def Header(
20
20
 
21
21
  # set states for menu
22
22
  with solara.Column(gap="0px"):
23
- with solara.Div(classes=["news"]):
24
- solara.HTML(
25
- "div",
26
- unsafe_innerHTML="<a href='https://github.com/widgetti/solara' target='_blank' >Star us on github 🤩</a>",
27
- )
28
- with solara.v.AppBar(tag="header", flat=True, class_="bg-primary-fade padding-40", height="auto", clipped_left=True):
29
- with rv.ToolbarTitle(class_="d-flex", style_="align-items:center"):
30
- if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
31
- with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_left_menu and on_toggle_left_menu()):
32
- rv.Icon(children=["mdi-menu"])
23
+ # with solara.Div(classes=["news"]):
24
+ # solara.HTML(
25
+ # "div",
26
+ # unsafe_innerHTML="<a href='https://github.com/widgetti/solara' target='_blank' >Star us on github 🤩</a>",
27
+ # )
28
+ with solara.v.AppBar(
29
+ tag="header", flat=True, clipped_left=True, style_="background-color: transparent; border-bottom: 1px solid var(--color-border-appbar);"
30
+ ):
31
+ if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
32
+ with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_left_menu and on_toggle_left_menu()):
33
+ rv.Icon(children=["mdi-menu"])
33
34
 
34
- with solara.Row(
35
- justify="start", classes=["header-logo-container"], style={"flex-grow": "1", "background-color": "transparent", "align-items": "center"}
35
+ display = " d-none d-sm-flex" if route_current is not None and route_current.path not in ["about", "pricing", "careers"] else " d-flex"
36
+ with solara.v.Html(
37
+ tag="div",
38
+ class_="header-logo-container" + display,
39
+ style_="""
40
+ background-color: transparent;
41
+ flex-grow: 1;
42
+ align-items: stretch;
43
+ max-height: 65%;
44
+ """,
36
45
  ):
37
- with solara.Link(path_or_route="/"):
46
+ with solara.Link(path_or_route="/", style={"display": "flex", "align-items": "center", "flex-direction": "row", "gap": "10px"}):
38
47
  solara.Image(router.root_path + f"/static/assets/images/logo{'_white' if dark_effective else ''}.svg", classes=["header-logo"])
48
+ solara.Text("API", style={"font-size": "20px", "font-weight": "600"})
39
49
 
40
- with rv.Html(tag="ul", class_="main-menu menu d-none d-md-flex", style_="flex-grow: 1;"):
50
+ if route_current is not None and route_current.path not in ["about", "pricing", "careers"]:
41
51
  if settings.search.enabled:
42
52
  from solara_enterprise.search.search import Search
43
53
 
44
54
  Search()
45
55
  else:
46
- with solara.Row(justify="end", style={"align-items": "center", "flex-grow": "1", "background-color": "transparent"}):
47
- Algolia()
56
+ Algolia()
48
57
 
58
+ with rv.Html(tag="ul", class_="main-menu menu d-none d-md-flex", style_="justify-content: flex-end;"):
49
59
  for route in all_routes:
50
- if route.path in ["apps", "contact", "changelog"]:
60
+ if route.path in ["apps", "contact", "changelog", "our_team", "about", "pricing", "roadmap", "careers"]:
51
61
  continue
52
62
  current = route_current == route
53
63
  with rv.Html(tag="li", class_="active" if current else None):
@@ -58,7 +68,8 @@ def Header(
58
68
  with rv.Btn(icon=True, tag="a", class_="d-none d-md-flex", attributes={"href": "https://discord.solara.dev", "target": "_blank"}):
59
69
  rv.Icon(children=["mdi-discord"])
60
70
 
61
- solara.lab.ThemeToggle()
71
+ with solara.v.Html(tag="div", class_="d-none d-md-flex"):
72
+ solara.lab.ThemeToggle()
62
73
 
63
- with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_right_menu and on_toggle_right_menu()):
64
- rv.Icon(children=["mdi-menu"])
74
+ # with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_right_menu and on_toggle_right_menu()):
75
+ # rv.Icon(children=["mdi-menu"])
@@ -27,4 +27,15 @@ def MarkdownWithMetadata(content: str, unsafe_solara_execute=True):
27
27
  solara.Meta(property=key, content=value)
28
28
  else:
29
29
  solara.Meta(name=key, content=value)
30
- solara.Markdown(content, unsafe_solara_execute=unsafe_solara_execute)
30
+ with solara.v.Html(
31
+ tag="div",
32
+ style_="display: flex; flex-direction: row; justify-content: center; gap: 15px; max-width: 90%; margin: 0 auto;",
33
+ attributes={"id": "markdown-to-navigate"},
34
+ ):
35
+ solara.Markdown(content, unsafe_solara_execute=unsafe_solara_execute, style="flex-grow: 1; max-width: min(100%, 1024px);")
36
+ MarkdownNavigation(id="markdown-to-navigate").key("markdown-nav" + str(hash(content)))
37
+
38
+
39
+ @solara.component_vue("markdown_nav.vue")
40
+ def MarkdownNavigation(id: str):
41
+ pass
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <v-list dense :style="`margin: 40px 24px 0 24px; position: sticky; top: 88px; align-self: flex-start;`" class="d-none d-lg-inline-block">
3
+ <v-list-item
4
+ v-for="(element, index) in this.sections"
5
+ :key="index"
6
+ :href="'#' + element.id"
7
+ :style="'padding-left: ' + (16 + (element.nodeName[1] - 1) * 20) + 'px;'"
8
+ >
9
+ <v-list-item-content>
10
+ <v-list-item-title>
11
+ {{ element.innerText }}
12
+ </v-list-item-title>
13
+ </v-list-item-content>
14
+ </v-list-item>
15
+ </v-list>
16
+ </template>
17
+ <script>
18
+ module.exports = {
19
+ mounted() {
20
+ this.getSections();
21
+ },
22
+ methods: {
23
+ getSections() {
24
+ const parentToSearch = document.getElementById(this.id);
25
+ this.sections = parentToSearch.querySelectorAll('h1, h2, h3, h4');
26
+ },
27
+ },
28
+ data() {
29
+ return {
30
+ sections: []
31
+ }
32
+ }
33
+ }
34
+ </script>
@@ -14,7 +14,11 @@ def Sidebar():
14
14
  all_routes = route.children
15
15
  break
16
16
 
17
- with solara.v.List(expand=True, nav=True, style_="height: 100%; display: flex; flex-direction: column;") as main:
17
+ with solara.v.List(
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;",
21
+ ) as main:
18
22
  with solara.v.ListItemGroup(v_model=router.path):
19
23
  # e.g. getting_started, examples, components, api, advanced, faq
20
24
  for route in all_routes:
@@ -93,5 +97,9 @@ def Sidebar():
93
97
  with solara.v.ListItem(value="/changelog"):
94
98
  solara.v.ListItemIcon(children=[solara.v.Icon(children=["mdi-history"])])
95
99
  solara.v.ListItemTitle(style_="padding: 0 20px;", children=["Changelog"])
100
+ with solara.Link("/roadmap"):
101
+ with solara.v.ListItem(value="/roadmap"):
102
+ solara.v.ListItemIcon(children=[solara.v.Icon(children=["mdi-road"])])
103
+ solara.v.ListItemTitle(style_="padding: 0 20px;", children=["Roadmap"])
96
104
 
97
105
  return main
@@ -5,12 +5,11 @@ from solara.components.title import Title
5
5
  from solara.server import server
6
6
  from solara.website.components.algolia import Algolia
7
7
 
8
- from ..components import Header, Hero
9
- from ..components.mailchimp import MailChimp
8
+ from ..components import Header
10
9
 
11
10
  title = "Home"
12
11
 
13
- route_order = ["/", "showcase", "documentation", "apps", "contact", "changelog"]
12
+ route_order = ["/", "showcase", "documentation", "apps", "contact", "changelog", "roadmap", "pricing", "our_team", "careers", "about", "scale_ipywidgets"]
14
13
 
15
14
 
16
15
  _redirects = {
@@ -236,6 +235,11 @@ def List(children=[], class_: str = None):
236
235
  return rv.Html(tag="ul", children=children, attributes={"class": class_})
237
236
 
238
237
 
238
+ @solara.component_vue("home.vue")
239
+ def Home(children=[]):
240
+ pass
241
+
242
+
239
243
  @solara.component
240
244
  def Layout(children=[]):
241
245
  router = solara.use_router()
@@ -247,265 +251,100 @@ def Layout(children=[]):
247
251
 
248
252
  target, set_target = solara.use_state(0)
249
253
 
250
- if route_current and route_current.path == "apps":
254
+ if route_current is not None:
255
+ with solara.Div(style={"display": "none"}):
256
+ solara.Meta(name="twitter:card", content="summary_large_image")
257
+ solara.Meta(name="twitter:site", content="@solara_dev")
258
+ solara.Meta(name="twitter:image", content="https://solara.dev/static/assets/images/logo-small.png")
259
+ solara.Meta(property="og:url", content="https://solara.dev" + router.path)
260
+ solara.Meta(property="og:image", content="https://solara.dev/static/assets/images/logo-small.png")
261
+ solara.Meta(property="og:type", content="website")
262
+ if route_current is not None and route_current.path == "apps":
251
263
  return children[0]
252
- with solara.VBox(grow=False) as main:
253
- Title(title="Solara documentation")
254
- solara.Meta(name="twitter:card", content="summary_large_image")
255
- solara.Meta(name="twitter:site", content="@solara_dev")
256
- solara.Meta(name="twitter:image", content="https://solara.dev/static/assets/images/logo-small.png")
257
- solara.Meta(property="og:url", content="https://solara.dev" + router.path)
258
- solara.Meta(property="og:image", content="https://solara.dev/static/assets/images/logo-small.png")
259
- solara.Meta(property="og:type", content="website")
260
- Header(
261
- on_toggle_left_menu=lambda: set_show_left_menu(not show_left_menu),
262
- on_toggle_right_menu=lambda: set_show_right_menu(not show_right_menu),
263
- )
264
- if route_current is not None and route_current.path == "/":
265
- Hero(
266
- title="A pure Python, React-style web framework",
267
- sub_title="Solara helps you build powerful & scalable Jupyter and web apps <b>faster</b> and <b>easier</b>.",
268
- button_text="Quickstart",
264
+ elif route_current is not None and route_current.path == "/":
265
+ Title(title="Solara: Build high-quality web applications in pure Python")
266
+ Home()
267
+ else:
268
+ with solara.VBox(grow=False) as main:
269
+ Title(title="Solara documentation")
270
+ Header(
271
+ on_toggle_left_menu=lambda: set_show_left_menu(not show_left_menu),
272
+ on_toggle_right_menu=lambda: set_show_right_menu(not show_right_menu),
269
273
  )
270
-
271
- with rv.Container(tag="section", fluid=True, ma_0=True, pa_0=True, class_="fill-height solara-content-main"):
272
- if route_current is None:
273
- return solara.Error("Page not found")
274
- elif route_current.path == "/":
275
- description = "Use ipywidgets with Solara to build powerful and scalable web apps for Jupyter and production in Python."
276
- # both tags in one
277
- solara.Meta(name="description", property="og:description", content=description)
278
- solara.Meta(name="twitter:description", content=description)
279
- solara.Meta(property="og:title", content="Solara documentation")
280
- solara.Meta(name="twitter:title", content="Solara documentation")
281
-
282
- with rv.Row(class_="ma-2"):
283
- with rv.Col(md=6, offset_md=3, sm=8, offset_sm=2):
284
- solara.Markdown(
285
- """
286
- # What is Solara?
287
-
288
- Solara lets you build web apps from pure Python using ipywidgets or a React-like API on
289
- top of ipywidgets.
290
- These apps work both inside the Jupyter Notebook and as standalone web apps with frameworks like FastAPI.
291
-
292
- With Solara, you benefit from a paradigm that promotes component-based code and simplifies state management,
293
- making your development process more efficient and your applications more maintainable.
294
-
295
- Solara provides you with access to the full strength of the Python ecosystem.
296
- This means you can continue using your favorite libraries while expanding your web development capabilities.
297
- """
298
- )
299
- with solara.HBox():
300
- with solara.Link("/documentation"):
301
- solara.Button(label="Read more", class_="ma-1 homepage-button", href="/documentation", color="primary", dark=True)
302
- with solara.Link("/documentation/getting_started"):
303
- solara.Button(label="Quickstart", class_="ma-1 homepage-button", color="primary", dark=True)
304
- # with rv.Col(md=4, sm=5):
305
- # rv.Img(src="https://dxhl76zpt6fap.cloudfront.net/public/landing/what.webp", style_="width:900px")
306
-
307
- with solara.Column(style={"width": "100%"}, gap="2.5em", classes=["pt-10", "mt-8"], align="center"):
308
- with solara.Row(justify="center", gap="2.5em", classes=["ma-2", "row-container"]):
309
- rv.Img(src="https://dxhl76zpt6fap.cloudfront.net/public/landing/complexity.webp", contain=True)
310
- solara.Markdown(
311
- """
312
- # Build **large** apps with **low** code complexity
313
-
314
- With Solara, you can build large scale apps without hitting a complexity wall.
315
-
316
- With other tools you may hit a dead end due to missing features or implementing features
317
- adds too much complexity to your code base.
318
-
319
- Solara offers the **flexibility** to build complex apps, but keeps the **simplicity** of a small code base.
320
- """
321
- )
322
- with solara.Row(justify="center", gap="2.5em", classes=["ma-2", "row-container"]):
323
- solara.Markdown(
324
- """
325
- # The trustworthiness of React
326
-
327
- Using the same API as React, but ported to Python, Solara lets you build apps with the same
328
- trustworthiness as React.
329
-
330
- With a decade of experience, React is battle-tested and proven to be
331
- a reliable and robust framework to build large scale apps.
332
- """
333
- )
334
- with solara.Row(justify="center", style={"width": "500px"}):
335
- rv.Img(src="https://dxhl76zpt6fap.cloudfront.net/public/landing/python-love-react.webp", style_="max-width:300px", contain=True)
336
- with solara.Row(justify="center", gap="2.5em", classes=["ma-2", "row-container"]):
337
- with solara.Column():
338
- if target == 0:
339
- solara.Markdown("#### Running in: Jupyter notebook")
340
- solara.Image(
341
- "https://global.discourse-cdn.com/standard11/uploads/jupyter/original/2X/8/8bc875c0c3845ae077168575a4f8a49cf1b35bc6.gif"
342
- )
343
- else:
344
- solara.Markdown("#### Running in: FastAPI")
345
- solara.Image(
346
- "https://global.discourse-cdn.com/standard11/uploads/jupyter/original/2X/9/9442fc70e2a1fcd201f4f900fa073698a1f8c937.gif"
347
- )
348
- import solara.website.pages.apps.scatter as scatter
349
-
350
- github_url = solara.util.github_url(scatter.__file__)
351
- solara.Button(
352
- label="View source",
353
- icon_name="mdi-github-circle",
354
- attributes={"href": github_url, "target": "_blank"},
355
- text=True,
356
- outlined=False,
357
- )
358
- with solara.Link("/documentation/examples"):
359
- with solara.Column(style="width: 100%;"):
360
- solara.Button(
361
- label="More examples",
362
- icon_name="mdi-brain",
363
- text=True,
364
- outlined=False,
365
- )
366
- with solara.Column():
367
- solara.Markdown(
368
- """
369
- ## Create apps
370
-
371
- In Jupyter or standalone, and run them in production
372
- using FastAPI or starlette.
373
-
374
- Get more inspiration from our [examples](/documentation/examples).
375
- """
376
- )
377
- with rv.ExpansionPanels(v_model=target, on_v_model=set_target, mandatory=True, flat=True):
378
- with rv.ExpansionPanel():
379
- rv.ExpansionPanelHeader(children=["Jupyter notebook"])
380
- with rv.ExpansionPanelContent():
381
- solara.Markdown("Build on top of ipywidgets, solara components work in all Jupyter notebook environments.")
382
- with rv.ExpansionPanel():
383
- rv.ExpansionPanelHeader(children=["FastAPI"])
384
- with rv.ExpansionPanelContent():
385
- solara.Markdown(
386
- """Using [solara-server](documentation/advanced/understanding/solara-server),
387
- we can run our app in production using FastAPI."""
388
- )
389
-
390
- with solara.Column(style={"width": "100%"}):
391
- solara.v.Divider()
392
-
393
- with solara.Column(align="center", gap="2.5em", style={"width": "100%", "padding-bottom": "50px"}):
394
- solara.Markdown("# Testimonials", style="text-align:center")
395
- with solara.Row(justify="center", gap="2.5em", style={"align-items": "stretch", "flex-wrap": "wrap", "row-gap": "2.5em"}):
396
- Testimonial(
397
- "Solara is like streamlit, but for Jupyter. I am really excited to see where this goes!",
398
- "Jack Parmer",
399
- "Former CEO and Co-Founder of Plotly",
400
- "https://dxhl76zpt6fap.cloudfront.net/public/avatar/jack-parmer.jpg",
401
- )
402
- Testimonial(
403
- "Solara has been transformative, allowing us to rapidly create a Jupyter app and iterate with impressive speed.",
404
- "Nick Elprin",
405
- "CEO and Co-Founder of Domino Data Lab",
406
- "https://dxhl76zpt6fap.cloudfront.net/public/avatar/nick-elprin.jpg",
407
- )
408
- Testimonial(
409
- "Solara allows us to go from prototype to production with the same stack.",
410
- "Jonathan Chambers",
411
- "Co-founder of Planeto",
412
- "https://dxhl76zpt6fap.cloudfront.net/public/avatar/jonathan-chambers.jpg",
413
- )
414
-
415
- with solara.Column(style={"width": "100%"}):
416
- solara.v.Divider()
417
-
418
- with solara.Column(align="center", gap="2.5em", style={"width": "100%", "padding-bottom": "50px"}):
419
- solara.Markdown("# Sponsors", style="text-align:center")
420
- with solara.Row(justify="center", gap="2.5em", style={"align-items": "stretch"}):
421
- with solara.v.Html(tag="a", attributes={"href": "https://www.dominodatalab.com/", "target": "_blank"}):
422
- solara.Image("https://dxhl76zpt6fap.cloudfront.net/public/sponsors/domino.png", width="300px")
423
-
424
- with solara.Column(style={"width": "100%"}):
425
- solara.v.Divider()
426
-
427
- with solara.Row(justify="center", gap="2.5em", classes=["footer-wrapper"]):
428
- with solara.Column(align="center", style={"min-width": "300px"}):
429
- solara.Markdown(
430
- """
431
- #### For any consulting, training or support needs
432
- [contact@solara.dev](mailto:contact@solara.dev)
433
- """
434
- )
435
- solara.v.Divider(vertical=True)
436
- with solara.Column(align="center", style={"min-width": "300px"}):
437
- solara.Markdown("#### Join our Mailing list to get the latest news")
438
- with solara.Div(style={"width": "80%"}):
439
- MailChimp(location=router.path)
440
- else:
441
- with rv.Row(
442
- style_="flex-wrap: nowrap; margin: 0; min-height: calc(100vh - 215.5px);",
443
- justify="center" if route_current is not None and route_current.path in ["documentation", "showcase"] else "start",
444
- ):
445
- if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
446
- with solara.v.NavigationDrawer(
447
- clipped=True,
448
- class_="d-none d-md-block",
449
- height="unset",
450
- style_="min-height: calc(100vh - 215.5px);",
451
- width="20rem",
452
- v_model=True, # Forces menu to display even if it had somehow been closed
453
- ):
454
- route_current.module.Sidebar()
455
- with rv.Col(
456
- tag="main",
457
- md=True,
458
- class_="pa-0",
459
- style_=f"""max-width: {'1024px' if route_current.path not in ['documentation', 'contact', 'changelog']
460
- else 'unset'}; overflow-x: hidden;""",
274
+ with rv.Container(tag="section", fluid=True, ma_0=True, pa_0=True, class_="fill-height solara-content-main"):
275
+ if route_current is None:
276
+ return solara.Error("Page not found")
277
+ else:
278
+ with rv.Row(
279
+ style_="flex-wrap: nowrap; margin: 0; min-height: calc(100vh - 64px);",
280
+ justify="center" if route_current is not None and route_current.path in ["documentation", "showcase"] else "start",
461
281
  ):
462
- if route_current is not None and route_current.path == "/":
463
- with rv.Row(align="center"):
464
- pass
465
- with solara.Row(
466
- children=children,
467
- justify="center",
468
- classes=["solara-page-content-search"],
469
- style=f"height: {'100%' if route_current.path == 'documentation' else 'unset'};",
282
+ if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
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,
296
+ ):
297
+ route_current.module.Sidebar()
298
+ with rv.Col(
299
+ tag="main",
300
+ md=True,
301
+ class_="pa-0",
302
+ style_="max-width: 1024px" if route_current.path == "showcase" else "",
470
303
  ):
471
- pass
472
-
473
- # absolute = True prevents the drawer from being below the overlay it generates
474
- # Drawer navigation for top menu
475
- with rv.NavigationDrawer(
476
- v_model=show_right_menu,
477
- on_v_model=set_show_right_menu,
478
- fixed=True,
479
- absolute=True,
480
- right=True,
481
- hide_overlay=False,
482
- overlay_color="#000000",
483
- overlay_opacity=0.5,
484
- style_="height: 100vh",
485
- ):
486
- Algolia()
487
- with rv.List(nav=True):
488
- with rv.ListItemGroup(active_class="text--primary"):
489
- for route in all_routes:
490
- if route.path == "apps":
491
- continue
492
- with solara.Link(route):
493
- solara.ListItem(route.label)
304
+ with solara.Row(
305
+ children=children,
306
+ justify="center",
307
+ classes=["solara-page-content-search"],
308
+ style="height: unset",
309
+ ):
310
+ pass
494
311
 
495
- if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
496
- with solara.v.NavigationDrawer(
312
+ # absolute = True prevents the drawer from being below the overlay it generates
313
+ # Drawer navigation for top menu
314
+ with rv.NavigationDrawer(
315
+ v_model=show_right_menu,
316
+ on_v_model=set_show_right_menu,
317
+ fixed=True,
497
318
  absolute=True,
498
- clipped=True,
499
- class_="d-md-none d-block",
500
- height="unset",
501
- style_="min-height: 100vh;",
502
- v_model=show_left_menu,
503
- on_v_model=set_show_left_menu,
504
- width="20rem",
319
+ right=True,
320
+ hide_overlay=False,
321
+ overlay_color="#000000",
322
+ overlay_opacity=0.5,
323
+ style_="height: 100vh",
505
324
  ):
506
- route_current.module.Sidebar()
325
+ Algolia()
326
+ with rv.List(nav=True):
327
+ with rv.ListItemGroup(active_class="text--primary"):
328
+ for route in all_routes:
329
+ if route.path == "apps":
330
+ continue
331
+ with solara.Link(route):
332
+ solara.ListItem(route.label)
333
+
334
+ if route_current is not None and route_current.module is not None and hasattr(route_current.module, "Sidebar"):
335
+ with solara.v.NavigationDrawer(
336
+ absolute=True,
337
+ clipped=True,
338
+ class_="d-md-none d-block",
339
+ height="unset",
340
+ style_="min-height: 100vh;",
341
+ v_model=show_left_menu,
342
+ on_v_model=set_show_left_menu,
343
+ width="20rem",
344
+ ):
345
+ route_current.module.Sidebar()
507
346
 
508
- return main
347
+ return main
509
348
 
510
349
 
511
350
  @solara.component
@@ -0,0 +1,9 @@
1
+ from pathlib import Path
2
+
3
+ from solara.website.components.markdown import MarkdownWithMetadata
4
+
5
+
6
+ title = "About Us"
7
+ HERE = Path(__file__)
8
+
9
+ Page = MarkdownWithMetadata(Path(HERE.parent / "about.md").read_text())
@@ -0,0 +1,3 @@
1
+ # About Us
2
+
3
+ Solara is a framework created by Maarten Breddels, and developed by [Widgetti](https://widgetti.io). Widgetti is a small company based in the Netherlands, focusing on developing tools for the Jupyter ecosystem. We combine ipywidgets and python experience with expertise in front-end development to help data scientists and python app developers make the most of their time. If you could use our years of diverse industry experience, reach out [here](/contact). You can find out more about Solara [here](/documentation/getting_started/introduction), or get to know our team [here](/our_team).
@@ -0,0 +1,27 @@
1
+ import solara
2
+
3
+
4
+ @solara.component
5
+ def Page():
6
+ with solara.Column():
7
+ solara.Markdown(
8
+ """
9
+ # Careers
10
+ We are always looking for talented individuals to join our team. If you're still be interested after reading the rest of this page, reach out at [contact@widgetti.io](mailto:contact@widgetti.io).
11
+
12
+ ## Who Are We?
13
+ We are a small team of developers working in the gap between Jupyter notebooks and web applications. We are passionate about making data science more accessible and app development painless.
14
+ We are based in Groningen, The Netherlands, but work remote first.
15
+
16
+ ## What Do We Offer?
17
+ We offer a flexible work environment, competitive salary, and the opportunity to do meaningful, crossdisciplinary work with scientists and companies worldwide.
18
+ We are a small team, so you will have a lot of freedom in your work, and the chance to get your hands dirty with many projects.
19
+
20
+ ### Open Source
21
+ We are strong believers in open source software. When working with us, you can expect the majority of the software you write to be open source, with contributions to Solara as well as other open source projects.
22
+
23
+ ## Who Are We Looking For?
24
+ We are looking for developers, technical writers, designers, and everything in between.
25
+ """,
26
+ style={"max-width": "90%", "margin": "0 auto"},
27
+ )
@@ -1,10 +1,10 @@
1
1
  from pathlib import Path
2
2
 
3
- import solara
4
3
  from solara.website.components.sidebar import Sidebar
4
+ from solara.website.components import MarkdownWithMetadata
5
5
 
6
6
  title = "Changelog"
7
7
  HERE = Path(__file__)
8
8
 
9
- Page = solara.Markdown(Path(HERE.parent / "changelog.md").read_text())
9
+ Page = MarkdownWithMetadata(Path(HERE.parent / "changelog.md").read_text())
10
10
  Sidebar = Sidebar