diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d92b5226..7df3da97e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -This is the old changelog, check the [Solara website](https://solara.dev/docs/changelog) for the up to date changelog. +This is the old changelog, check the [Solara website](https://solara.dev/changelog) for the up to date changelog. ## Changelog for solara v1.22 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b7ac4d2f..909938d82 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1 @@ -Please go to https://solara.dev/docs/howto/contribute for more information. +Please go to https://solara.dev/documentation/advanced/development/contribute for more information. diff --git a/README.md b/README.md index 744c036b4..1b7d1ae12 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Run: pip install solara ``` -Or follow the [Installation instructions](https://solara.dev/docs/installing) for more detailed instructions. +Or follow the [Installation instructions](https://solara.dev/documentation/getting_started/installing) for more detailed instructions. ## First script @@ -73,7 +73,7 @@ Solara server is starting at http://localhost:8765 Or copy-paste this to a Jupyter notebook cell and execute it (the `Page()` expression at the end will cause it to automatically render the component in the notebook). -See this snippet run live at https://solara.dev/docs/quickstart +See this snippet run live at https://solara.dev/documentation/getting_started ## Demo @@ -100,7 +100,7 @@ By building on top of ipywidgets, we automatically leverage an existing ecosyste Visit our main website or jump directly to the introduction -[![Introduction](https://dabuttonfactory.com/button.png?t=Introduction&f=Open+Sans-Bold&ts=20&tc=fff&hp=45&vp=12&c=8&bgt=unicolored&bgc=f19f41)](https://solara.dev/docs) -[![Quickstart](https://dabuttonfactory.com/button.png?t=Quickstart&f=Open+Sans-Bold&ts=20&tc=fff&hp=45&vp=12&c=8&bgt=unicolored&bgc=f19f41)](https://solara.dev/docs/quickstart) +[![Introduction](https://dabuttonfactory.com/button.png?t=Introduction&f=Open+Sans-Bold&ts=20&tc=fff&hp=45&vp=12&c=8&bgt=unicolored&bgc=f19f41)](https://solara.dev/documentation) +[![Quickstart](https://dabuttonfactory.com/button.png?t=Quickstart&f=Open+Sans-Bold&ts=20&tc=fff&hp=45&vp=12&c=8&bgt=unicolored&bgc=f19f41)](https://solara.dev/documentation/getting_started) *Note that the solara.dev website is created using Solara* diff --git a/packages/solara-enterprise/solara_enterprise/auth/components.py b/packages/solara-enterprise/solara_enterprise/auth/components.py index f6b4e4a49..acc7589a5 100644 --- a/packages/solara-enterprise/solara_enterprise/auth/components.py +++ b/packages/solara-enterprise/solara_enterprise/auth/components.py @@ -28,7 +28,7 @@ def Page(): solara.Button("Logout", icon_name="mdi-logout", href=auth.get_logout_url()) ``` - Note that a common use case is to put the avatar in the [AppBar](/api/app_bar). + Note that a common use case is to put the avatar in the [AppBar](/documentation/components/layout/app_bar). ```solara import solara from solara_enterprise import auth diff --git a/solara/__init__.py b/solara/__init__.py index 244e79057..97fc40755 100644 --- a/solara/__init__.py +++ b/solara/__init__.py @@ -77,10 +77,10 @@ def display(*objs, **kwargs): However, if you require callback functions, use the specific Solara components, e.g.: - * [Plotly](/api/plotly) - * [Altair](/api/altair) - * [Matplotlib](/api/matplotlib) - * [Dataframe](/api/dataframe) + * [Plotly](/documentation/components/viz/plotly) + * [Altair](/documentation/components/viz/altair) + * [Matplotlib](/documentation/components/viz/matplotlib) + * [Dataframe](/documentation/components/data/dataframe) ```solara import solara diff --git a/solara/__main__.py b/solara/__main__.py index 28a36c44a..da34c1b34 100644 --- a/solara/__main__.py +++ b/solara/__main__.py @@ -489,7 +489,7 @@ def deploy(): time.sleep(1) rprint("Want your app to run instantly on awesomeapp-mystartup-gh.solara.run?") - rprint("\tCheck out https://solara.dev/docs/deploying/cloud-hosted") + rprint("\tCheck out https://solara.dev/documentation/getting_started/deploying/cloud-hosted") @cli.command() diff --git a/solara/autorouting.py b/solara/autorouting.py index 15a2be343..4b766f6ba 100644 --- a/solara/autorouting.py +++ b/solara/autorouting.py @@ -371,7 +371,7 @@ def generate_routes(module: ModuleType) -> List[solara.Route]: files are not Python modules. - See [our multipage guide](/docs/howto/multipage#as-a-package) for more details. + See [our multipage guide](/documentation/advanced/howto/multipage#as-a-package) for more details. """ @@ -474,7 +474,7 @@ def generate_routes_directory(path: Path) -> List[solara.Route]: Python files ending in .py, or Jupyter notebooks ending in .ipynb will be executed and its `Page` component will be rendered. - Automatic titles will be [generated as explained in the multipage guide](/docs/howto/multipage). + Automatic titles will be [generated as explained in the multipage guide](/documentation/advanced/howto/multipage). """ diff --git a/solara/cache.py b/solara/cache.py index f88c622d7..a64ec2255 100644 --- a/solara/cache.py +++ b/solara/cache.py @@ -221,7 +221,7 @@ def mean(df, column): memory content. The storage can be any object that implements the MutableMapping interface, for instance a dict or - a cachetools.LRUCache. Or a new instance of `solara.cache.Memory`, see [caching](/docs/reference/caching) + a cachetools.LRUCache. Or a new instance of `solara.cache.Memory`, see [caching](/documentation/getting_started/reference/caching) for cache storage options. The return value of the decorator behaves like the original function, but also has a few attributes: @@ -233,7 +233,7 @@ def mean(df, column): If the value is already cached, the function will not be executed in a thread. - See also the [reference on caching](/docs/reference/caching) for more caching details. + See also the [reference on caching](/documentation/getting_started/reference/caching) for more caching details. """ diff --git a/solara/checks.html b/solara/checks.html index fa327ef95..062c39b8f 100644 --- a/solara/checks.html +++ b/solara/checks.html @@ -60,7 +60,7 @@ const div = document.createElement("div") const div2 = document.createElement("div") div.innerHTML = `Run ${jupyter_python_executable} -m pip install ${needsInstall.join(" ")}. Refresh the page after installation.` - div2.innerHTML = `Visit https://solara/dev/docs/troubleshoot for more information.` + div2.innerHTML = `Visit https://solara/dev/documentation/getting_started/troubleshoot for more information.` rootEl.appendChild(div) rootEl.appendChild(div2) } diff --git a/solara/components/applayout.py b/solara/components/applayout.py index b83b096ac..5a40ee498 100644 --- a/solara/components/applayout.py +++ b/solara/components/applayout.py @@ -90,7 +90,7 @@ def AppBar(children=[]): This component does not need to be a direct child of the AppLayout, it can be at any level in your component tree. - If a [Tabs](/api/tabs) component is used as direct child of the app bar, it will be shown under the app bar. + If a [Tabs](/documentation/components/lab/tabs) component is used as direct child of the app bar, it will be shown under the app bar. ## Example showing an app bar ```solara @@ -204,11 +204,11 @@ def AppLayout( ): """The default layout for Solara apps. It consists of an toolbar bar, a sidebar and a main content area. - * The title of the app is set using the [Title](/api/title) component. - * The sidebar content is set using the [Sidebar](/api/sidebar) component. + * The title of the app is set using the [Title](/documentation/components/page/title) component. + * The sidebar content is set using the [Sidebar](/documentation/components/layout/sidebar) component. * The content is set by the `Page` component provided by the user. - This component is usually not used directly, but rather through via the [Layout system](/docs/howto/layout). + This component is usually not used directly, but rather through via the [Layout system](/documentation/advanced/howto/layout). The sidebar is only added when the AppLayout has more than one child. @@ -224,7 +224,7 @@ def AppLayout( * `children`: The children of the AppLayout. The first child is used as the sidebar content, the rest as the main content. * `sidebar_open`: Whether the sidebar is open or not. - * `title`: The title of the app shown in the app bar, can also be set using the [Title](/api/title) component. + * `title`: The title of the app shown in the app bar, can also be set using the [Title](/documentation/components/page/title) component. * `toolbar_dark`: Whether the toolbar should be dark or not. * `navigation`: Whether the navigation tabs based on routing should be shown. * `color`: The color of the toolbar. diff --git a/solara/components/button.py b/solara/components/button.py index dd9a2a219..d2225760c 100644 --- a/solara/components/button.py +++ b/solara/components/button.py @@ -1,10 +1,9 @@ from typing import Callable, Dict, List, Optional, Union -from reacton import ipyvue -from reacton import ipyvuetify as v - import solara import solara.util +from reacton import ipyvue +from reacton import ipyvuetify as v @solara.component @@ -51,7 +50,8 @@ def Page(): - `disabled`: Whether the button is disabled. - `text`: Whether the button should be displayed as text, it has no shadow and no background. - `outlined`: Whether the button should be displayed as outlined, it has no background. - - `value`: (Optional) When used as a child of a ToggleButtons component, the value of the selected button, see [ToggleButtons](/api/togglebuttons). + - `value`: (Optional) When used as a child of a ToggleButtons component, the value of the selected button, see + [ToggleButtons](/documentation/components/input/togglebuttons). - `classes`: Additional CSS classes to apply. - `style`: CSS style to apply. diff --git a/solara/components/card.py b/solara/components/card.py index 3d6570b76..f61253054 100644 --- a/solara/components/card.py +++ b/solara/components/card.py @@ -1,7 +1,6 @@ from typing import Dict, List, Optional, Union import reacton.ipyvuetify as v - import solara from solara.util import _combine_classes @@ -79,7 +78,7 @@ def Page(): def CardActions(children: List[solara.Element] = []): """Container for actions in a card. - See [Card](/api/card) for an example. + See [Card](/documentation/components/layout/card) for an example. # Arguments diff --git a/solara/components/component_vue.py b/solara/components/component_vue.py index a1049eee5..633725b6c 100644 --- a/solara/components/component_vue.py +++ b/solara/components/component_vue.py @@ -78,7 +78,7 @@ def component_vue(vue_path: str, vuetify=True) -> Callable[[Callable[P, None]], [See the vue v2 api](https://v2.vuejs.org/v2/api/) for more information on how to use Vue, like `watch`, `methods` and lifecycle hooks such as `mounted` and `destroyed`. - See the [Vue component example](/examples/general/vue_component) for an example of how to use this decorator. + See the [Vue component example](/documentation/examples/general/vue_component) for an example of how to use this decorator. ## Arguments diff --git a/solara/components/cross_filter.py b/solara/components/cross_filter.py index e39f0ef77..8ce8407ce 100644 --- a/solara/components/cross_filter.py +++ b/solara/components/cross_filter.py @@ -3,9 +3,8 @@ import ipyvuetify import reacton.ipyvuetify as v -import traitlets - import solara +import traitlets from solara import CellAction, ColumnAction from ..lab.hooks.dataframe import use_df_column_names @@ -55,7 +54,7 @@ def CrossFilterSelect( ): """A Select widget that will cross filter a DataFrame. - See [use_cross_filter](/api/use_cross_filter) for more information about how to use cross filtering. + See [use_cross_filter](/documentation/api/hooks/use_cross_filter) for more information about how to use cross filtering. ## Arguments @@ -170,7 +169,7 @@ def CrossFilterReport(df, classes: List[str] = []): Shows number of rows filtered, and the total number of rows. - See [use_cross_filter](/api/use_cross_filter) for more information about how to use cross filtering. + See [use_cross_filter](/documentation/api/hooks/use_cross_filter) for more information about how to use cross filtering. ## Arguments @@ -214,7 +213,7 @@ def CrossFilterSlider( ): """A Slider widget that will cross filter a DataFrame. - See [use_cross_filter](/api/use_cross_filter) for more information about how to use cross filtering. + See [use_cross_filter](/documentation/api/hooks/use_cross_filter) for more information about how to use cross filtering. ## Arguments @@ -318,9 +317,9 @@ def update_filter(): def CrossFilterDataFrame(df, items_per_page=20, column_actions: List[ColumnAction] = [], cell_actions: List[CellAction] = [], scrollable=False): """Display a DataFrame with filters applied from the cross filter. - This component wraps [DataFrame](/api/dataframe). + This component wraps [DataFrame](/documentation/components/data/dataframe). - See [use_cross_filter](/api/use_cross_filter) for more information about how to use cross filtering. + See [use_cross_filter](/documentation/api/hooks/use_cross_filter) for more information about how to use cross filtering. # Arguments diff --git a/solara/components/datatable.py b/solara/components/datatable.py index 07fefe0d8..5c04d1133 100644 --- a/solara/components/datatable.py +++ b/solara/components/datatable.py @@ -6,11 +6,10 @@ import ipyvuetify as v import ipywidgets -import traitlets - import solara import solara.hooks.dataframe import solara.lab +import traitlets from solara.lab.hooks.dataframe import use_df_column_names from solara.lab.utils.dataframe import df_type @@ -208,7 +207,7 @@ def Page(): * `cell_actions` - Triggered via clicking on the triple dot icon in the cell (visible when hovering). * `on_column_header_hover` - Optional callback when the user hovers over the triple dot icon on a header. * `column_header_info` - Element to display in the column menu popup (visible when hovering), provide an - empty container element (like [Column](/api/column)) to force showing the trigle dot icon (see example). + empty container element (like [Column](/documentation/components/layout/column)) to force showing the trigle dot icon (see example). """ return DataTable( diff --git a/solara/components/figure_altair.py b/solara/components/figure_altair.py index 8a5a0a534..2fcb50cc6 100644 --- a/solara/components/figure_altair.py +++ b/solara/components/figure_altair.py @@ -12,7 +12,7 @@ def FigureAltair( ): """Renders an Altair chart using VegaLite. - See also [our altair example](/examples/libraries/altair). + See also [our altair example](/documentation/examples/libraries/altair). ## Arguments diff --git a/solara/components/file_download.py b/solara/components/file_download.py index dbf0e88d1..eceea7057 100644 --- a/solara/components/file_download.py +++ b/solara/components/file_download.py @@ -144,8 +144,8 @@ def get_data(): ## Note on file size Note that the data will be kept in memory when downloading. - If the file is large (>10 MB), and when using [Solara server](/docs/understanding), we recommend using the - [static files directory](/docs/reference/static-files) instead. + If the file is large (>10 MB), and when using [Solara server](/documentation/advanced/understanding/solara-server), we recommend using the + [static files directory](/documentation/getting_started/reference/static-files) instead. """ request_download, set_request_download = solara.use_state(False) diff --git a/solara/components/head.py b/solara/components/head.py index 466fe5469..2d82f4664 100644 --- a/solara/components/head.py +++ b/solara/components/head.py @@ -1,7 +1,6 @@ from typing import List import reacton - import solara @@ -9,7 +8,7 @@ def Head(children: List[reacton.core.Element] = []): """A component that manager the "head" tag of the page to avoid duplicate tags, such as titles. - Currently only supports the [title](/api/title) tag as child, e.g.: + Currently only supports the [title](/documentation/components/page/title) tag as child, e.g.: ```python import solara diff --git a/solara/components/head_tag.py b/solara/components/head_tag.py index d478b7a7e..59b9c2fe7 100644 --- a/solara/components/head_tag.py +++ b/solara/components/head_tag.py @@ -2,9 +2,8 @@ import ipyvuetify as vy import reacton.core -import traitlets - import solara +import traitlets class HeadTagWidget(vy.VuetifyTemplate): @@ -19,7 +18,7 @@ class HeadTagWidget(vy.VuetifyTemplate): def HeadTag(tagname: str, key=None, attributes: Optional[dict] = None): """Add a child element to head element, or replace a meta tag with the same tagname and key. - This component should be used inside a [Head](/api/head) component, e.g.: + This component should be used inside a [Head](/documentation/components/page/head) component, e.g.: ```python import solara diff --git a/solara/components/link.py b/solara/components/link.py index e7b63fa51..2b8b0a5ca 100644 --- a/solara/components/link.py +++ b/solara/components/link.py @@ -2,7 +2,6 @@ import ipyvue as vue import reacton.ipyvue as vuer - import solara @@ -18,8 +17,8 @@ def Link( See also: - * [Multipage](/docs/howto/multipage). - * [Understanding Routing](/docs/understanding/routing). + * [Multipage](/documentation/advanced/howto/multipage). + * [Understanding Routing](/documentation/advanced/understanding/routing). Most common usage is in combination with a button, e.g.: @@ -32,7 +31,7 @@ def Link( ## Arguments * path_or_route: the path or route to navigate to. Paths should be absolute, e.g. '/fruit/banana'. - If a route is given, [`resolve_path`](/api/resolve_path)] will be used to resolve to the absolute path. + If a route is given, [`resolve_path`](/documentation/api/routing/resolve_path)] will be used to resolve to the absolute path. * children: the children of the link. If a child is clicked, the link will be followed. * nofollow: If True, the link will not be followed by web crawlers (such as google). * style: CSS styles to apply to the HTML link element. Either a string or a dictionary. diff --git a/solara/components/meta.py b/solara/components/meta.py index 02a11e89b..381bdcaf9 100644 --- a/solara/components/meta.py +++ b/solara/components/meta.py @@ -9,7 +9,7 @@ def Meta(name: Optional[str] = None, property: Optional[str] = None, content: Optional[str] = None): """Add a meta tag to the head element, or replace a meta tag with the same name and or property. - This component should be used inside a [Head](/api/head) component, e.g.: + This component should be used inside a [Head](/documentation/components/page/head) component, e.g.: ```python import solara diff --git a/solara/components/misc.py b/solara/components/misc.py index 5419783a7..83ac41f51 100644 --- a/solara/components/misc.py +++ b/solara/components/misc.py @@ -3,7 +3,6 @@ import reacton import reacton.ipyvuetify as v - import solara import solara.widgets from solara.util import _combine_classes @@ -159,7 +158,7 @@ def HBox(children=[], grow=True, align_items="stretch", classes: List[str] = []) def Row(children=[], gap="12px", justify="start", margin: int = 0, classes: List[str] = [], style: Union[str, Dict[str, str], None] = None): """Lays out children in a row, side by side, with the given gap between them. - See also [Column](/api/column). + See also [Column](/documentation/components/layout/column). Example with three children side by side: @@ -200,7 +199,7 @@ def Page(): def Column(children=[], gap="12px", align="stretch", margin: int = 0, classes: List[str] = [], style: Union[str, Dict[str, str], None] = None): """Lays out children in a column on top of each other, with the given gap between them. - See also [Row](/api/row). + See also [Row](/documentation/components/layout/row). Example with three children on top of each other: @@ -287,17 +286,14 @@ def on_points_callback(data): "plotly_hover": on_hover, "plotly_unhover": on_unhover, "plotly_selected": on_selection, - "plotly_deselect": on_deselect + "plotly_deselect": on_deselect, } - + callback = event_mapping.get(event_type) if callback: callback(data) - fig_element = FigureWidget.element( - on__js2py_pointsCallback=on_points_callback, - on__js2py_relayout=on_relayout - ) + fig_element = FigureWidget.element(on__js2py_pointsCallback=on_points_callback, on__js2py_relayout=on_relayout) def update_data(): fig_widget: FigureWidget = solara.get_widget(fig_element) diff --git a/solara/datatypes.py b/solara/datatypes.py index fd9fc37fb..4ec2e3d76 100644 --- a/solara/datatypes.py +++ b/solara/datatypes.py @@ -114,8 +114,8 @@ class Route: ## See also - * [Multipage](/docs/howto/multipage). - * [Understanding Routing](/docs/understanding/routing). + * [Multipage](/documentation/advanced/howto/multipage). + * [Understanding Routing](/documentation/advanced/understanding/routing). """ diff --git a/solara/hooks/use_reactive.py b/solara/hooks/use_reactive.py index 65fbd3c1d..2bfc0778c 100644 --- a/solara/hooks/use_reactive.py +++ b/solara/hooks/use_reactive.py @@ -13,7 +13,7 @@ def use_reactive( It is a useful alternative to `use_state` when you want to use a reactive variable for the component state. - See also [our documentation on state management](/docs/fundamentals/state-management). + See also [our documentation on state management](/documentation/getting_started/fundamentals/state-management). If the variable passed is a reactive variable, it will be returned instead and no new reactive variable will be created. This is useful for implementing component @@ -92,7 +92,7 @@ def MyComponent(value: Union[T, solara.Reactive[T]], except RuntimeError as e: raise RuntimeError( "use_reactive must be called from a component function, inside the render function.\n" - "Do not call it top level, use [solara.reactive()](https://solara.dev/api/reactive) instead." + "Do not call it top level, use [solara.reactive()](https://solara.dev/documentation/api/utilities/reactive) instead." ) from e on_change_ref.current = on_change diff --git a/solara/lab/components/confirmation_dialog.py b/solara/lab/components/confirmation_dialog.py index d0b3d5b3b..1cf2eaad0 100644 --- a/solara/lab/components/confirmation_dialog.py +++ b/solara/lab/components/confirmation_dialog.py @@ -60,7 +60,7 @@ def ConfirmationDialog( ): """A dialog used to confirm a user action. - (*Note: [This component is experimental and its API may change in the future](/docs/lab).*) + (*Note: [This component is experimental and its API may change in the future](/documentation/getting_started/lab).*) By default, has a title, a text explaining the decision to be made, and two buttons "OK" and "Cancel". diff --git a/solara/lab/components/tabs.py b/solara/lab/components/tabs.py index 6a5c62073..75135a1bb 100644 --- a/solara/lab/components/tabs.py +++ b/solara/lab/components/tabs.py @@ -17,9 +17,9 @@ def Tab( ): """An item in a Tabs component. - (*Note: [This component is experimental and its API may change in the future](/docs/lab).*) + (*Note: [This component is experimental and its API may change in the future](/documentation/getting_started/lab).*) - Should be a direct child of a [Tabs](/api/tabs). + Should be a direct child of a [Tabs](/documentation/components/lab/tabs). ## Arguments * `label`: The label of the tab. @@ -62,12 +62,12 @@ def Tabs( ): """A tabbed container showing one tab at a time. - (*Note: [This component is experimental and its API may change in the future](/docs/lab).*) + (*Note: [This component is experimental and its API may change in the future](/documentation/getting_started/lab).*) - Note that if Tabs are used as a child of the [AppBar](/api/appbar) component, the tabs + Note that if Tabs are used as a child of the [AppBar](/documentation/components/layout/app_bar) component, the tabs will be placed under the app bar. See our [authorization app](/apps/authorization) for an example. - If the children [Tab](/api/tab) elements are passed a `path_or_route` argument, the active tab + If the children [Tab](/documentation/components/lab/tab) elements are passed a `path_or_route` argument, the active tab will be based on the path of the current page. @@ -89,7 +89,7 @@ def Page(): ### Tabs with content - This is usually only used when the tabs are placed in the [AppBar](/api/appbar) component. + This is usually only used when the tabs are placed in the [AppBar](/documentation/components/layout/app_bar) component. ```solara import solara diff --git a/solara/reactive.py b/solara/reactive.py index 4da960070..6ecb0558d 100644 --- a/solara/reactive.py +++ b/solara/reactive.py @@ -14,7 +14,7 @@ def reactive(value: T) -> Reactive[T]: Solara web applications. They provide an easy-to-use mechanism for keeping track of the changing state of data and for propagating those changes to the appropriate UI components. For managing local or component-specific - state, consider using the [`solara.use_state()`](/api/use_state) function. + state, consider using the [`solara.use_state()`](/documentation/api/hooks/use_state) function. Reactive variables can be accessed using the `.value` attribute. To modify diff --git a/solara/routing.py b/solara/routing.py index b990675f8..d393bd9c1 100644 --- a/solara/routing.py +++ b/solara/routing.py @@ -101,7 +101,7 @@ def use_route_level(): def use_router() -> Router: """Returns the current router object. - See also [Understanding Routing](/docs/understanding/routing). + See also [Understanding Routing](/documentation/advanced/understanding/routing). `use_router` returns the current router object. This is useful to build custom routing. @@ -123,7 +123,7 @@ def Page(): router = solara.use_router() def redirect(): - router.push(f"/api/use_route") + router.push(f"/documentation/api/routing/use_route") solara.Button("Navigate using an event", on_click=redirect) ``` @@ -138,7 +138,7 @@ def use_route( ) -> Tuple[Optional[solara.Route], List[solara.Route]]: """Returns (if found) the current route that matches the pathname, or None - See also [Understanding Routing](/docs/understanding/routing). + See also [Understanding Routing](/documentation/advanced/understanding/routing). `use_route` returns (if found) the current route that matches the pathname, or None. It also returns all resolved routes of that level (i.e. all siblings and itself). This return tuple is useful to build custom navigation (e.g. using tabs or buttons). @@ -166,9 +166,10 @@ def use_route( Note that all routes are relative, since a component does not know if it is embedded into a larger application, which may also do routing. Therefore you should never use the `route.path` for navigation since the route object has no knowledge of the full url - (e.g. `/api/use_route/fruit/banana`) but only knows its small piece of the pathname (e.g. `banana`) + (e.g. `/documentation/api/routing/use_route/fruit/banana`) but only knows its small piece of the pathname (e.g. `banana`) - Use [`resolve_path`](/api/resolve_path) to request the full url for navigation, or simply use the `Link` component that can do this for us. + Use [`resolve_path`](/documentation/api/routing/resolve_path) to request the full url for navigation, + or simply use the `Link` component that can do this for us. If the current route has children, any child component that calls `use_route` will return the matched route and its siblings of our children. @@ -229,12 +230,12 @@ def resolve_path(path_or_route: Union[str, solara.Route], level=0) -> str: ## Arguments - * path_or_route: a path string or a [`solara.Route`](/api/route) object to resolve. + * path_or_route: a path string or a [`solara.Route`](/documentation/api/routing/route) object to resolve. ## See also - * [Multipage](/docs/howto/multipage). - * [Understanding Routing](/docs/understanding/routing). + * [Multipage](/documentation/advanced/howto/multipage). + * [Understanding Routing](/documentation/advanced/understanding/routing). """ diff --git a/solara/server/server.py b/solara/server/server.py index 021be9dc2..320ececad 100644 --- a/solara/server/server.py +++ b/solara/server/server.py @@ -34,6 +34,7 @@ ipywidgets_major = int(ipywidgets.__version__.split(".")[0]) cache_memory = solara.cache.Memory(max_items=128) vue3 = ipyvue.__version__.startswith("3") +_redirects: Dict[str, str] = {} # first look at the project directory, then the builtin solara directory diff --git a/solara/server/starlette.py b/solara/server/starlette.py index fdd27cd55..a8e7a026d 100644 --- a/solara/server/starlette.py +++ b/solara/server/starlette.py @@ -40,7 +40,7 @@ from starlette.middleware.authentication import AuthenticationMiddleware from starlette.middleware.gzip import GZipMiddleware from starlette.requests import HTTPConnection, Request -from starlette.responses import HTMLResponse, JSONResponse, Response +from starlette.responses import HTMLResponse, JSONResponse, RedirectResponse, Response from starlette.routing import Mount, Route, WebSocketRoute from starlette.staticfiles import StaticFiles from starlette.types import Receive, Scope, Send @@ -315,6 +315,9 @@ async def root(request: Request, fullpath: str = ""): request_path = request.url.path if request_path.startswith(root_path): request_path = request_path[len(root_path) :] + if request_path in server._redirects.keys(): + return RedirectResponse(server._redirects[request_path]) + content = server.read_root(request_path, root_path) if content is None: if settings.oauth.private and not request.user.is_authenticated: diff --git a/solara/website/assets/custom.css b/solara/website/assets/custom.css index 3243dbafa..054410516 100644 --- a/solara/website/assets/custom.css +++ b/solara/website/assets/custom.css @@ -27,6 +27,11 @@ --dark-color-text: hsla(0,0%,100%,.7); --dark-color-grey: #ababab; --dark-color-grey-light: #202020; + + --docs-color-grey: #40362E; + --docs-social-discord: #5865F2; + --docs-social-github: #333; + --docs-social-twitter: #000000; } html, @@ -178,6 +183,56 @@ blockquote p:last-child { background-color: var(--dark-color-primary-lightest); } +/* API PAGE REFACTOR STYLE */ + +.v-sheet.api-search-container{ + flex-grow: 1; +} + .v-sheet.api-search-container .v-input{ + flex-grow: 0; + } +.v-sheet.docs-card-container{ + width: 100%; + padding: 0 10%; + justify-content: start; + align-content: center; + flex-wrap: wrap !important; + flex-grow: 1; + row-gap: 20px; +} +.v-sheet.docs-card-container > a{ + height: fit-content; +} +.v-sheet.docs-card-container > a > .docs-card{ + display: flex; + width: 20rem; + height: 12rem; + border-radius: 16px !important; + color: var(--color-grey-light); +} + .v-sheet.docs-card-container > a .docs-card-icon{ + padding-right: 1.5rem; + transition: ease padding 0.25s; + } + .v-sheet.docs-card-container > a:hover .docs-card-icon{ + color: var(--color-primary); + padding-right: 0.5rem; + transition: ease padding 0.25s; + } +.component-card{ + display: flex; + flex-direction: column; + width: 19rem; +} +.social-logo-container{ + display: flex; + justify-content: center; + align-items: center; + width: 4rem; + height: 4rem; + border-radius: 8px; +} + /* vuetify component overrides */ .v-btn.solara-docs-button { @@ -354,6 +409,7 @@ blockquote p:last-child { } .solara-autorouter-content { + padding-top: 2rem; max-width: 100%; } diff --git a/solara/website/components/__init__.py b/solara/website/components/__init__.py index b9a267c7a..d76eba3a6 100644 --- a/solara/website/components/__init__.py +++ b/solara/website/components/__init__.py @@ -1,3 +1,4 @@ +from .docs import CategoryLayout, Gallery, NoPage, SubCategoryLayout, WithCode # noqa from .header import Header from .hero import Hero diff --git a/solara/website/components/algolia_api.vue b/solara/website/components/algolia_api.vue new file mode 100644 index 000000000..c970fb040 --- /dev/null +++ b/solara/website/components/algolia_api.vue @@ -0,0 +1,157 @@ + + diff --git a/solara/website/components/docs.py b/solara/website/components/docs.py new file mode 100644 index 000000000..cfed59a99 --- /dev/null +++ b/solara/website/components/docs.py @@ -0,0 +1,118 @@ +import solara +from solara.alias import rv + + +@solara.component +def Gallery(route_external=None): + if route_external is not None: + route_current = route_external + else: + # show a gallery of all the examples + router = solara.use_router() + route_current = router.path_routes[-2] + + with solara.Column(gap="75px", align="center"): + with solara.Row(justify="center", gap="30px", style={"margin": "30px 0 !important", "flex-wrap": "wrap", "align-items": "start", "row-gap": "30px"}): + for child in route_current.children: + if child.path == "/": + continue + with solara.v.Html(tag="a", attributes={"href": "#" + child.path}): + solara.Button( + child.label, + color="primary", + classes=["v-btn--rounded", "v-size--x-large"], + ) + + with solara.Column(gap="75px", style={"padding-bottom": "75px"}): + for route in route_current.children: + if route.children: + with solara.Column(classes=["subcategory-row", "ps-md-10"]): + solara.HTML(tag="h2", unsafe_innerHTML=route.label, attributes={"id": route.path}, style="padding-left: 10%;") + with solara.Row(justify="center", gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "max-width": "90rem"}): + for child in route.children: + if child.path == "/": + continue + path = route.path + "/" + child.path + if child.path in [ + "button", + "checkbox", + "confirmation_dialog", + "echarts", + "file_browser", + "file_download", + "matplotlib", + "select", + "switch", + "tooltip", + ]: + image_url = "https://dxhl76zpt6fap.cloudfront.net/public/api/" + child.path + ".gif" + elif child.path in ["card", "dataframe", "pivot_table", "slider"]: + image_url = "https://dxhl76zpt6fap.cloudfront.net/public/api/" + child.path + ".png" + else: + image_url = "https://dxhl76zpt6fap.cloudfront.net/public/logo.svg" + + if path: + path = path if route_external is None else route_current.path + "/" + path + title = solara.Link(path, children=[child.label]) + with solara.Card(title, classes=["component-card"], margin=0): + with solara.Column(align="center"): + with solara.Link(path): + solara.Image(image_url, width="12rem") + + +@solara.component +def NoPage(): + raise RuntimeError("This page should not be rendered") + + +@solara.component +def WithCode(module): + component = getattr(module, "Page", None) + with rv.Sheet() as main: + # It renders code better + solara.Markdown( + module.__doc__ or "# no docs yet", + unsafe_solara_execute=True, + ) + if component and component != NoPage: + with solara.Card("Example", margin=0, classes=["mt-8"]): + component() + github_url = solara.util.github_url(module.__file__) + solara.Button( + label="View source", + icon_name="mdi-github-circle", + attributes={"href": github_url, "target": "_blank"}, + text=True, + outlined=True, + class_="mt-8", + ) + return main + + +@solara.component +def SubCategoryLayout(children=[]): + route_current, all_routes = solara.use_route() + if route_current is None: + return solara.Error("Page not found") + elif route_current.path == "/": + return solara.Error("Not supposed to be rendered") + elif route_current.module: + WithCode(route_current.module) + else: + with solara.Column(align="center", children=children, style={"flex-grow": 1, "padding": "0"}) as main: + pass + return main + + +@solara.component +def CategoryLayout(children=[]): + route_current, all_routes = solara.use_route() + if route_current is None: + return solara.Error("Page not found") + + if route_current.path == "/": + return Gallery() + else: + with solara.Column(align="stretch", style={"width": "1024px", "flex-grow": 1}, children=children) as main: + pass + return main diff --git a/solara/website/components/header.py b/solara/website/components/header.py index 20e910081..f7519c8b5 100644 --- a/solara/website/components/header.py +++ b/solara/website/components/header.py @@ -6,8 +6,8 @@ from solara.server import settings -@solara._component_vue("algolia.vue") -def Algolia(app_id: str, index_name: str, api_key: str, debug=False): +@solara.component_vue("algolia_api.vue") +def Algolia(): pass @@ -18,6 +18,7 @@ def Header( ): # use routes of parent (assuming we are a child of a layout) route_current, all_routes = solara.use_route(level=-1) + route_current_with_children, all_routes_with_children = solara.use_route() router = solara.use_router() dark_effective = solara.lab.use_dark_effective() @@ -28,7 +29,7 @@ def Header( "div", unsafe_innerHTML="Star us on github 🤩", ) - with rv.AppBar(tag="header", flat=True, class_="bg-primary-fade padding-40", height="auto"): + with solara.v.AppBar(tag="header", flat=True, class_="bg-primary-fade padding-40", height="auto", clipped_left=True): with rv.ToolbarTitle(class_="d-flex", style_="align-items:center"): if route_current and len(route_current.children) > 0: with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_left_menu and on_toggle_left_menu()): @@ -37,15 +38,24 @@ def Header( solara.Image(router.root_path + f"/static/assets/images/logo{'_white' if dark_effective else ''}.svg") rv.Spacer() - if settings.search.enabled: - from solara_enterprise.search.search import Search + if ( + route_current_with_children is not None + and route_current is not None + and route_current.path == "documentation" + and route_current_with_children.path == "/" + ): + solara.v.Spacer() + else: + if settings.search.enabled: + from solara_enterprise.search.search import Search - Search() - Algolia(app_id="9KW9L7O5EQ", api_key="ef7495102afff1e16d1b7cf6ec2ab2d0", index_name="solara", debug=True) - # menu + Search() + else: + with solara.Row(justify="end", style={"align-items": "center", "flex-grow": "1", "background-color": "transparent"}): + Algolia() with rv.Html(tag="ul", class_="main-menu menu d-none d-md-flex"): for route in all_routes: - if route.path == "apps": + if route.path in ["apps", "contact", "changelog"]: continue current = route_current == route with rv.Html(tag="li", class_="active" if current else None): @@ -53,7 +63,7 @@ def Header( with rv.Btn(icon=True, tag="a", class_="d-none d-md-flex", attributes={"href": solara.github_url, "target": "_blank"}): rv.Icon(children=["mdi-github-circle"]) - with rv.Btn(icon=True, tag="a", class_="d-none d-md-flex", attributes={"href": "https://discord.gg/dm4GKNDjXN", "target": "_blank"}): + with rv.Btn(icon=True, tag="a", class_="d-none d-md-flex", attributes={"href": "https://discord.solara.dev", "target": "_blank"}): rv.Icon(children=["mdi-discord"]) solara.lab.ThemeToggle() diff --git a/solara/website/components/hero.py b/solara/website/components/hero.py index ee76ee39e..974564f2f 100644 --- a/solara/website/components/hero.py +++ b/solara/website/components/hero.py @@ -10,6 +10,6 @@ def Hero(title, sub_title, button_text): with rv.Col(md=8, offset_md=2, sm=10, offset_sm=1): rv.Html(tag="h1", children=[title], class_="mb-4"), solara.HTML(tag="div", unsafe_innerHTML=f"

{sub_title}

", class_="mb-4"), - with solara.Link("/docs/quickstart"): + with solara.Link("/documentation/getting_started"): solara.Button(label=button_text, elevation=0, large=True, class_="btn-size--xlarge solara-docs-button") return main diff --git a/solara/website/pages/__init__.py b/solara/website/pages/__init__.py index 92ce76d2e..678ce1a9b 100644 --- a/solara/website/pages/__init__.py +++ b/solara/website/pages/__init__.py @@ -3,13 +3,208 @@ import solara from solara.alias import rv from solara.components.title import Title +from solara.server import server from ..components import Header, Hero from ..components.mailchimp import MailChimp title = "Home" -route_order = ["/", "showcase", "docs", "api", "examples", "apps"] +route_order = ["/", "showcase", "documentation", "apps", "contact", "changelog"] + + +server._redirects = { + "/docs": "/documentation/getting_started/introduction", + "/docs/installing": "/documentation/getting_started/installing", + "/docs/quickstart": "/documentation/getting_started", + "/docs/tutorial": "/documentation/getting_started/tutorials", + "/docs/tutorial/data-science": "/documentation/getting_started/tutorials/data-science", + "/docs/tutorial/web-app": "/documentation/getting_started/tutorials/web-app", + "/docs/tutorial/ipywidgets": "/documentation/getting_started/tutorials/ipywidgets", + "/docs/tutorial/streamlit": "/documentation/getting_started/tutorials/streamlit", + "/docs/tutorial/dash": "/documentation/getting_started/tutorials/dash", + "/docs/tutorial/jupyter-dashboard-part1": "/documentation/getting_started/tutorials/jupyter-dashboard-part1", + "/docs/fundamentals": "/documentation/getting_started/fundamentals", + "/docs/fundamentals/components": "/documentation/getting_started/fundamentals/components", + "/docs/fundamentals/state-management": "/documentation/getting_started/fundamentals/state-management", + "/docs/howto": "/documentation/advanced/howto", + "/docs/howto/contribute": "/documentation/advanced/development/contribute", + "/docs/howto/multipage": "/documentation/advanced/howto/multipage", + "/docs/howto/layout": "/documentation/advanced/howto/layout", + "/docs/howto/testing": "/documentation/advanced/howto/testing", + "/docs/howto/debugging": "/documentation/advanced/howto/debugging", + "/docs/howto/embed": "/documentation/advanced/howto/embed", + "/docs/howto/ipywidget-libraries": "/documentation/advanced/howto/ipywidget-libraries", + "/docs/reference": "/documentation/getting_started/reference", + "/docs/reference/static-files": "/documentation/getting_started/reference/static-files", + "/docs/reference/asset-files": "/documentation/getting_started/reference/asset-files", + "/docs/reference/static-site-generation": "/documentation/getting_started/reference/static-site-generation", + "/docs/reference/search": "/documentation/getting_started/reference/search", + "/docs/reference/reloading": "/documentation/getting_started/reference/reloading", + "/docs/reference/notebook-support": "/documentation/getting_started/reference/notebook-support", + "/docs/reference/caching": "/documentation/getting_started/reference/caching", + "/docs/understanding": "/documentation/advanced/understanding", + "/docs/understanding/ipywidgets": "/documentation/advanced/understanding/ipywidgets", + "/docs/understanding/ipyvuetify": "/documentation/advanced/understanding/ipyvuetify", + "/docs/understanding/reacton": "/documentation/advanced/understanding/reacton", + "/docs/understanding/reacton-basics": "/documentation/advanced/understanding/reacton-basics", + "/docs/understanding/anatomy": "/documentation/advanced/understanding/anatomy", + "/docs/understanding/rules-of-hooks": "/documentation/advanced/understanding/rules-of-hooks", + "/docs/understanding/containers": "/documentation/advanced/understanding/containers", + "/docs/understanding/solara": "/documentation/advanced/understanding/solara", + "/docs/understanding/routing": "/documentation/advanced/understanding/routing", + "/docs/understanding/solara-server": "/documentation/advanced/understanding/solara-server", + "/docs/understanding/voila": "/documentation/advanced/understanding/voila", + "/docs/deploying": "/documentation/getting_started/deploying", + "/docs/deploying/self-hosted": "/documentation/getting_started/deploying/self-hosted", + "/docs/deploying/cloud-hosted": "/documentation/getting_started/deploying/cloud-hosted", + "/docs/enterprise": "/documentation/advanced/enterprise", + "/docs/enterprise/oauth": "/documentation/advanced/enterprise/oauth", + "/docs/development": "/documentation/advanced/development/setup", + "/docs/troubleshoot": "/documentation/getting_started/troubleshoot", + "/docs/changelog": "/changelog", + "/docs/contact": "/contact", + "/docs/faq": "/documentation/faq", + "/docs/lab": "/documentation/getting_started/lab", + "/api": "/documentation/api", + "/api/altair": "/documentation/components/viz/altair", + "/api/app_bar": "/documentation/components/layout/app_bar", + "/api/app_bar_title": "/documentation/components/layout/app_bar_title", + "/api/app_layout": "/documentation/components/layout/app_layout", + "/api/avatar": "/documentation/components/enterprise/avatar", + "/api/avatar_menu": "/documentation/components/enterprise/avatar_menu", + "/api/card": "/documentation/components/layout/card", + "/api/card_actions": "/documentation/components/layout/card_actions", + "/api/column": "/documentation/components/layout/column", + "/api/columns": "/documentation/components/layout/columns", + "/api/columns_responsive": "/documentation/components/layout/columns_responsive", + "/api/cross_filter_dataframe": "/documentation/api/cross_filter/cross_filter_dataframe", + "/api/cross_filter_report": "/documentation/api/cross_filter/cross_filter_report", + "/api/cross_filter_select": "/documentation/api/cross_filter/cross_filter_select", + "/api/cross_filter_slider": "/documentation/api/cross_filter/cross_filter_slider", + "/api/generate_routes": "/documentation/api/routing/generate_routes", + "/api/generate_routes_directory": "/documentation/api/routing/generate_routes_directory", + "/api/resolve_path": "/documentation/api/routing/resolve_path", + "/api/resolve_path/kiwi": "/documentation/api/routing/resolve_path/kiwi", + "/api/resolve_path/banana": "/documentation/api/routing/resolve_path/banana", + "/api/resolve_path/apple": "/documentation/api/routing/resolve_path/apple", + "/api/link": "/documentation/components/advanced/link", + "/api/link/kiwi": "/documentation/components/advanced/link/kiwi", + "/api/link/banana": "/documentation/components/advanced/link/banana", + "/api/link/apple": "/documentation/components/advanced/link/apple", + "/api/use_route": "/documentation/api/routing/use_route", + "/api/use_route/fruit": "/documentation/api/routing/use_route/fruit", + "/api/use_route/fruit/kiwi": "/documentation/api/routing/use_route/fruit/kiwi", + "/api/use_route/fruit/banana": "/documentation/api/routing/use_route/fruit/banana", + "/api/use_route/fruit/apple": "/documentation/api/routing/use_route/fruit/apple", + "/api/use_router": "/documentation/api/routing/use_router", + "/api/use_cross_filter": "/documentation/api/hooks/use_cross_filter", + "/api/use_dark_effective": "/documentation/api/hooks/use_dark_effective", + "/api/use_effect": "/documentation/api/hooks/use_effect", + "/api/use_exception": "/documentation/api/hooks/use_exception", + "/api/use_memo": "/documentation/api/hooks/use_memo", + "/api/use_previous": "/documentation/api/hooks/use_previous", + "/api/use_reactive": "/documentation/api/hooks/use_reactive", + "/api/use_state": "/documentation/api/hooks/use_state", + "/api/use_state_or_update": "/documentation/api/hooks/use_state_or_update", + "/api/use_task": "/documentation/components/lab/use_task", + "/api/use_thread": "/documentation/api/hooks/use_thread", + "/api/use_trait_observe": "/documentation/api/hooks/use_trait_observe", + "/examples/fullscreen": "/documentation/examples/fullscreen", + "/examples/fullscreen/authorization": "/documentation/examples/fullscreen/authorization", + "/examples/fullscreen/layout_demo": "/documentation/examples/fullscreen/layout_demo", + "/examples/fullscreen/multipage": "/documentation/examples/fullscreen/multipage", + "/examples/fullscreen/scatter": "/documentation/examples/fullscreen/scatter", + "/examples/fullscreen/scrolling": "/documentation/examples/fullscreen/scrolling", + "/examples/fullscreen/tutorial_streamlit": "/documentation/examples/fullscreen/tutorial_streamlit", + "/api/route": "/documentation/api/routing/route", + "/api/route/kiwi": "/documentation/api/routing/route/kiwi", + "/api/route/banana": "/documentation/api/routing/route/banana", + "/api/route/apple": "/documentation/api/routing/route/apple", + "/examples/libraries": "/documentation/examples/libraries", + "/examples/libraries/altair": "/documentation/examples/libraries/altair", + "/examples/libraries/bqplot": "/documentation/examples/libraries/bqplot", + "/examples/libraries/ipyleaflet": "/documentation/examples/libraries/ipyleaflet", + "/examples/libraries/ipyleaflet_advanced": "/documentation/examples/libraries/ipyleaflet_advanced", + "/examples/utilities": "/documentation/examples/utilities", + "/examples/utilities/calculator": "/documentation/examples/utilities/calculator", + "/examples/utilities/countdown_timer": "/documentation/examples/utilities/countdown_timer", + "/examples/utilities/todo": "/documentation/examples/utilities/todo", + "/examples/visualization": "/documentation/examples/visualization", + "/examples/visualization/annotator": "/documentation/examples/visualization/annotator", + "/examples/visualization/linked_views": "/documentation/examples/visualization/linked_views", + "/examples/visualization/plotly": "/documentation/examples/visualization/plotly", + "/examples/general": "/documentation/examples/general", + "/examples/general/custom_storage": "/documentation/examples/general/custom_storage", + "/examples/general/deploy_model": "/documentation/examples/general/deploy_model", + "/examples/general/live_update": "/documentation/examples/general/live_update", + "/examples/general/login_oauth": "/documentation/examples/general/login_oauth", + "/examples/general/pokemon_search": "/documentation/examples/general/pokemon_search", + "/examples/general/vue_component": "/documentation/examples/general/vue_component", + "/examples": "/documentation/examples", + "/examples/ai": "/documentation/examples/ai", + "/examples/ai/chatbot": "/documentation/examples/ai/chatbot", + "/examples/ai/tokenizer": "/documentation/examples/ai/tokenizer", + "/examples/basics": "/documentation/examples/basics", + "/examples/basics/sine": "/documentation/examples/basics/sine", + "/api/get_kernel_id": "/documentation/api/utilities/get_kernel_id", + "/api/get_session_id": "/documentation/api/utilities/get_session_id", + "/api/on_kernel_start": "/documentation/api/utilities/on_kernel_start", + "/api/component_vue": "/documentation/api/utilities/component_vue", + "/api/plotly": "/documentation/components/viz/plotly", + "/api/plotly_express": "/documentation/components/viz/plotly_express", + "/api/tab": "/documentation/components/lab/tab", + "/api/tabs": "/documentation/components/lab/tabs", + "/api/task": "/documentation/components/lab/task", + "/api/computed": "/documentation/api/utilities/computed", + "/api/markdown": "/documentation/components/output/markdown", + "/api/markdown_editor": "/documentation/components/output/markdown_editor", + "/api/matplotlib": "/documentation/components/viz/matplotlib", + "/api/echarts": "/documentation/components/viz/echarts", + "/api/theming": "/documentation/components/lab/theming", + "/api/griddraggable": "/documentation/components/layout/griddraggable", + "/api/gridfixed": "/documentation/components/layout/gridfixed", + "/api/html": "/documentation/components/output/html", + "/api/file_download": "/documentation/components/output/file_download", + "/api/hbox": "/documentation/components/layout/hbox", + "/api/vbox": "/documentation/components/layout/vbox", + "/api/sidebar": "/documentation/components/layout/sidebar", + "/api/row": "/documentation/components/layout/row", + "/api/error": "/documentation/components/status/error", + "/api/info": "/documentation/components/status/info", + "/api/progress": "/documentation/components/status/progress", + "/api/spinner": "/documentation/components/status/spinner", + "/api/success": "/documentation/components/status/success", + "/api/warning": "/documentation/components/status/warning", + "/api/image": "/documentation/components/output/image", + "/api/sql_code": "/documentation/components/output/sql_code", + "/api/tooltip": "/documentation/components/output/tooltip", + "/api/chat": "/documentation/components/lab/chat", + "/api/confirmation_dialog": "/documentation/components/lab/confirmation_dialog", + "/api/cookies_headers": "/documentation/components/lab/cookies_headers", + "/api/input_date": "/documentation/components/lab/input_date", + "/api/button": "/documentation/components/input/button", + "/api/checkbox": "/documentation/components/input/checkbox", + "/api/file_browser": "/documentation/components/input/file_browser", + "/api/file_drop": "/documentation/components/input/file_drop", + "/api/meta": "/documentation/components/advanced/meta", + "/api/style": "/documentation/components/advanced/style", + "/api/menu": "/documentation/components/lab/menu", + "/api/head": "/documentation/components/page/head", + "/api/input": "/documentation/components/input/input", + "/api/select": "/documentation/components/input/select", + "/api/slider": "/documentation/components/input/slider", + "/api/switch": "/documentation/components/input/switch", + "/api/togglebuttons": "/documentation/components/input/togglebuttons", + "/api/dataframe": "/documentation/components/data/dataframe", + "/api/pivot_table": "/documentation/components/data/pivot_table", + "/api/display": "/documentation/api/utilities/display", + "/api/memoize": "/documentation/api/utilities/memoize", + "/api/reactive": "/documentation/api/utilities/reactive", + "/api/widget": "/documentation/api/utilities/widget", + "/api/default_layout": "/documentation/components/layout", + "/api/title": "/documentation/components/page/title", +} @solara.component @@ -96,8 +291,10 @@ def Layout(children=[]): button_text="Quickstart", ) - with rv.Container(tag="section", fluid=True, ma_0=True, pa_0=True, class_="fill-height mb-8 solara-content-main"): - if route_current is not None and route_current.path == "/": + with rv.Container(tag="section", fluid=True, ma_0=True, pa_0=True, class_="fill-height solara-content-main"): + if route_current is None: + return solara.Error("Page not found") + elif route_current.path == "/": description = "Use ipywidgets with Solara to build powerful and scalable web apps for Jupyter and production in Python." # both tags in one solara.Meta(name="description", property="og:description", content=description) @@ -123,9 +320,9 @@ def Layout(children=[]): """ ) with solara.HBox(): - with solara.Link("/docs"): - solara.Button(label="Read more", class_="ma-1 homepage-button", href="/docs", color="primary", dark=True) - with solara.Link("/docs/quickstart"): + with solara.Link("/documentation"): + solara.Button(label="Read more", class_="ma-1 homepage-button", href="/documentation", color="primary", dark=True) + with solara.Link("/documentation/getting_started"): solara.Button(label="Quickstart", class_="ma-1 homepage-button", color="primary", dark=True) # with rv.Col(md=4, sm=5): # rv.Img(src="https://dxhl76zpt6fap.cloudfront.net/public/landing/what.webp", style_="width:900px") @@ -181,7 +378,7 @@ def Layout(children=[]): text=True, outlined=False, ) - with solara.Link("/examples"): + with solara.Link("/documentation/examples"): with solara.Column(style="width: 100%;"): solara.Button( label="More examples", @@ -197,7 +394,7 @@ def Layout(children=[]): In Jupyter or standalone, and run them in production using FastAPI or starlette. - Get more inspiration from our [examples](/examples). + Get more inspiration from our [examples](/documentation/examples). """ ) with rv.ExpansionPanels(v_model=target, on_v_model=set_target, mandatory=True, flat=True): @@ -209,7 +406,8 @@ def Layout(children=[]): rv.ExpansionPanelHeader(children=["FastAPI"]) with rv.ExpansionPanelContent(): solara.Markdown( - "Using [solara-server](/docs/understanding/solara-server), we can run our app in production using FastAPI." + """Using [solara-server](documentation/advanced/understanding/solara-server), + we can run our app in production using FastAPI.""" ) with solara.Column(style={"width": "100%"}): @@ -262,26 +460,32 @@ def Layout(children=[]): solara.Markdown("#### Join our Mailing list to get the latest news") with solara.Div(style={"width": "80%"}): MailChimp(location=router.path) - else: with rv.Row( - style_="gap:6rem; flex-wrap: nowrap;", justify="center" if route_current is not None and route_current.path == "showcase" else "start" + style_="flex-wrap: nowrap; margin: 0; min-height: calc(100vh - 215.5px);", + justify="center" if route_current is not None and route_current.path in ["documentation", "showcase"] else "start", ): if route_current is not None and hasattr(route_current.module, "Sidebar"): route_current.module.Sidebar() # type: ignore else: - if route_current is not None and route_current.path != "showcase": + if route_current is not None and route_current.path not in ["documentation", "showcase", "contact", "changelog"]: Sidebar() - with rv.Col(tag="main", md=True, class_="pt-12 pl-12 pr-10", style_="max-width: 1024px; overflow: auto;"): + with rv.Col( + tag="main", + md=True, + class_="pa-0", + style_=f"""max-width: {'1024px' if route_current.path not in ['documentation', 'contact', 'changelog'] + else 'unset'}; overflow: hidden auto;""", + ): if route_current is not None and route_current.path == "/": with rv.Row(align="center"): pass - # with rv.Col(md=6, class_="pa-0"): - # rv.Html(tag="h1", children=["Live Demo"]) - # with rv.Col(md=6, class_="d-flex", style_="justify-content: end"): - # rv.Btn(elevation=0, large=True, children=["Running App"], color="primary", class_="btn-size--xlarge") - # solara.Padding(6) - with rv.Row(children=children, class_="solara-page-content-search"): + with solara.Row( + children=children, + justify="center", + classes=["solara-page-content-search"], + style=f"height: {'100%' if route_current.path == 'documentation' else 'unset'};", + ): pass # absolute = True prevents the drawer from being below the overlay it generates @@ -344,7 +548,6 @@ def Testimonial(text, name, position, img): max_width=max_width, class_="testimonial-card", ): - # rv.CardTitle(children=["Former Plotly CEO"]) with rv.CardActions(): with rv.ListItem(class_="grow"): with rv.ListItemAvatar(color="grey darken-3"): diff --git a/solara/website/pages/api/__init__.py b/solara/website/pages/api/__init__.py deleted file mode 100644 index ee9f94eec..000000000 --- a/solara/website/pages/api/__init__.py +++ /dev/null @@ -1,292 +0,0 @@ -""" -# Overview -Click on one of the items on the left. -""" - -import solara -from solara.alias import rv - -from .. import List -from .. import SimpleListItem as ListItem - -_title = "API" - - -# @solara.component -# def Page(): -# return solara.Markdown(__doc__) - -items = [ - { - "name": "Input", - "icon": "mdi-chevron-left-box", - "pages": ["button", "checkbox", "input", "select", "slider", "switch", "togglebuttons", "file_browser", "file_drop"], - }, - { - "name": "Output", - "icon": "mdi-chevron-right-box", - "pages": ["markdown", "markdown_editor", "html", "image", "sql_code", "file_download", "tooltip"], - }, - { - "name": "Status", - "icon": "mdi-information", - "pages": ["success", "info", "warning", "error", "spinner", "progress"], - }, - { - "name": "Viz", - "icon": "mdi-chart-histogram", - "pages": ["altair", "echarts", "matplotlib", "plotly", "plotly_express"], - }, - { - "name": "Layout", - "icon": "mdi-page-layout-sidebar-left", - "pages": [ - "app_layout", - "app_bar", - "app_bar_title", - "card", - "card_actions", - "columns", - "columns_responsive", - "column", - "row", - "griddraggable", - "gridfixed", - "sidebar", - "hbox", - "vbox", - ], - }, - { - "name": "Data", - "icon": "mdi-database", - "pages": ["dataframe", "pivot_table"], - }, - { - "name": "Page", - "icon": "mdi-file-code", - "pages": ["head", "title"], - }, - { - "name": "Hooks", - "icon": "mdi-hook", - "pages": [ - "use_cross_filter", - "use_thread", - "use_exception", - "use_effect", - "use_memo", - "use_previous", - "use_reactive", - "use_state", - "use_state_or_update", - "use_trait_observe", - ], - }, - { - "name": "Types", - "icon": "mdi-fingerprint", - "pages": ["route"], - }, - { - "name": "Routing", - "icon": "mdi-router", - "pages": ["use_route", "use_router", "resolve_path", "generate_routes", "generate_routes_directory", "link"], - }, - { - "name": "Utils", - "icon": "mdi-hammer-wrench", - "pages": [ - "display", - "get_kernel_id", - "get_session_id", - "memoize", - "reactive", - "widget", - "component_vue", - ], - }, - { - "name": "Advanced", - "icon": "mdi-head-cog-outline", - "pages": ["style", "meta"], - }, - { - "name": "Cross filter", - "icon": "mdi-filter-variant-remove", - "pages": ["cross_filter_dataframe", "cross_filter_report", "cross_filter_slider", "cross_filter_select"], - }, - { - "name": "Enterprise", - "icon": "mdi-office-building", - "pages": ["avatar", "avatar_menu"], - }, - { - "name": "Lab (experimental)", - "icon": "mdi-flask-outline", - "pages": [ - "computed", - "chat", - "confirmation_dialog", - "cookies_headers", - "menu", - "input_date", - "on_kernel_start", - "tab", - "tabs", - "task", - "theming", - "use_task", - "use_dark_effective", - ], - }, -] - - -@solara.component -def Page(): - # show a gallery of all the api pages - router = solara.use_router() - route_current = router.path_routes[-2] - - routes = {r.path: r for r in route_current.children} - - for item in items: - solara.Markdown(f"## {item['name']}") - with solara.ColumnsResponsive(12, 6, 6, 4, 4): - for page in item["pages"]: - if page not in routes: - continue - route = routes[page] - path = route.path - image_url = None - if page in [ - "button", - "checkbox", - "confirmation_dialog", - "echarts", - "file_browser", - "file_download", - "matplotlib", - "select", - "switch", - "tooltip", - ]: - image_url = "https://dxhl76zpt6fap.cloudfront.net/public/api/" + page + ".gif" - elif page in ["card", "dataframe", "pivot_table", "slider"]: - image_url = "https://dxhl76zpt6fap.cloudfront.net/public/api/" + page + ".png" - else: - image_url = "https://dxhl76zpt6fap.cloudfront.net/public/logo.svg" - - path = getattr(route.module, "redirect", path) - if path: - with rv.Card( - elevation=2, - dark=False, - height="100%", - style_="display: flex; flex-direction: column; justify-content: space-between;", - ): - rv.CardTitle(children=[route.label]) - with rv.CardText(): - with solara.Link(path): - with solara.Column(align="center"): - solara.Image(image_url, width="120px") - doc = route.module.__doc__ or "" - if doc: - lines = doc.split("\n") - lines = [line.strip() for line in lines if line.strip()] - first = lines[1] - - rv.CardText( - children=[solara.Markdown(first)], - ) - - -@solara.component -def NoPage(): - raise RuntimeError("This page should not be rendered") - - -@solara.component -def Sidebar(children=[], level=0): - # note that we don't use children here, but we used route.module instead to ge the module - # this is fine because all api/*.py files use the standard Page component, and do not add - # a new Layout component - route_current, all_routes = solara.use_route() - if route_current is None: - return solara.Error("Page not found") - - # keeps track of which routes we includes - routes = {r.path: r for r in all_routes.copy()} - - def add(path): - route = routes[path] - with solara.Link(route): - ListItem(route.label, class_="active" if route_current is not None and path == route_current.path else None) - del routes[path] - - # with solara.HBox(grow=True) as main: - with rv.Col(tag="aside", md=4, lg=3, class_="sidebar bg-grey d-none d-md-block") as main: - with solara.Head(): - name = route_current.label if route_current.label is not None else "No name" - if name == "API": - solara.Title("Solara » API overview") - else: - solara.Title("Solara » API » " + name) - with List(): - add("/") - - for item in items: - with ListItem(item["name"], icon_name=item["icon"]): - with List(): - for component in item["pages"]: - add(component) - - if routes: - print(f"Routes not used: {list(routes.keys())}") # noqa - - return main - - -@solara.component -def Layout(children=[]): - route_current, all_routes = solara.use_route() - if route_current is None: - return solara.Error("Page not found") - - if route_current.path == "/": - return Page() - else: - with solara.HBox(grow=True) as main: - with solara.Padding(4): - if route_current.module: - # we ignore children, and make the element again - WithCode(route_current.module) - return main - - -@solara.component -def WithCode(module): - # e = solara.use_exception_handler() - # if e is not None: - # return solara.Error("oops") - component = getattr(module, "Page", None) - with rv.Sheet() as main: - # It renders code better - solara.Markdown( - module.__doc__ or "# no docs yet", - unsafe_solara_execute=True, - ) - if component and component != NoPage: - with solara.Card("Example", margin=0, classes=["mt-8"]): - component() - github_url = solara.util.github_url(module.__file__) - solara.Button( - label="View source", - icon_name="mdi-github-circle", - attributes={"href": github_url, "target": "_blank"}, - text=True, - outlined=True, - class_="mt-8", - ) - return main diff --git a/solara/website/pages/api/default_layout.py b/solara/website/pages/api/default_layout.py deleted file mode 100644 index 0b00e800e..000000000 --- a/solara/website/pages/api/default_layout.py +++ /dev/null @@ -1,16 +0,0 @@ -"""# DefaultLayout - -""" - -import solara -from solara.website.utils import apidoc - -title = "DefaultLayout" - - -@solara.component -def Page(): - return solara.Warning("This component does not render well as a child component. If you want to see it, you should follow the multipage guide above 🙂") - - -__doc__ += apidoc(solara.DefaultLayout.f) # type: ignore diff --git a/solara/website/pages/apps/jupyter-dashboard-1.py b/solara/website/pages/apps/jupyter-dashboard-1.py index 01ddd3ee9..605263082 100644 --- a/solara/website/pages/apps/jupyter-dashboard-1.py +++ b/solara/website/pages/apps/jupyter-dashboard-1.py @@ -14,7 +14,7 @@ limit = solara.reactive(100) -ROOT = Path(solara.__file__).parent / "website" / "pages" / "docs" / "content" / "04-tutorial" +ROOT = Path(solara.__file__).parent / "website" / "pages" / "documentation" / "getting_started" / "content" / "04-tutorials" path = ROOT / Path("SF_crime_sample.csv.gz") url = "https://raw.githubusercontent.com/widgetti/solara/master/solara/website/pages/docs/content/04-tutorial/SF_crime_sample.csv" diff --git a/solara/website/pages/apps/multipage/__init__.py b/solara/website/pages/apps/multipage/__init__.py index 2fe8debea..e5387949b 100644 --- a/solara/website/pages/apps/multipage/__init__.py +++ b/solara/website/pages/apps/multipage/__init__.py @@ -12,7 +12,7 @@ def SharedComponent(): f""" This component will be used on each page. - It uses the `app_state` [reactive variable](https://solara.dev/api/reactive) + It uses the `app_state` [reactive variable](https://solara.dev/documentation/api/utilities/reactive) so that the state outlives each page diff --git a/solara/website/pages/apps/multipage/page2.py b/solara/website/pages/apps/multipage/page2.py index 07a460ad5..2d2516d0c 100644 --- a/solara/website/pages/apps/multipage/page2.py +++ b/solara/website/pages/apps/multipage/page2.py @@ -23,7 +23,7 @@ def Page(): It creates the `component_state` [using the use_reactive hook](https://solara.dev/api/use_reactive) so that the state is bound to the component. - See also [about state management](https://solara.dev/docs/fundamentals/state-management) for more information. + See also [about state management](https://solara.dev/documentation/getting_started/fundamentals/state-management) for more information. component_state: {component_state.value} diff --git a/solara/website/pages/changelog/__init__.py b/solara/website/pages/changelog/__init__.py new file mode 100644 index 000000000..3fce157d9 --- /dev/null +++ b/solara/website/pages/changelog/__init__.py @@ -0,0 +1,8 @@ +from pathlib import Path + +import solara + +title = "Changelog" +HERE = Path(__file__) + +Page = solara.Markdown(Path(HERE.parent / "changelog.md").read_text()) diff --git a/solara/website/pages/docs/content/95-changelog.md b/solara/website/pages/changelog/changelog.md similarity index 98% rename from solara/website/pages/docs/content/95-changelog.md rename to solara/website/pages/changelog/changelog.md index 511f466fa..1ba977ef6 100644 --- a/solara/website/pages/docs/content/95-changelog.md +++ b/solara/website/pages/changelog/changelog.md @@ -149,7 +149,7 @@ ### Highlights * Feature: Solara now has a production mode (enabled by passing in `--production`) which will load optimized CSS and JS and disable hot reloading. - Our [Solara server](https://solara.dev/docs/understanding/solara-server) page contains more information about it. If you used `--reload` or + Our [Solara server](https://solara.dev/documentation/advanced/understanding/solara-server) page contains more information about it. If you used `--reload` or `--dev` before you can now use the `-a/--auto-restart` flat. The `--dev` and `--reload` flags are kept for backwards compatibility. * Feature: All `Input` components expose the `style` and `classes` arguments for custom styling. * Feature: New component: [`InputDate` and `InputDateRange`](https://solara.dev/api/input_date) which use a datepicker in a menu. (#326) diff --git a/solara/website/pages/contact/__init__.py b/solara/website/pages/contact/__init__.py new file mode 100644 index 000000000..25523f9b3 --- /dev/null +++ b/solara/website/pages/contact/__init__.py @@ -0,0 +1,8 @@ +from pathlib import Path + +import solara + +title = "Contact" +HERE = Path(__file__) + +Page = solara.Markdown(Path(HERE.parent / "contact.md").read_text()) diff --git a/solara/website/pages/docs/content/99-contact.md b/solara/website/pages/contact/contact.md similarity index 100% rename from solara/website/pages/docs/content/99-contact.md rename to solara/website/pages/contact/contact.md diff --git a/solara/website/pages/docs/content/04-tutorial/00-overview.md b/solara/website/pages/docs/content/04-tutorial/00-overview.md deleted file mode 100644 index aca1e4801..000000000 --- a/solara/website/pages/docs/content/04-tutorial/00-overview.md +++ /dev/null @@ -1,9 +0,0 @@ -# Tutorials - -Instead of having one tutorial, we have tutorials for different audiences. - - * [Jupyter Dashboard](/docs/tutorial/jupyter-dashboard-part1): Learn to create a dashboard in the Jupyter notebook. - * [Data science](/docs/tutorial/data-science): In this tutorial, we will introduce Solara from the perspective of a data scientist or when you are thinking of using Solara for a data science app. - * [Web app](/docs/tutorial/web-app): You are not a data scientist, but you are interested in using Solara to create a web app using Pure Python. - * [IPywidgets user](/docs/tutorial/ipywidgets): If you are already using [ipywidgets](/docs/understanding/ipywidgets) you will learn how to use the [Solara server](/docs/understanding/solara-server) to render your regular ipywidget applications. - * [Streamlit](/docs/tutorial/streamlit): If you are an existing Streamlit user, this might appeal more to you. diff --git a/solara/website/pages/docs/content/07-fundamentals/00-overview.md b/solara/website/pages/docs/content/07-fundamentals/00-overview.md deleted file mode 100644 index 8ef50dabd..000000000 --- a/solara/website/pages/docs/content/07-fundamentals/00-overview.md +++ /dev/null @@ -1,7 +0,0 @@ -# Fundamentals - -If you want to dive deeper into Solara, this section is for you. We will cover the following topics: - - * [Components](/docs/fundamentals/components) - * Hooks (soon) - * [State management](/docs/fundamentals/state-management) diff --git a/solara/website/pages/docs/content/15-reference/00-overview.md b/solara/website/pages/docs/content/15-reference/00-overview.md deleted file mode 100644 index c7521997c..000000000 --- a/solara/website/pages/docs/content/15-reference/00-overview.md +++ /dev/null @@ -1,6 +0,0 @@ -# Reference documentation - -Our reference documentation informs you about how certain parts in Solara work. - -The [API docs](/api) are considered part of the reference documentation, but because of the -large content has its own page. diff --git a/solara/website/pages/docs/content/30-deploying/00-overview.md b/solara/website/pages/docs/content/30-deploying/00-overview.md deleted file mode 100644 index 00affea62..000000000 --- a/solara/website/pages/docs/content/30-deploying/00-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# Deploying a solara app - -A Solara app can be [self hosted](/docs/deploying/self-hosted) or [cloud hosted](/docs/deploying/cloud-hosted). diff --git a/solara/website/pages/documentation/__init__.py b/solara/website/pages/documentation/__init__.py new file mode 100644 index 000000000..b540c74d9 --- /dev/null +++ b/solara/website/pages/documentation/__init__.py @@ -0,0 +1,181 @@ +from pathlib import Path + +import solara + +_title = "Documentation" + +HERE = Path(__file__).parent + +route_order = ["/", "getting_started", "examples", "components", "api", "advanced", "faq"] + + +@solara.component_vue(str(HERE.parent.parent / "components" / "algolia_api.vue")) +def Algolia(): + pass + + +@solara.component +def Page(children=[]): + # show a gallery of all the api pages + router = solara.use_router() + route_current = router.path_routes[-2] + + with solara.Column(style={"width": "100%"}, gap="75px"): + if route_current.path == "documentation": + with solara.Column(classes=["api-search-container"], gap="50px", style={"justify-content": "center"}, align="center"): + solara.Markdown("# Search the Solara Documentation", style={"text-align": "center"}) + with solara.Row(style={"width": "100%", "min-width": "20rem", "justify-content": "center", "background-color": "transparent"}): + Algolia() + with solara.Row(gap="20px", classes=["docs-card-container"]): + for route in route_current.children: + if route.path in ["/", "advanced", "faq"]: + continue + with solara.Link("/documentation/" + route.path): + with solara.Row( + classes=["docs-card"], + style={ + "background-color": f"var({'--docs-color-grey' if route.path != 'getting_started' else '--color-primary'})", + }, + ): + with solara.Column(style={"height": "100%", "flex-grow": "1", "background-color": "transparent"}): + solara.HTML(tag="h2", unsafe_innerHTML=route.label, style={"color": "white", "padding": "1.5rem"}) + with solara.Column(style={"justify-content": "center", "height": "100%", "background-color": "transparent"}): + solara.v.Icon(children=["mdi-arrow-right"], color="var(--color-grey-light)", x_large=True, class_="docs-card-icon") + with solara.Row(gap="75px", style={"flex-wrap": "wrap", "row-gap": "75px", "padding-bottom": "75px"}): + with solara.Column(style={"padding-left": "10%"}): + solara.HTML(tag="h2", unsafe_innerHTML="How to use our documentation:", style={"padding": "1.5rem"}) + solara.Markdown( + """ +* [Getting Started](/documentation/getting_started) - Learn how to install Solara and get started with building your app. + Also includes tutorials for you to get a hang of Solara workflow. +* [Examples](/documentation/examples) - More complex and real world applicable examples of Solara apps. + For even more complexity you can see the [Showcase](/showcase) page. +* [Components](/documentation/components) - All the components that are available in Solara. +* [API](/documentation/api) - All the API functions that are available in Solara. Importantly, this includes routing and hooks. +* [Advanced](/documentation/advanced) - Advanced topics like associated and underlying libraries. + If a component you would like to use is not available in Solara, you can use the underlying library directly. + """ + ) + with solara.Column(style={"justify-content": "center", "height": "100%"}): + solara.HTML(tag="h2", unsafe_innerHTML="Also Check Out", style={"padding": "1.5rem"}) + with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center"}): + with solara.v.Html(tag="a", attributes={"href": "https://discord.solara.dev", "target": "_blank"}): + with solara.Div(classes=["social-logo-container"], style={"background-color": "var(--docs-social-discord)"}): + solara.v.Html(tag="img", attributes={"src": "/static/public/social/discord.svg"}, style_="height: 1.5rem; width: auto;") + solara.Text("We use discord to provide support and answer questions there actively.") + with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center"}): + with solara.v.Html(tag="a", attributes={"href": "https://github.com/widgetti/solara", "target": "_blank"}): + with solara.Div(classes=["social-logo-container"], style={"background-color": "var(--docs-social-github)"}): + solara.v.Html(tag="img", attributes={"src": "/static/public/social/github.svg"}, style_="height: 1.5rem; width: auto;") + solara.Text("Search for solutions on Github issues, or report bugs.") + with solara.Row(gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "align-items": "center"}): + with solara.v.Html(tag="a", attributes={"href": "https://twitter.com/solara_dev", "target": "_blank"}): + with solara.Div(classes=["social-logo-container"], style={"background-color": "var(--docs-social-twitter)"}): + solara.v.Html(tag="img", attributes={"src": "/static/public/social/twitter.svg"}, style_="height: 1.5rem; width: auto;") + solara.Text("Get announcements about Solara features, showcases, and events!.") + + else: + with solara.Column(align="center", children=children, style={"padding": "0"}): + pass + + +@solara.component +def Sidebar(): + route_current, all_routes = solara.use_route() + if route_current is None: + return solara.Error("Page not found") + + with solara.v.NavigationDrawer( + clipped=True, width="20rem", height="unset", style_="min-height: calc(100vh - 215.5px);", class_="d-none d-md-block" + ) as main: + with solara.v.List(expand=True, nav=True, style_="height: calc(100vh - 215.5px); display: flex; flex-direction: column;"): + with solara.v.ListItemGroup(): + for route in all_routes: + if len(route.children) == 1 or route.path == "/": + with solara.Link("/documentation/" + route.path if route.path != "/" else "/documentation"): + with solara.v.ListItem(): + if route.path == "/": + solara.v.ListItemIcon(children=[solara.v.Icon(children=["mdi-home"])]) + solara.v.ListItemTitle(style_="padding: 0 20px;", children=[route.label]) + else: + with solara.v.ListGroup( + v_slots=[ + { + "name": "activator", + "children": solara.v.ListItemTitle( + children=[route.label], + style_="padding: 0 20px;", + ), + } + ] + ): + for item in route.children: + if item.path == "/": + continue + if item.children != [] and any([c.label is not None and c.path != "/" for c in item.children]): + with solara.v.ListGroup( + v_slots=[ + { + "name": "activator", + "children": solara.v.ListItemTitle( + children=[item.label], + ), + } + ], + sub_group=True, + no_action=True, + ): + for subitem in item.children: + # skip pages that are only used to demonstrate Link or Router usage + if subitem.path == "/" or subitem.label is None: + continue + path = ( + "/documentation/" + route.path + "/" + item.path + "/" + subitem.path + if item.path != "fullscreen" + else "/apps/" + subitem.path + ) + with solara.Link( + path, + ): + with solara.v.ListItem(dense=True, style_="padding: 0 20px;"): + solara.v.ListItemContent( + children=[subitem.label], + ) + else: + with solara.v.ListItemGroup(): + with solara.Link( + "/documentation/" + route.path + "/" + item.path, + ): + with solara.v.ListItem(dense=True, style_="padding: 0 20px;"): + solara.v.ListItemContent( + children=[item.label], + ) + solara.v.Spacer(style_="flex-grow: 1;") + with solara.v.ListItemGroup(): + with solara.Link("/contact"): + with solara.v.ListItem(): + solara.v.ListItemIcon(children=[solara.v.Icon(children=["mdi-email"])]) + solara.v.ListItemTitle(style_="padding: 0 20px;", children=["Contact"]) + with solara.Link("/changelog"): + with solara.v.ListItem(): + solara.v.ListItemIcon(children=[solara.v.Icon(children=["mdi-history"])]) + solara.v.ListItemTitle(style_="padding: 0 20px;", children=["Changelog"]) + + return main + + +@solara.component +def Layout(children=[]): + route_current, all_routes = solara.use_route() + if route_current is None: + return solara.Error("Page not found") + + if route_current.path == "/": + return Page() + else: + return Page(children=children) + + +@solara.component +def Overview(): + pass diff --git a/solara/website/pages/documentation/advanced/__init__.py b/solara/website/pages/documentation/advanced/__init__.py new file mode 100644 index 000000000..64e457815 --- /dev/null +++ b/solara/website/pages/documentation/advanced/__init__.py @@ -0,0 +1,36 @@ +from pathlib import Path + +import solara +from solara.autorouting import generate_routes_directory + +title = "Advanced" +HERE = Path(__file__) +# if we didn't put the content in the subdirectory, but pointed to the current file +# we would include the current file recursively, causing an infinite loop +routes = generate_routes_directory(HERE.parent / "content") + + +@solara.component +def Page(route_external=None): + solara.Markdown(Path(HERE.parent / "content" / "10-howto" / "00-overview.md").read_text()) + + with solara.Row(justify="center", style={"flex-wrap": "wrap", "align-items": "start"}): + for child in route_external.children: + if child.path == "/": + continue + + card_title = solara.Link("/documentation/advanced/" + child.path, children=[child.label]) + + with solara.Card(title=card_title, style={"min-width": "300px"}): + with solara.v.List(): + with solara.v.ListItemGroup(): + for grandchild in child.children: + if grandchild.path == "/": + continue + with solara.Link( + "/documentation/advanced/" + child.path + "/" + grandchild.path + if child.path != "/" + else "/documentation/advanced/" + grandchild.path + ): + with solara.v.ListItem(): + solara.v.ListItemTitle(children=[grandchild.label]) diff --git a/solara/website/pages/documentation/advanced/content/00-overview.md b/solara/website/pages/documentation/advanced/content/00-overview.md new file mode 100644 index 000000000..2d9a6d853 --- /dev/null +++ b/solara/website/pages/documentation/advanced/content/00-overview.md @@ -0,0 +1 @@ +The entries are meant as deeper dives into specific topics. Although we try to write each as a standalone document, some parts may build on previous ones. diff --git a/solara/website/pages/docs/content/10-howto/00-overview.md b/solara/website/pages/documentation/advanced/content/10-howto/00-overview.md similarity index 100% rename from solara/website/pages/docs/content/10-howto/00-overview.md rename to solara/website/pages/documentation/advanced/content/10-howto/00-overview.md diff --git a/solara/website/pages/docs/content/10-howto/20-multipage.md b/solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md similarity index 92% rename from solara/website/pages/docs/content/10-howto/20-multipage.md rename to solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md index b71623c2d..0fd498057 100644 --- a/solara/website/pages/docs/content/10-howto/20-multipage.md +++ b/solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md @@ -1,6 +1,6 @@ # Multi-page support -In the [Web App tutorial](/docs/tutorial/web-app), we created an application consisting of a single page. Web applications generally have multiple pages, and Solara supports this as well. +In the [Web App tutorial](/documentation/getting_started/tutorials/web-app), we created an application consisting of a single page. Web applications generally have multiple pages, and Solara supports this as well. ## Multiple scripts @@ -42,8 +42,7 @@ Solara now: * Generate a nice URL by stripping of prefix, splitting the filename taking out `-`, `_` and spaces, and join them together using a `-` (e.g. "/markdown-editor"). * Generate a nice default title similar to the link, but now capitalize the first letter and join with a space instead (e.g. "Mardown Editor"). * The first page will be the default (and its URL will be empty instead, i.e., the empty string `""`) - * Since the first script does not define a `Layout` component, nor did we add a `__init__.py` with a `Layout` component, Solara will add a [default - Layout component](/api/default_layout) which includes a navigation sidebar. + * Since the first script does not define a `Layout` component, nor did we add a `__init__.py` with a `Layout` component, Solara will add a [Layout component](/documentation/components/layout/app_layout) which includes a navigation sidebar. * If a path is a directory, Solara will recursively scan the subdirectory and include it in the navigation. Read more on this in the [Layout section](layout) Solara will render two pages: @@ -148,7 +147,7 @@ routes = [ ] ``` -See more details in the [Route section](/docs/understanding/routing). +See more details in the [Route section](/documentation/advanced/understanding/routing). ## Dynamic pages @@ -189,4 +188,4 @@ By giving the name argument a default value of `"foo"`, Solara will also accept # What next? - * Also check out the [Multipage example](/apps/multipage) for more inspiration. + * Also check out the [Multipage example](/documentation/examples/fullscreen/multipage) for more inspiration. diff --git a/solara/website/pages/docs/content/10-howto/30-layout.md b/solara/website/pages/documentation/advanced/content/10-howto/20-layout.md similarity index 60% rename from solara/website/pages/docs/content/10-howto/30-layout.md rename to solara/website/pages/documentation/advanced/content/10-howto/20-layout.md index df33ac5af..1842812ad 100644 --- a/solara/website/pages/docs/content/10-howto/30-layout.md +++ b/solara/website/pages/documentation/advanced/content/10-howto/20-layout.md @@ -33,29 +33,29 @@ def Page(): solara.Info("two per column on small screens, three per column on large screens") ``` -[Navigate here to watch this layout in a full browser window](/apps/layout-demo) +[Navigate here to watch this layout in a full browser window](/documentation/examples/fullscreen/layout_demo) The key takeaways are: - * By default, Solara will wrap your component in an [AppLayout](/api/app_layout), which will give you: - * Room for a sidebar, that you can populate using the [Sidebar](/api/sidebar) component. - * A toolbar showing the [Title](/api/title). - * Not visible here: In the case of [multiple pages](/docs/howto/multipage) will include page navigation tabs. See [The multipage demo app](/app/multipage) for an example. - * Use [Card](/api/card) to put related components together with a title. - * Use [Column](/api/column) to simply layout components under each other. - * Use [Columns](/api/columns) if you want to have a few columns with relative sizes next to each other. - * Use [ColumnsResponsive](/api/columns_responsive) to have the column widths respond to screen size. + * By default, Solara will wrap your component in an [AppLayout](/documentation/components/layout/app_layout), which will give you: + * Room for a sidebar, that you can populate using the [Sidebar](/documentation/components/layout/sidebar) component. + * A toolbar showing the [Title](/documentation/components/page/title). + * Not visible here: In the case of [multiple pages](/documentation/advanced/howto/multipage) will include page navigation tabs. See [The multipage demo app](/documentation/examples/fullscreen/multipage) for an example. + * Use [Card](/documentation/components/layout/card) to put related components together with a title. + * Use [Column](/documentation/components/layout/column) to simply layout components under each other. + * Use [Columns](/documentation/components/layout/columns) if you want to have a few columns with relative sizes next to each other. + * Use [ColumnsResponsive](/documentation/components/layout/columns_responsive) to have the column widths respond to screen size. ## Changing the default layout -While [AppLayout](/api/app_layout) may be sufficient in 80% of the cases. Solara provides a way to change this default layout in [Solara server](/docs/understanding/solara-server). +While [AppLayout](/documentation/components/layout/app_layout) may be sufficient in 80% of the cases. Solara provides a way to change this default layout in [Solara server](/documentation/advanced/understanding/solara-server). You can define your own `Layout` component in the `__init__.py` file in the same directory of your app script. -For instance, putting the following `Layout` component in `__init__.py` will give you effectively the same [AppLayout](/api/app_layout): +For instance, putting the following `Layout` component in `__init__.py` will give you effectively the same [AppLayout](/documentation/components/layout/app_layout): ```python @solara.component def Layout(children=[]): @@ -80,7 +80,7 @@ This layout leaves every page responsible for creating its own header, footer, a ### Layout with navigation In case you want to set up your own layout system, which sets up navigation as well, this example may get you started. It may help -to [understand routing](/docs/understanding/routing). +to [understand routing](/documentation/advanced/understanding/routing). ```python @solara.component def Layout(children=[]): @@ -108,13 +108,13 @@ This is useful for larger apps where each subdirectory may add a bit of layout/c ## Components -The following [Container components](/docs/understanding/containers) can be used to define the layout of you app. +The following [Container components](/documentation/advanced/understanding/containers) can be used to define the layout of you app. - * [Row](/api/row) - * [Column](/api/column) - * [ColumnsResponsive](/api/columns_responsive) - * [GridFixed](/api/gridfixed) - * [GridDraggable](/api/griddraggable) - * [VBox](/api/vbox) (kept for ipywidgets compatibility, please use Column) - * [HBox](/api/hbox) (kept for ipywidgets compatibility, please use Row) - * [AppLayout](/api/app_layout) Not often used directly, since Solara will already wrap your page in it. Sometimes re-used in a new `Layout` component. + * [Row](/documentation/components/layout/row) + * [Column](/documentation/components/layout/column) + * [ColumnsResponsive](/documentation/components/layout/columns_responsive) + * [GridFixed](/documentation/components/layout/gridfixed) + * [GridDraggable](/documentation/components/layout/griddraggable) + * [VBox](/documentation/components/layout/vbox) (kept for ipywidgets compatibility, please use Column) + * [HBox](/documentation/components/layout/hbox) (kept for ipywidgets compatibility, please use Row) + * [AppLayout](/documentation/components/layout/app_layout) Not often used directly, since Solara will already wrap your page in it. Sometimes re-used in a new `Layout` component. diff --git a/solara/website/pages/docs/content/10-howto/50-testing.md b/solara/website/pages/documentation/advanced/content/10-howto/30-testing.md similarity index 100% rename from solara/website/pages/docs/content/10-howto/50-testing.md rename to solara/website/pages/documentation/advanced/content/10-howto/30-testing.md diff --git a/solara/website/pages/docs/content/10-howto/51-debugging.md b/solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md similarity index 100% rename from solara/website/pages/docs/content/10-howto/51-debugging.md rename to solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md diff --git a/solara/website/pages/docs/content/10-howto/80-embed.md b/solara/website/pages/documentation/advanced/content/10-howto/40-embed.md similarity index 94% rename from solara/website/pages/docs/content/10-howto/80-embed.md rename to solara/website/pages/documentation/advanced/content/10-howto/40-embed.md index e76cd2b10..59f20e3fb 100644 --- a/solara/website/pages/docs/content/10-howto/80-embed.md +++ b/solara/website/pages/documentation/advanced/content/10-howto/40-embed.md @@ -40,4 +40,4 @@ Solara uses a cookie to implement sessions. To support cookies settings in an if ## Embed into an existing page -If embedding into an iframe does not suit your needs (for example, dialogs not being fullscreen), [please contact us](/docs/contact) and we can discuss other options. +If embedding into an iframe does not suit your needs (for example, dialogs not being fullscreen), [please contact us](/contact) and we can discuss other options. diff --git a/solara/website/pages/docs/content/10-howto/ipywidget_libraries.md b/solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md similarity index 100% rename from solara/website/pages/docs/content/10-howto/ipywidget_libraries.md rename to solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md diff --git a/solara/website/pages/docs/content/20-understanding/00-introduction.md b/solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md similarity index 100% rename from solara/website/pages/docs/content/20-understanding/00-introduction.md rename to solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md diff --git a/solara/website/pages/docs/content/20-understanding/05-ipywidgets.md b/solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md similarity index 100% rename from solara/website/pages/docs/content/20-understanding/05-ipywidgets.md rename to solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md diff --git a/solara/website/pages/docs/content/20-understanding/06-ipyvuetify.md b/solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md similarity index 92% rename from solara/website/pages/docs/content/20-understanding/06-ipyvuetify.md rename to solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md index 1ef39d369..f37f4f608 100644 --- a/solara/website/pages/docs/content/20-understanding/06-ipyvuetify.md +++ b/solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md @@ -11,7 +11,7 @@ material design based widgets. ## Reacton and ipyvuetify -We consider ipyvuetify one of the most essential ipywidget libraries, and that is the reason why [Reacton](/docs/understanding/reacton) ships with +We consider ipyvuetify one of the most essential ipywidget libraries, and that is the reason why [Reacton](/documentation/advanced/understanding/reacton) ships with generated ipyvuetify components to make your app type safe. ```solara diff --git a/solara/website/pages/docs/content/20-understanding/10-reacton.md b/solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md similarity index 100% rename from solara/website/pages/docs/content/20-understanding/10-reacton.md rename to solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md diff --git a/solara/website/pages/docs/content/20-understanding/12-reacton-basics.md b/solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md similarity index 96% rename from solara/website/pages/docs/content/20-understanding/12-reacton-basics.md rename to solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md index 82e07c62b..0de513ffe 100644 --- a/solara/website/pages/docs/content/20-understanding/12-reacton-basics.md +++ b/solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md @@ -90,7 +90,7 @@ In words 1. Solara create `el = ButtonClick()` from your component. 1. The `display(el)` triggers the call to Reacton. 1. The render call enters the render phase, which will call the function body (which we call render function) of the `ButtonClick` component. - 1. Our ButtonClick render function calls [`use_state`](/api/use_state). Because this is our first render phase, this returns the initial value (0). + 1. Our ButtonClick render function calls [`use_state`](/documentation/api/hooks/use_state). Because this is our first render phase, this returns the initial value (0). 1. The ButtonClick render function returns a Button element (not a widget!) with `description="Clicked: 0 times"`. 1. The Reacton render call is done with the render phase, and enters the reconciliation phase, where it looks at the difference between the real widgets and the virtual widgets tree (represented by the Reacton elements). We find there is no previous widget associated with the virtual widget (or element) and decide to create a widget. 1. Asynchronously via the Jupyter protocol, a widget model and view are created and displayed to the user in the browser. diff --git a/solara/website/pages/docs/content/20-understanding/15-anatomy.md b/solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md similarity index 84% rename from solara/website/pages/docs/content/20-understanding/15-anatomy.md rename to solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md index 231e835ea..cdb34ae9e 100644 --- a/solara/website/pages/docs/content/20-understanding/15-anatomy.md +++ b/solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md @@ -9,10 +9,10 @@ As a reference, we provide this "anatomy" image of our favorite `ClickButton` co * Import `solara` and you also get the `reacton` namespace with it (saves typing, and finding/remembering which hooks is in which packages) * Add a `@solara.component` decorator to turn your function into a component. - * Start with `use_state` hooks and other hooks. This avoids issues with [conditional hooks](/docs/understanding/rules-of-hooks) or hooks in loops. + * Start with `use_state` hooks and other hooks. This avoids issues with [conditional hooks](/documentation/advanced/understanding/rules-of-hooks) or hooks in loops. * Data/state flows down (to children) * Information (events, data) flows up from children via events and callbacks (`on_=my_callback`). - * If you need multiple components, use a [parent container component](/api#layout) as context manager. A good default name to give this context manager is `main`. Don't forget to return it in your render function! + * If you need multiple components, use a [parent container component](/documentation/components/layout/app_layout) as context manager. A good default name to give this context manager is `main`. Don't forget to return it in your render function! * The body of your component (the function you wrote) is called the render function. * In between the hooks as defining all your elements, you put your custom code, like checking variables, defining callbacks, and other logic. * The only way for a component to cause itself to rerender is to have state (using `use_state`) and change it (calling the second return value with a different value). diff --git a/solara/website/pages/docs/content/20-understanding/17-rules-of-hooks.md b/solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md similarity index 100% rename from solara/website/pages/docs/content/20-understanding/17-rules-of-hooks.md rename to solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md diff --git a/solara/website/pages/docs/content/20-understanding/18-containers.md b/solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md similarity index 92% rename from solara/website/pages/docs/content/20-understanding/18-containers.md rename to solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md index b44b586a5..83b0b4112 100644 --- a/solara/website/pages/docs/content/20-understanding/18-containers.md +++ b/solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md @@ -51,7 +51,7 @@ Page = FancyClickButton ``` -Here we use an [HBox](/api/hbox) to lay out two child components horizontally. +Here we use an [HBox](/documentation/components/layout/hbox) to lay out two child components horizontally. ## Cleaner way to add children to containers @@ -96,7 +96,7 @@ with some_named_context_manager() as this_is_my_name: print("some other code") ``` -Where the last example assigns the context manager to a variable. In Solara we only need to do that to the top context manager, since we need to return that in our [render function](/docs/understanding/anatomy). +Where the last example assigns the context manager to a variable. In Solara we only need to do that to the top context manager, since we need to return that in our [render function](/documentation/advanced/understanding/anatomy). All Reacton or Solara components return elements that can be used as context managers. Context managers allow for code to be executed before and after your code block inside of the context manager. This allows us to capture all elements created inside of the context manager. If you want to know more about context managers, consult the Python documentation since this is not Solara specific. @@ -138,7 +138,7 @@ Page = FancyClickButton Instead of returning the main container, Solara also allows you to not have a return value (or return `None`). If that is the case, Solara will look at what elements you created. If you created one, that element will be taken as a return value instead. If you make more than one element, those elements will be automatically wrapped by -a [Column](/api/column). The only benefit of returning an element, is that we can infer the correct return type, +a [Column](/documentation/components/layout/column). The only benefit of returning an element, is that we can infer the correct return type, which can be useful for testing purposes. Users should probably never return an element, but use the automatic container feature. diff --git a/solara/website/pages/docs/content/20-understanding/20-solara.md b/solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md similarity index 100% rename from solara/website/pages/docs/content/20-understanding/20-solara.md rename to solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md diff --git a/solara/website/pages/docs/content/20-understanding/40-routing.md b/solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md similarity index 88% rename from solara/website/pages/docs/content/20-understanding/40-routing.md rename to solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md index 743395b4c..5d6db05e4 100644 --- a/solara/website/pages/docs/content/20-understanding/40-routing.md +++ b/solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md @@ -13,15 +13,15 @@ Setting up routing can be repetitive, and therefore Solara comes also with a mor ### Based on a directory -Using [`generate_routes_directory(path: Path) -> List[solara.Route]:`](/api/generate_routes_directory) we can request Solara to give us a list of +Using [`generate_routes_directory(path: Path) -> List[solara.Route]:`](/documentation/api/routing/generate_routes_directory) we can request Solara to give us a list of routes by scanning a directory for Python scripts, Notebooks and Markdown files. -This function is being used by Solara if you run solara server with a directory as argument name, as used in [our Multi Page guide](/docs/howto/multipage). More details can be found there. +This function is being used by Solara if you run solara server with a directory as argument name, as used in [our Multi Page guide](/documentation/advanced/howto/multipage). More details can be found there. ### Based on a Python package -Similar to the previous section [`generate_routes(module: ModuleType) -> List[solara.Route]:`](/api/generate_routes) will return a list of routes by scanning a Python package or module for `Page` components, or `app` elements. Again, more information can be found at [our Multi Page guide](/docs/howto/multipage). +Similar to the previous section [`generate_routes(module: ModuleType) -> List[solara.Route]:`](/documentation/api/routing/generate_routes) will return a list of routes by scanning a Python package or module for `Page` components, or `app` elements. Again, more information can be found at [our Multi Page guide](/documentation/advanced/howto/multipage). ## Manually defining routes @@ -59,7 +59,7 @@ routes = [ ### Defining route components -If you do define a `Page` component, you are fully responsible for how routing is done, but we recommend using [use_route](/api/use_route). +If you do define a `Page` component, you are fully responsible for how routing is done, but we recommend using [use_route](/documentation/api/routing/use_route). An example route definition could be something like this: @@ -180,9 +180,9 @@ routes = [ ] ``` -In the case where you did not specify a `Page` component, label is used for the [Title](/api/title) component. +In the case where you did not specify a `Page` component, label is used for the [Title](/documentation/components/page/title) component. -If you need to store more data in the route, you are free to put whatever you want in the `data` attribute, see also [Route](/api/route). +If you need to store more data in the route, you are free to put whatever you want in the `data` attribute, see also [Route](/documentation/api/routing/route). @@ -194,14 +194,14 @@ Note that all routes are relative, since a component does not know if it is embe Therefore you should never use the `route.path` for navigation since the route object has no knowledge of the full url (e.g. `/docs/basics/ipywigets`) but only knows its small piece of the pathname (e.g. `ipywidgets`) -Using [`resolve_path`](/api/resolve_path) we can request the full url for navigation. +Using [`resolve_path`](/documentation/api/routing/resolve_path) we can request the full url for navigation. ```python def resolve_path(path_or_route: Union[str, solara.Route], level=0) -> str: ... ``` -We can pass this full URL to the [`solara.Link`](/api/link) component, e.g. like: +We can pass this full URL to the [`solara.Link`](/documentation/components/advanced/link) component, e.g. like: ```python @solara.component @@ -217,7 +217,7 @@ def LinkToIpywidgets(): ## Fully manual routing -If you want to do routing fully manually, you can use the [`solara.use_router`](/api/use_router) hook, and use the `.path` attribute. +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. ```python import solara diff --git a/solara/website/pages/docs/content/20-understanding/50-solara-server.md b/solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md similarity index 97% rename from solara/website/pages/docs/content/20-understanding/50-solara-server.md rename to solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md index e7835c6a3..2ee418db9 100644 --- a/solara/website/pages/docs/content/20-understanding/50-solara-server.md +++ b/solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md @@ -67,7 +67,7 @@ The JSON format may be subject to change. By default, solara runs in development mode. This means, it will: - * Automatically [reload your project files](docs/reference/reloading) by watching files on the filesystemn + * Automatically [reload your project files](/documentation/getting_started/reference/reloading) by watching files on the filesystemn * Load debug version of the CSS files and JavaScript files for improved error messages (which leads to larger asset files). To disabled all of these option, pass the `--production` flag, or set the environment variable `SOLARA_MODE=production`. diff --git a/solara/website/pages/docs/content/20-understanding/60-voila.md b/solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md similarity index 100% rename from solara/website/pages/docs/content/20-understanding/60-voila.md rename to solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md diff --git a/solara/website/pages/docs/content/50-enterprise/00-overview.md b/solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md similarity index 100% rename from solara/website/pages/docs/content/50-enterprise/00-overview.md rename to solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md diff --git a/solara/website/pages/docs/content/50-enterprise/10-oauth.md b/solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md similarity index 95% rename from solara/website/pages/docs/content/50-enterprise/10-oauth.md rename to solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md index eec9ada17..e730a6294 100644 --- a/solara/website/pages/docs/content/50-enterprise/10-oauth.md +++ b/solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md @@ -8,7 +8,7 @@ You have probably used OAuth without realizing it when signing into various onli ## Installing -To install Solara with OAuth support, make sure you have [Solara Enterprise](/docs/enterprise) install by run the following command: +To install Solara with OAuth support, make sure you have [Solara Enterprise](/documentation/advanced/enterprise) install by run the following command: ```bash $ pip install solara solara-enterprise[auth] @@ -152,8 +152,8 @@ ZgrzSLUyft-JvnNMNJ2LgbCFVqcxPOatANAQhMD5EYU Solara provides two convenient components for creating a user interface for login and logout: - 1. [Avatar](/api/avatar): This component shows the user's avatar. - 2. [AvatarMenu](/api/avatar_menu): This component shows a menu with the user's avatar and a logout button. + 1. [Avatar](/documentation/components/enterprise/avatar): This component shows the user's avatar. + 2. [AvatarMenu](/documentation/components/enterprise/avatar_menu): This component shows a menu with the user's avatar and a logout button. ## Python version support diff --git a/solara/website/pages/docs/content/__init__.py b/solara/website/pages/documentation/advanced/content/40-development/00-overview.md similarity index 100% rename from solara/website/pages/docs/content/__init__.py rename to solara/website/pages/documentation/advanced/content/40-development/00-overview.md diff --git a/solara/website/pages/docs/content/10-howto/01-contribute.md b/solara/website/pages/documentation/advanced/content/40-development/01-contribute.md similarity index 85% rename from solara/website/pages/docs/content/10-howto/01-contribute.md rename to solara/website/pages/documentation/advanced/content/40-development/01-contribute.md index 01f9fe2a0..5672321b2 100644 --- a/solara/website/pages/docs/content/10-howto/01-contribute.md +++ b/solara/website/pages/documentation/advanced/content/40-development/01-contribute.md @@ -7,8 +7,8 @@ You do not need to be a developer to contribute to Solara. We welcome all contri We use [GitHub to manage issues](https://github.com/widgetti/solara/issues/new) and you should not hesitate to report any bug you find. Please include as much information as possible for us to be able to reproduce the bug. Yes, reporting a bug/issue is a contribution! -It might take a while for us to get back to you. If the bug is urgent, and you are able to provide financial support for its rapid resolution, please [contact us](/docs/contact). -If you can fix the bug yourself, please consider submitting a pull request instead, see [the development guide](/docs/development) for more information. +It might take a while for us to get back to you. If the bug is urgent, and you are able to provide financial support for its rapid resolution, please [contact us](/contact). +If you can fix the bug yourself, please consider submitting a pull request instead, see [the development guide](/documentation/advanced/development/setup) for more information. If you are unable to address the bug yourself and find it challenging to provide financial support, please be assured we are still committed to rectifying bugs and resolving issues. However, please understand that our ability to address these issues may be impacted by our resources at hand, as sustaining this project also entails financial obligations. Your patience and understanding in this matter is highly appreciated 🙇. @@ -16,7 +16,7 @@ If you are unable to address the bug yourself and find it challenging to provide The documentation is mostly written in Markdown, and can be found at [in the main repository](https://github.com/widgetti/solara/tree/master/solara/website/pages). -You can use the GitHub web interface to edit the files, or clone the repository and edit them locally. See [the development guide](/docs/development) for more information. +You can use the GitHub web interface to edit the files, or clone the repository and edit them locally. See [the development guide](/documentation/advanced/development/setup) for more information. If you locally want to render the documentation, run: @@ -26,10 +26,10 @@ $ solara run solara.website.pages ## Examples or showcase -If you have a complete program you want to share, and you think it would be cool to be listed at [our showcase page](/showcase), [please contact us](/docs/contact). +If you have a complete program you want to share, and you think it would be cool to be listed at [our showcase page](/showcase), [please contact us](/contact). If you want to show a particular way of using Solara that you think is very useful -for others, but it is not a complete program, consider adding to [the examples](/docs/examples). See [the development guide](/docs/development) for more information. +for others, but it is not a complete program, consider adding to [the examples](/documentation/examples/). See [the development guide](/documentation/advanced/development/setup) for more information. ## Share your experiences and ideas diff --git a/solara/website/pages/docs/content/90-development/10-setup.md b/solara/website/pages/documentation/advanced/content/40-development/10-setup.md similarity index 88% rename from solara/website/pages/docs/content/90-development/10-setup.md rename to solara/website/pages/documentation/advanced/content/40-development/10-setup.md index b16739ae3..a2442289c 100644 --- a/solara/website/pages/docs/content/90-development/10-setup.md +++ b/solara/website/pages/documentation/advanced/content/40-development/10-setup.md @@ -1,9 +1,9 @@ # Development -See also [the contributing guide](/docs/howto/contribute) for more information on how to contribute to Solara. +See also [the contributing guide](/documentation/advanced/development/contribute) for more information on how to contribute to Solara. ## Development setup -Assuming you have created a virtual environment as described in [the installation guide](/docs/installing), you can install a development install of Solara using: +Assuming you have created a virtual environment as described in [the installation guide](/documentation/getting_started/installing), you can install a development install of Solara using: $ git clone git@github.com:widgetti/solara.git $ cd solara diff --git a/solara/website/pages/documentation/advanced/content/__init__.py b/solara/website/pages/documentation/advanced/content/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/solara/website/pages/documentation/api/__init__.py b/solara/website/pages/documentation/api/__init__.py new file mode 100644 index 000000000..bb76e3b08 --- /dev/null +++ b/solara/website/pages/documentation/api/__init__.py @@ -0,0 +1,19 @@ +""" +# Overview +Click on one of the items on the left. +""" + +import solara +from solara.website.components import CategoryLayout, Gallery + +_title = "API" + + +@solara.component +def Page(route_external=None): + Gallery(route_external) + + +@solara.component +def Layout(children=[]): + CategoryLayout(children=children) diff --git a/solara/website/pages/documentation/api/cross_filter/__init__.py b/solara/website/pages/documentation/api/cross_filter/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/api/cross_filter/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/cross_filter_dataframe.py b/solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py similarity index 100% rename from solara/website/pages/api/cross_filter_dataframe.py rename to solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py diff --git a/solara/website/pages/api/cross_filter_report.py b/solara/website/pages/documentation/api/cross_filter/cross_filter_report.py similarity index 100% rename from solara/website/pages/api/cross_filter_report.py rename to solara/website/pages/documentation/api/cross_filter/cross_filter_report.py diff --git a/solara/website/pages/api/cross_filter_select.py b/solara/website/pages/documentation/api/cross_filter/cross_filter_select.py similarity index 100% rename from solara/website/pages/api/cross_filter_select.py rename to solara/website/pages/documentation/api/cross_filter/cross_filter_select.py diff --git a/solara/website/pages/api/cross_filter_slider.py b/solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py similarity index 100% rename from solara/website/pages/api/cross_filter_slider.py rename to solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py diff --git a/solara/website/pages/documentation/api/hooks/__init__.py b/solara/website/pages/documentation/api/hooks/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/api/hooks/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/use_cross_filter.py b/solara/website/pages/documentation/api/hooks/use_cross_filter.py similarity index 100% rename from solara/website/pages/api/use_cross_filter.py rename to solara/website/pages/documentation/api/hooks/use_cross_filter.py diff --git a/solara/website/pages/api/use_dark_effective.py b/solara/website/pages/documentation/api/hooks/use_dark_effective.py similarity index 100% rename from solara/website/pages/api/use_dark_effective.py rename to solara/website/pages/documentation/api/hooks/use_dark_effective.py diff --git a/solara/website/pages/api/use_effect.md b/solara/website/pages/documentation/api/hooks/use_effect.md similarity index 95% rename from solara/website/pages/api/use_effect.md rename to solara/website/pages/documentation/api/hooks/use_effect.md index 5927b380e..94fec19fb 100644 --- a/solara/website/pages/api/use_effect.md +++ b/solara/website/pages/documentation/api/hooks/use_effect.md @@ -8,7 +8,7 @@ def use_effect( ... ``` -Execute non-declarative code within a callback, for instance to add event handlers. `effect` is executed *after* page render, letting us fetch the actual underlying widget object using `solara.get_widget` on an element. `dependencies` should be a list of variables, which when changed trigger re-execution of `effect`. If left empty, `effect` will never re-execute. +Execute non-declarative code within a callback, for instance to add event handlers. `effect` is executed *after* page render, letting us fetch the actual underlying widget object using `solara.get_widget` on an element. `dependencies` should be a list of variables, which when changed trigger re-execution of `effect`. If left empty, `effect` will never re-execute. `effect` can return a cleanup function, which will be called before re-execution of `effect`, or when the component containing `use_effect` is removed. @@ -34,10 +34,10 @@ def use_event(el: solara.Element, callback: Callable): def Page(): def function(): #Do something... - + input = solara.InputText(): use_event(input, function) ... ``` -See also the [Reacton docs](https://reacton.solara.dev/en/latest/api/#use_effect). \ No newline at end of file +See also the [Reacton docs](https://reacton.solara.dev/en/latest/api/#use_effect). diff --git a/solara/website/pages/api/use_effect.py b/solara/website/pages/documentation/api/hooks/use_effect.py similarity index 74% rename from solara/website/pages/api/use_effect.py rename to solara/website/pages/documentation/api/hooks/use_effect.py index 4b62b52bc..6dbc8b1d3 100644 --- a/solara/website/pages/api/use_effect.py +++ b/solara/website/pages/documentation/api/hooks/use_effect.py @@ -1,5 +1,6 @@ from pathlib import Path -from . import NoPage + +from solara.website.components import NoPage HERE = Path(__file__).parent __doc__ = open(HERE / "use_effect.md").read() diff --git a/solara/website/pages/api/use_exception.py b/solara/website/pages/documentation/api/hooks/use_exception.py similarity index 100% rename from solara/website/pages/api/use_exception.py rename to solara/website/pages/documentation/api/hooks/use_exception.py diff --git a/solara/website/pages/api/use_memo.md b/solara/website/pages/documentation/api/hooks/use_memo.md similarity index 77% rename from solara/website/pages/api/use_memo.md rename to solara/website/pages/documentation/api/hooks/use_memo.md index 275efc47d..231a45d7c 100644 --- a/solara/website/pages/api/use_memo.md +++ b/solara/website/pages/documentation/api/hooks/use_memo.md @@ -11,6 +11,6 @@ def use_memo( `use_memo` stores ([memoize](https://en.wikipedia.org/wiki/Memoization)) the function return on first render, and then excludes it from being re-executed, except when one of the `dependencies` changes. `dependencies` can take the value `None`, in which case dependencies are automatically obtained from nonlocal variables. If an empty list is passed as `dependencies` instead, the function is only executed once over the entire lifetime of the component. -Not to be confused with [memorize](https://solara.dev/api/memoize) which can cache multiple return values and which can be used outside of component. +Not to be confused with [memorize](https://solara.dev/documentation/api/utilities/memoize) which can cache multiple return values and which can be used outside of component. -See also the [Reacton docs](https://reacton.solara.dev/en/latest/api/#use_memo). \ No newline at end of file +See also the [Reacton docs](https://reacton.solara.dev/en/latest/api/#use_memo). diff --git a/solara/website/pages/api/use_memo.py b/solara/website/pages/documentation/api/hooks/use_memo.py similarity index 74% rename from solara/website/pages/api/use_memo.py rename to solara/website/pages/documentation/api/hooks/use_memo.py index 6dbd4a5a1..58d2717a4 100644 --- a/solara/website/pages/api/use_memo.py +++ b/solara/website/pages/documentation/api/hooks/use_memo.py @@ -1,5 +1,6 @@ from pathlib import Path -from . import NoPage + +from solara.website.components import NoPage HERE = Path(__file__).parent __doc__ = open(HERE / "use_memo.md").read() diff --git a/solara/website/pages/api/use_previous.py b/solara/website/pages/documentation/api/hooks/use_previous.py similarity index 100% rename from solara/website/pages/api/use_previous.py rename to solara/website/pages/documentation/api/hooks/use_previous.py diff --git a/solara/website/pages/api/use_reactive.py b/solara/website/pages/documentation/api/hooks/use_reactive.py similarity index 79% rename from solara/website/pages/api/use_reactive.py rename to solara/website/pages/documentation/api/hooks/use_reactive.py index fa23d9cd3..d6f5ae46a 100644 --- a/solara/website/pages/api/use_reactive.py +++ b/solara/website/pages/documentation/api/hooks/use_reactive.py @@ -3,10 +3,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "use_reactive" diff --git a/solara/website/pages/api/use_state.py b/solara/website/pages/documentation/api/hooks/use_state.py similarity index 80% rename from solara/website/pages/api/use_state.py rename to solara/website/pages/documentation/api/hooks/use_state.py index eeb4c937e..f51bb8679 100644 --- a/solara/website/pages/api/use_state.py +++ b/solara/website/pages/documentation/api/hooks/use_state.py @@ -3,10 +3,9 @@ """ import solara import solara.autorouting +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "use_state" Page = NoPage __doc__ += apidoc(solara.use_state) # type: ignore diff --git a/solara/website/pages/api/use_state_or_update.py b/solara/website/pages/documentation/api/hooks/use_state_or_update.py similarity index 100% rename from solara/website/pages/api/use_state_or_update.py rename to solara/website/pages/documentation/api/hooks/use_state_or_update.py diff --git a/solara/website/pages/api/use_thread.md b/solara/website/pages/documentation/api/hooks/use_thread.md similarity index 100% rename from solara/website/pages/api/use_thread.md rename to solara/website/pages/documentation/api/hooks/use_thread.md diff --git a/solara/website/pages/api/use_thread.py b/solara/website/pages/documentation/api/hooks/use_thread.py similarity index 100% rename from solara/website/pages/api/use_thread.py rename to solara/website/pages/documentation/api/hooks/use_thread.py diff --git a/solara/website/pages/api/use_trait_observe.py b/solara/website/pages/documentation/api/hooks/use_trait_observe.py similarity index 100% rename from solara/website/pages/api/use_trait_observe.py rename to solara/website/pages/documentation/api/hooks/use_trait_observe.py diff --git a/solara/website/pages/documentation/api/routing/__init__.py b/solara/website/pages/documentation/api/routing/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/api/routing/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/generate_routes.py b/solara/website/pages/documentation/api/routing/generate_routes.py similarity index 82% rename from solara/website/pages/api/generate_routes.py rename to solara/website/pages/documentation/api/routing/generate_routes.py index a6adb9804..123d92c59 100644 --- a/solara/website/pages/api/generate_routes.py +++ b/solara/website/pages/documentation/api/routing/generate_routes.py @@ -3,10 +3,9 @@ """ import solara import solara.autorouting +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "generate_routes" Page = NoPage __doc__ += apidoc(solara.autorouting.generate_routes) # type: ignore diff --git a/solara/website/pages/api/generate_routes_directory.py b/solara/website/pages/documentation/api/routing/generate_routes_directory.py similarity index 84% rename from solara/website/pages/api/generate_routes_directory.py rename to solara/website/pages/documentation/api/routing/generate_routes_directory.py index 2e2472c1a..d0ca88750 100644 --- a/solara/website/pages/api/generate_routes_directory.py +++ b/solara/website/pages/documentation/api/routing/generate_routes_directory.py @@ -3,10 +3,9 @@ """ import solara import solara.autorouting +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "generate_routes_directory" Page = NoPage __doc__ += apidoc(solara.autorouting.generate_routes_directory) # type: ignore diff --git a/solara/website/pages/api/resolve_path.py b/solara/website/pages/documentation/api/routing/resolve_path.py similarity index 100% rename from solara/website/pages/api/resolve_path.py rename to solara/website/pages/documentation/api/routing/resolve_path.py diff --git a/solara/website/pages/api/route.py b/solara/website/pages/documentation/api/routing/route.py similarity index 100% rename from solara/website/pages/api/route.py rename to solara/website/pages/documentation/api/routing/route.py diff --git a/solara/website/pages/api/use_route.py b/solara/website/pages/documentation/api/routing/use_route.py similarity index 92% rename from solara/website/pages/api/use_route.py rename to solara/website/pages/documentation/api/routing/use_route.py index e602190a2..d705be116 100644 --- a/solara/website/pages/api/use_route.py +++ b/solara/website/pages/documentation/api/routing/use_route.py @@ -29,9 +29,9 @@ def Fruit(): with solara.Link(solara.resolve_path(route_fruit)): solara.Button(route_fruit.path) - with solara.Link("/api/use_route/fruit/nofruit", nofollow=True): + with solara.Link("/documentation/api/routing/use_route/fruit/nofruit", nofollow=True): solara.Button("Wrong fruit") - with solara.Link("/api/use_route/not-routed", nofollow=True): + with solara.Link("/documentation/api/routing/use_route/not-routed", nofollow=True): solara.Button("Wrong url") solara.Success(f"You chose {route.path}") return main diff --git a/solara/website/pages/api/use_router.py b/solara/website/pages/documentation/api/routing/use_router.py similarity index 78% rename from solara/website/pages/api/use_router.py rename to solara/website/pages/documentation/api/routing/use_router.py index 170fc86c2..c4437f218 100644 --- a/solara/website/pages/api/use_router.py +++ b/solara/website/pages/documentation/api/routing/use_router.py @@ -3,10 +3,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "use_router" diff --git a/solara/website/pages/documentation/api/utilities/__init__.py b/solara/website/pages/documentation/api/utilities/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/api/utilities/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/component_vue.py b/solara/website/pages/documentation/api/utilities/component_vue.py similarity index 81% rename from solara/website/pages/api/component_vue.py rename to solara/website/pages/documentation/api/utilities/component_vue.py index a6436eaaa..96c189540 100644 --- a/solara/website/pages/api/component_vue.py +++ b/solara/website/pages/documentation/api/utilities/component_vue.py @@ -3,10 +3,9 @@ """ import solara import solara.autorouting +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "component_vue" Page = NoPage __doc__ += apidoc(solara.component_vue) # type: ignore diff --git a/solara/website/pages/api/computed.py b/solara/website/pages/documentation/api/utilities/computed.py similarity index 78% rename from solara/website/pages/api/computed.py rename to solara/website/pages/documentation/api/utilities/computed.py index cb4e4f1fb..868ea3a36 100644 --- a/solara/website/pages/api/computed.py +++ b/solara/website/pages/documentation/api/utilities/computed.py @@ -2,11 +2,11 @@ # computed """ + import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "computed" diff --git a/solara/website/pages/api/display.py b/solara/website/pages/documentation/api/utilities/display.py similarity index 78% rename from solara/website/pages/api/display.py rename to solara/website/pages/documentation/api/utilities/display.py index c42f4e0fd..af0ee4a27 100644 --- a/solara/website/pages/api/display.py +++ b/solara/website/pages/documentation/api/utilities/display.py @@ -3,10 +3,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "display" diff --git a/solara/website/pages/api/get_kernel_id.py b/solara/website/pages/documentation/api/utilities/get_kernel_id.py similarity index 79% rename from solara/website/pages/api/get_kernel_id.py rename to solara/website/pages/documentation/api/utilities/get_kernel_id.py index ca4394fa8..6ae57fbf4 100644 --- a/solara/website/pages/api/get_kernel_id.py +++ b/solara/website/pages/documentation/api/utilities/get_kernel_id.py @@ -2,11 +2,11 @@ # get_kernel_id """ + import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "get_kernel_id" diff --git a/solara/website/pages/api/get_session_id.py b/solara/website/pages/documentation/api/utilities/get_session_id.py similarity index 80% rename from solara/website/pages/api/get_session_id.py rename to solara/website/pages/documentation/api/utilities/get_session_id.py index eaaf66a51..cf385e167 100644 --- a/solara/website/pages/api/get_session_id.py +++ b/solara/website/pages/documentation/api/utilities/get_session_id.py @@ -2,11 +2,11 @@ # get_session_id """ + import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "get_session_id" diff --git a/solara/website/pages/api/memoize.py b/solara/website/pages/documentation/api/utilities/memoize.py similarity index 100% rename from solara/website/pages/api/memoize.py rename to solara/website/pages/documentation/api/utilities/memoize.py diff --git a/solara/website/pages/api/on_kernel_start.py b/solara/website/pages/documentation/api/utilities/on_kernel_start.py similarity index 94% rename from solara/website/pages/api/on_kernel_start.py rename to solara/website/pages/documentation/api/utilities/on_kernel_start.py index e3347337d..e36b1dd68 100644 --- a/solara/website/pages/api/on_kernel_start.py +++ b/solara/website/pages/documentation/api/utilities/on_kernel_start.py @@ -15,7 +15,7 @@ def on_kernel_start(f: Callable[[], Optional[Callable[[], None]]]): (e.g. the cleanup function of the last call to `on_kernel_start` will be called first on kernel shutdown) """ -from . import NoPage +from solara.website.components import NoPage title = "on_kernel_start" Page = NoPage diff --git a/solara/website/pages/api/reactive.py b/solara/website/pages/documentation/api/utilities/reactive.py similarity index 78% rename from solara/website/pages/api/reactive.py rename to solara/website/pages/documentation/api/utilities/reactive.py index 17e588883..76ab9fc9c 100644 --- a/solara/website/pages/api/reactive.py +++ b/solara/website/pages/documentation/api/utilities/reactive.py @@ -3,10 +3,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "reactive" diff --git a/solara/website/pages/api/widget.py b/solara/website/pages/documentation/api/utilities/widget.py similarity index 94% rename from solara/website/pages/api/widget.py rename to solara/website/pages/documentation/api/utilities/widget.py index 55e8b619d..25ca346fa 100644 --- a/solara/website/pages/api/widget.py +++ b/solara/website/pages/documentation/api/utilities/widget.py @@ -21,7 +21,7 @@ def widget(self, **kwargs): ``` This is very useful if you are migrating your application from a classic -ipywidget to solara. See [also the ipywidgets tutorial](/docs/tutorial/ipywidgets). +ipywidget to solara. See [also the ipywidgets tutorial](/documentation/getting_started/tutorials/ipywidgets). The `ipywidgets.ValueWidget` is used to enable the use of the widget in interact, or interactive. The `ipywidgets.VBox` is used to enable @@ -98,7 +98,7 @@ def pick(): """ -from . import NoPage +from solara.website.components import NoPage Page = NoPage title = "widget" diff --git a/solara/website/pages/documentation/components/__init__.py b/solara/website/pages/documentation/components/__init__.py new file mode 100644 index 000000000..4672e8e0a --- /dev/null +++ b/solara/website/pages/documentation/components/__init__.py @@ -0,0 +1,12 @@ +import solara +from solara.website.components import CategoryLayout, Gallery + + +@solara.component +def Page(route_external=None): + Gallery(route_external) + + +@solara.component +def Layout(children=[]): + CategoryLayout(children=children) diff --git a/solara/website/pages/documentation/components/advanced/__init__.py b/solara/website/pages/documentation/components/advanced/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/advanced/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/link.py b/solara/website/pages/documentation/components/advanced/link.py similarity index 100% rename from solara/website/pages/api/link.py rename to solara/website/pages/documentation/components/advanced/link.py diff --git a/solara/website/pages/api/meta.py b/solara/website/pages/documentation/components/advanced/meta.py similarity index 100% rename from solara/website/pages/api/meta.py rename to solara/website/pages/documentation/components/advanced/meta.py diff --git a/solara/website/pages/api/style.py b/solara/website/pages/documentation/components/advanced/style.py similarity index 100% rename from solara/website/pages/api/style.py rename to solara/website/pages/documentation/components/advanced/style.py diff --git a/solara/website/pages/api/common.py b/solara/website/pages/documentation/components/common.py similarity index 100% rename from solara/website/pages/api/common.py rename to solara/website/pages/documentation/components/common.py diff --git a/solara/website/pages/documentation/components/data/__init__.py b/solara/website/pages/documentation/components/data/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/data/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/dataframe.py b/solara/website/pages/documentation/components/data/dataframe.py similarity index 100% rename from solara/website/pages/api/dataframe.py rename to solara/website/pages/documentation/components/data/dataframe.py diff --git a/solara/website/pages/api/pivot_table.py b/solara/website/pages/documentation/components/data/pivot_table.py similarity index 100% rename from solara/website/pages/api/pivot_table.py rename to solara/website/pages/documentation/components/data/pivot_table.py diff --git a/solara/website/pages/documentation/components/enterprise/__init__.py b/solara/website/pages/documentation/components/enterprise/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/enterprise/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/avatar.py b/solara/website/pages/documentation/components/enterprise/avatar.py similarity index 86% rename from solara/website/pages/api/avatar.py rename to solara/website/pages/documentation/components/enterprise/avatar.py index 4e54ee669..0e1dc63b8 100644 --- a/solara/website/pages/api/avatar.py +++ b/solara/website/pages/documentation/components/enterprise/avatar.py @@ -6,10 +6,9 @@ from solara_enterprise import auth except ImportError: auth = None +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "Avatar" Page = NoPage diff --git a/solara/website/pages/api/avatar_menu.py b/solara/website/pages/documentation/components/enterprise/avatar_menu.py similarity index 87% rename from solara/website/pages/api/avatar_menu.py rename to solara/website/pages/documentation/components/enterprise/avatar_menu.py index 8e4345b82..07faa9763 100644 --- a/solara/website/pages/api/avatar_menu.py +++ b/solara/website/pages/documentation/components/enterprise/avatar_menu.py @@ -6,10 +6,9 @@ from solara_enterprise import auth except ImportError: auth = None +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "AvatarMenu" Page = NoPage diff --git a/solara/website/pages/documentation/components/input/__init__.py b/solara/website/pages/documentation/components/input/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/input/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/button.py b/solara/website/pages/documentation/components/input/button.py similarity index 100% rename from solara/website/pages/api/button.py rename to solara/website/pages/documentation/components/input/button.py diff --git a/solara/website/pages/api/checkbox.py b/solara/website/pages/documentation/components/input/checkbox.py similarity index 76% rename from solara/website/pages/api/checkbox.py rename to solara/website/pages/documentation/components/input/checkbox.py index 5ebb93703..687527373 100644 --- a/solara/website/pages/api/checkbox.py +++ b/solara/website/pages/documentation/components/input/checkbox.py @@ -3,10 +3,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage diff --git a/solara/website/pages/api/file_browser.py b/solara/website/pages/documentation/components/input/file_browser.py similarity index 100% rename from solara/website/pages/api/file_browser.py rename to solara/website/pages/documentation/components/input/file_browser.py diff --git a/solara/website/pages/api/file_drop.py b/solara/website/pages/documentation/components/input/file_drop.py similarity index 100% rename from solara/website/pages/api/file_drop.py rename to solara/website/pages/documentation/components/input/file_drop.py diff --git a/solara/website/pages/api/input.py b/solara/website/pages/documentation/components/input/input.py similarity index 89% rename from solara/website/pages/api/input.py rename to solara/website/pages/documentation/components/input/input.py index 03a466604..4de1a2ce5 100644 --- a/solara/website/pages/api/input.py +++ b/solara/website/pages/documentation/components/input/input.py @@ -5,10 +5,9 @@ # InputText """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage diff --git a/solara/website/pages/api/select.py b/solara/website/pages/documentation/components/input/select.py similarity index 89% rename from solara/website/pages/api/select.py rename to solara/website/pages/documentation/components/input/select.py index adf08e838..009eeafd5 100644 --- a/solara/website/pages/api/select.py +++ b/solara/website/pages/documentation/components/input/select.py @@ -9,10 +9,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage diff --git a/solara/website/pages/api/slider.py b/solara/website/pages/documentation/components/input/slider.py similarity index 93% rename from solara/website/pages/api/slider.py rename to solara/website/pages/documentation/components/input/slider.py index 572e06a5b..f6581bd72 100644 --- a/solara/website/pages/api/slider.py +++ b/solara/website/pages/documentation/components/input/slider.py @@ -6,10 +6,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage __doc__ += "# SliderInt" diff --git a/solara/website/pages/api/switch.py b/solara/website/pages/documentation/components/input/switch.py similarity index 75% rename from solara/website/pages/api/switch.py rename to solara/website/pages/documentation/components/input/switch.py index f4757d713..93e239ca9 100644 --- a/solara/website/pages/api/switch.py +++ b/solara/website/pages/documentation/components/input/switch.py @@ -3,10 +3,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage diff --git a/solara/website/pages/api/togglebuttons.py b/solara/website/pages/documentation/components/input/togglebuttons.py similarity index 89% rename from solara/website/pages/api/togglebuttons.py rename to solara/website/pages/documentation/components/input/togglebuttons.py index 7a933c131..caa725b88 100644 --- a/solara/website/pages/api/togglebuttons.py +++ b/solara/website/pages/documentation/components/input/togglebuttons.py @@ -6,10 +6,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "ToggleButtons" Page = NoPage diff --git a/solara/website/pages/documentation/components/lab/__init__.py b/solara/website/pages/documentation/components/lab/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/lab/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/chat.py b/solara/website/pages/documentation/components/lab/chat.py similarity index 95% rename from solara/website/pages/api/chat.py rename to solara/website/pages/documentation/components/lab/chat.py index dd557fcb6..d74fab92e 100644 --- a/solara/website/pages/api/chat.py +++ b/solara/website/pages/documentation/components/lab/chat.py @@ -5,15 +5,14 @@ Although they can be used together to create a pre-built chat interface, inserting custom components is also possible. For an example of how to use a custom message component, see the bottom of the page. -Also check out the [Chatbot](/examples/ai/chatbot) example. +Also check out the [Chatbot](/documentation/examples/ai/chatbot) example. # ChatBox """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "Chat Components" diff --git a/solara/website/pages/api/confirmation_dialog.py b/solara/website/pages/documentation/components/lab/confirmation_dialog.py similarity index 100% rename from solara/website/pages/api/confirmation_dialog.py rename to solara/website/pages/documentation/components/lab/confirmation_dialog.py diff --git a/solara/website/pages/api/cookies_headers.py b/solara/website/pages/documentation/components/lab/cookies_headers.py similarity index 96% rename from solara/website/pages/api/cookies_headers.py rename to solara/website/pages/documentation/components/lab/cookies_headers.py index 030413100..f80a54140 100644 --- a/solara/website/pages/api/cookies_headers.py +++ b/solara/website/pages/documentation/components/lab/cookies_headers.py @@ -42,7 +42,7 @@ def Page(): """ -from . import NoPage +from solara.website.components import NoPage title = "Cookies and Headers" Page = NoPage diff --git a/solara/website/pages/api/input_date.py b/solara/website/pages/documentation/components/lab/input_date.py similarity index 89% rename from solara/website/pages/api/input_date.py rename to solara/website/pages/documentation/components/lab/input_date.py index 818337cca..c01a922e4 100644 --- a/solara/website/pages/api/input_date.py +++ b/solara/website/pages/documentation/components/lab/input_date.py @@ -6,10 +6,9 @@ # InputDate """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "InputDate" diff --git a/solara/website/pages/api/menu.py b/solara/website/pages/documentation/components/lab/menu.py similarity index 91% rename from solara/website/pages/api/menu.py rename to solara/website/pages/documentation/components/lab/menu.py index 7d53443ed..1023a5658 100644 --- a/solara/website/pages/api/menu.py +++ b/solara/website/pages/documentation/components/lab/menu.py @@ -6,10 +6,9 @@ # Menu """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "Menus" diff --git a/solara/website/pages/api/tab.py b/solara/website/pages/documentation/components/lab/tab.py similarity index 100% rename from solara/website/pages/api/tab.py rename to solara/website/pages/documentation/components/lab/tab.py diff --git a/solara/website/pages/api/tabs.py b/solara/website/pages/documentation/components/lab/tabs.py similarity index 100% rename from solara/website/pages/api/tabs.py rename to solara/website/pages/documentation/components/lab/tabs.py diff --git a/solara/website/pages/api/task.py b/solara/website/pages/documentation/components/lab/task.py similarity index 81% rename from solara/website/pages/api/task.py rename to solara/website/pages/documentation/components/lab/task.py index de66d06d3..5b24c1d67 100644 --- a/solara/website/pages/api/task.py +++ b/solara/website/pages/documentation/components/lab/task.py @@ -4,10 +4,9 @@ import solara import solara.autorouting import solara.lab +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "Task" Page = NoPage __doc__ += apidoc(solara.lab.task) # type: ignore diff --git a/solara/website/pages/api/theming.py b/solara/website/pages/documentation/components/lab/theming.py similarity index 98% rename from solara/website/pages/api/theming.py rename to solara/website/pages/documentation/components/lab/theming.py index ab669adbd..25cafc602 100644 --- a/solara/website/pages/api/theming.py +++ b/solara/website/pages/documentation/components/lab/theming.py @@ -64,10 +64,9 @@ def Page(): """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "Themes" Page = NoPage __doc__ += apidoc(solara.lab.ThemeToggle) # type: ignore diff --git a/solara/website/pages/api/use_task.py b/solara/website/pages/documentation/components/lab/use_task.py similarity index 82% rename from solara/website/pages/api/use_task.py rename to solara/website/pages/documentation/components/lab/use_task.py index 68b6c4c4f..04a96fc28 100644 --- a/solara/website/pages/api/use_task.py +++ b/solara/website/pages/documentation/components/lab/use_task.py @@ -4,10 +4,9 @@ import solara import solara.autorouting import solara.lab +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "use_task" Page = NoPage __doc__ += apidoc(solara.lab.use_task) # type: ignore diff --git a/solara/website/pages/documentation/components/layout/__init__.py b/solara/website/pages/documentation/components/layout/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/layout/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/app_bar.py b/solara/website/pages/documentation/components/layout/app_bar.py similarity index 79% rename from solara/website/pages/api/app_bar.py rename to solara/website/pages/documentation/components/layout/app_bar.py index 2f4b27637..23b58de6c 100644 --- a/solara/website/pages/api/app_bar.py +++ b/solara/website/pages/documentation/components/layout/app_bar.py @@ -4,10 +4,9 @@ """ import solara import solara.lab +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "AppBar" Page = NoPage diff --git a/solara/website/pages/api/app_bar_title.py b/solara/website/pages/documentation/components/layout/app_bar_title.py similarity index 80% rename from solara/website/pages/api/app_bar_title.py rename to solara/website/pages/documentation/components/layout/app_bar_title.py index 8df82173c..04fcb4073 100644 --- a/solara/website/pages/api/app_bar_title.py +++ b/solara/website/pages/documentation/components/layout/app_bar_title.py @@ -4,10 +4,9 @@ """ import solara import solara.lab +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "AppBarTitle" Page = NoPage diff --git a/solara/website/pages/api/app_layout.py b/solara/website/pages/documentation/components/layout/app_layout.py similarity index 100% rename from solara/website/pages/api/app_layout.py rename to solara/website/pages/documentation/components/layout/app_layout.py diff --git a/solara/website/pages/api/card.py b/solara/website/pages/documentation/components/layout/card.py similarity index 78% rename from solara/website/pages/api/card.py rename to solara/website/pages/documentation/components/layout/card.py index f52407d87..d33250b24 100644 --- a/solara/website/pages/api/card.py +++ b/solara/website/pages/documentation/components/layout/card.py @@ -4,10 +4,9 @@ """ import solara import solara.lab +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "Card" Page = NoPage diff --git a/solara/website/pages/api/card_actions.py b/solara/website/pages/documentation/components/layout/card_actions.py similarity index 80% rename from solara/website/pages/api/card_actions.py rename to solara/website/pages/documentation/components/layout/card_actions.py index 3c032ace4..f54ffb269 100644 --- a/solara/website/pages/api/card_actions.py +++ b/solara/website/pages/documentation/components/layout/card_actions.py @@ -4,10 +4,9 @@ """ import solara import solara.lab +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - title = "CardActions" Page = NoPage diff --git a/solara/website/pages/api/column.py b/solara/website/pages/documentation/components/layout/column.py similarity index 100% rename from solara/website/pages/api/column.py rename to solara/website/pages/documentation/components/layout/column.py diff --git a/solara/website/pages/api/columns.py b/solara/website/pages/documentation/components/layout/columns.py similarity index 100% rename from solara/website/pages/api/columns.py rename to solara/website/pages/documentation/components/layout/columns.py diff --git a/solara/website/pages/api/columns_responsive.py b/solara/website/pages/documentation/components/layout/columns_responsive.py similarity index 100% rename from solara/website/pages/api/columns_responsive.py rename to solara/website/pages/documentation/components/layout/columns_responsive.py diff --git a/solara/website/pages/api/griddraggable.py b/solara/website/pages/documentation/components/layout/griddraggable.py similarity index 98% rename from solara/website/pages/api/griddraggable.py rename to solara/website/pages/documentation/components/layout/griddraggable.py index ddb125ffc..5dfa5460c 100644 --- a/solara/website/pages/api/griddraggable.py +++ b/solara/website/pages/documentation/components/layout/griddraggable.py @@ -8,7 +8,7 @@ import solara -from .common import ColorCard +from ..common import ColorCard title = "GridDraggable" diff --git a/solara/website/pages/api/gridfixed.py b/solara/website/pages/documentation/components/layout/gridfixed.py similarity index 92% rename from solara/website/pages/api/gridfixed.py rename to solara/website/pages/documentation/components/layout/gridfixed.py index 5be6288eb..a6ce63ca9 100644 --- a/solara/website/pages/api/gridfixed.py +++ b/solara/website/pages/documentation/components/layout/gridfixed.py @@ -6,7 +6,7 @@ import solara -from .common import ColorCard +from ..common import ColorCard title = "GridFixed" diff --git a/solara/website/pages/api/hbox.py b/solara/website/pages/documentation/components/layout/hbox.py similarity index 91% rename from solara/website/pages/api/hbox.py rename to solara/website/pages/documentation/components/layout/hbox.py index d5f502abf..2e5331ada 100644 --- a/solara/website/pages/api/hbox.py +++ b/solara/website/pages/documentation/components/layout/hbox.py @@ -4,7 +4,7 @@ """ import solara -from .common import ColorCard +from ..common import ColorCard @solara.component diff --git a/solara/website/pages/api/row.py b/solara/website/pages/documentation/components/layout/row.py similarity index 100% rename from solara/website/pages/api/row.py rename to solara/website/pages/documentation/components/layout/row.py diff --git a/solara/website/pages/api/sidebar.py b/solara/website/pages/documentation/components/layout/sidebar.py similarity index 100% rename from solara/website/pages/api/sidebar.py rename to solara/website/pages/documentation/components/layout/sidebar.py diff --git a/solara/website/pages/api/vbox.py b/solara/website/pages/documentation/components/layout/vbox.py similarity index 91% rename from solara/website/pages/api/vbox.py rename to solara/website/pages/documentation/components/layout/vbox.py index 5d2005b10..4c9e70463 100644 --- a/solara/website/pages/api/vbox.py +++ b/solara/website/pages/documentation/components/layout/vbox.py @@ -6,7 +6,7 @@ import solara -from .common import ColorCard +from ..common import ColorCard @solara.component diff --git a/solara/website/pages/documentation/components/output/__init__.py b/solara/website/pages/documentation/components/output/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/output/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/file_download.py b/solara/website/pages/documentation/components/output/file_download.py similarity index 79% rename from solara/website/pages/api/file_download.py rename to solara/website/pages/documentation/components/output/file_download.py index 63be8fe23..bd286dc60 100644 --- a/solara/website/pages/api/file_download.py +++ b/solara/website/pages/documentation/components/output/file_download.py @@ -2,10 +2,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage title = "FileDownload" diff --git a/solara/website/pages/api/html.py b/solara/website/pages/documentation/components/output/html.py similarity index 100% rename from solara/website/pages/api/html.py rename to solara/website/pages/documentation/components/output/html.py diff --git a/solara/website/pages/api/image.py b/solara/website/pages/documentation/components/output/image.py similarity index 77% rename from solara/website/pages/api/image.py rename to solara/website/pages/documentation/components/output/image.py index 931d7f333..719417557 100644 --- a/solara/website/pages/api/image.py +++ b/solara/website/pages/documentation/components/output/image.py @@ -2,10 +2,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage title = "Image" diff --git a/solara/website/pages/api/markdown.py b/solara/website/pages/documentation/components/output/markdown.py similarity index 100% rename from solara/website/pages/api/markdown.py rename to solara/website/pages/documentation/components/output/markdown.py diff --git a/solara/website/pages/api/markdown_editor.py b/solara/website/pages/documentation/components/output/markdown_editor.py similarity index 100% rename from solara/website/pages/api/markdown_editor.py rename to solara/website/pages/documentation/components/output/markdown_editor.py diff --git a/solara/website/pages/api/sql_code.py b/solara/website/pages/documentation/components/output/sql_code.py similarity index 100% rename from solara/website/pages/api/sql_code.py rename to solara/website/pages/documentation/components/output/sql_code.py diff --git a/solara/website/pages/api/tooltip.py b/solara/website/pages/documentation/components/output/tooltip.py similarity index 77% rename from solara/website/pages/api/tooltip.py rename to solara/website/pages/documentation/components/output/tooltip.py index 5a8fa0626..d5b3aae6b 100644 --- a/solara/website/pages/api/tooltip.py +++ b/solara/website/pages/documentation/components/output/tooltip.py @@ -2,10 +2,9 @@ """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage title = "Tooltip" diff --git a/solara/website/pages/documentation/components/page/__init__.py b/solara/website/pages/documentation/components/page/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/page/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/head.py b/solara/website/pages/documentation/components/page/head.py similarity index 100% rename from solara/website/pages/api/head.py rename to solara/website/pages/documentation/components/page/head.py diff --git a/solara/website/pages/api/title.py b/solara/website/pages/documentation/components/page/title.py similarity index 100% rename from solara/website/pages/api/title.py rename to solara/website/pages/documentation/components/page/title.py diff --git a/solara/website/pages/documentation/components/status/__init__.py b/solara/website/pages/documentation/components/status/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/status/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/error.py b/solara/website/pages/documentation/components/status/error.py similarity index 86% rename from solara/website/pages/api/error.py rename to solara/website/pages/documentation/components/status/error.py index f41b34e80..69f90543c 100644 --- a/solara/website/pages/api/error.py +++ b/solara/website/pages/documentation/components/status/error.py @@ -2,9 +2,9 @@ Solara has 4 types of alerts: - * [Success](/api/success) - * [Info](/api/info) - * [Warning](/api/warning) + * [Success](/documentation/components/status/success) + * [Info](/documentation/components/status/info) + * [Warning](/documentation/components/status/warning) * Error (this page) diff --git a/solara/website/pages/api/info.py b/solara/website/pages/documentation/components/status/info.py similarity index 86% rename from solara/website/pages/api/info.py rename to solara/website/pages/documentation/components/status/info.py index 6b5db6caf..cac0cf272 100644 --- a/solara/website/pages/api/info.py +++ b/solara/website/pages/documentation/components/status/info.py @@ -2,10 +2,10 @@ Solara has 4 types of alerts: - * [Success](/api/success) + * [Success](/documentation/components/status/success) * Info (this page) - * [Warning](/api/warning) - * [Error](/api/error) + * [Warning](/documentation/components/status/warning) + * [Error](/documentation/components/status/error) diff --git a/solara/website/pages/api/progress.py b/solara/website/pages/documentation/components/status/progress.py similarity index 77% rename from solara/website/pages/api/progress.py rename to solara/website/pages/documentation/components/status/progress.py index d6ff52882..82def140a 100644 --- a/solara/website/pages/api/progress.py +++ b/solara/website/pages/documentation/components/status/progress.py @@ -1,10 +1,9 @@ """# ProgressLinear """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage diff --git a/solara/website/pages/api/spinner.py b/solara/website/pages/documentation/components/status/spinner.py similarity index 77% rename from solara/website/pages/api/spinner.py rename to solara/website/pages/documentation/components/status/spinner.py index 8acd17477..7600c9b1e 100644 --- a/solara/website/pages/api/spinner.py +++ b/solara/website/pages/documentation/components/status/spinner.py @@ -2,10 +2,9 @@ # SpinnerSolara """ import solara +from solara.website.components import NoPage from solara.website.utils import apidoc -from . import NoPage - Page = NoPage __doc__ += apidoc(solara.SpinnerSolara.f) # type: ignore diff --git a/solara/website/pages/api/success.py b/solara/website/pages/documentation/components/status/success.py similarity index 87% rename from solara/website/pages/api/success.py rename to solara/website/pages/documentation/components/status/success.py index a07d8ae9c..6525d84bc 100644 --- a/solara/website/pages/api/success.py +++ b/solara/website/pages/documentation/components/status/success.py @@ -3,9 +3,9 @@ Solara has 4 types of alerts: * Success (this page) - * [Info](/api/info) - * [Warning](/api/warning) - * [Error](/api/error) + * [Info](/documentation/components/status/info) + * [Warning](/documentation/components/status/warning) + * [Error](/documentation/components/status/error) diff --git a/solara/website/pages/api/warning.py b/solara/website/pages/documentation/components/status/warning.py similarity index 89% rename from solara/website/pages/api/warning.py rename to solara/website/pages/documentation/components/status/warning.py index 6a42f0e10..6ecd79467 100644 --- a/solara/website/pages/api/warning.py +++ b/solara/website/pages/documentation/components/status/warning.py @@ -2,10 +2,10 @@ Solara has 4 types of alerts: - * [Success](/api/success) - * [Info](/api/info) + * [Success](/documentation/components/status/success) + * [Info](/documentation/components/status/info) * Warning (this page) - * [Error](/api/error) + * [Error](/documentation/components/status/error) diff --git a/solara/website/pages/documentation/components/viz/__init__.py b/solara/website/pages/documentation/components/viz/__init__.py new file mode 100644 index 000000000..0d2e24972 --- /dev/null +++ b/solara/website/pages/documentation/components/viz/__init__.py @@ -0,0 +1,9 @@ +import solara +from solara.website.components import NoPage, SubCategoryLayout + +Page = NoPage + + +@solara.component +def Layout(children=[]): + SubCategoryLayout(children=children) diff --git a/solara/website/pages/api/altair.py b/solara/website/pages/documentation/components/viz/altair.py similarity index 100% rename from solara/website/pages/api/altair.py rename to solara/website/pages/documentation/components/viz/altair.py diff --git a/solara/website/pages/api/echarts.py b/solara/website/pages/documentation/components/viz/echarts.py similarity index 100% rename from solara/website/pages/api/echarts.py rename to solara/website/pages/documentation/components/viz/echarts.py diff --git a/solara/website/pages/api/matplotlib.py b/solara/website/pages/documentation/components/viz/matplotlib.py similarity index 100% rename from solara/website/pages/api/matplotlib.py rename to solara/website/pages/documentation/components/viz/matplotlib.py diff --git a/solara/website/pages/api/plotly.py b/solara/website/pages/documentation/components/viz/plotly.py similarity index 99% rename from solara/website/pages/api/plotly.py rename to solara/website/pages/documentation/components/viz/plotly.py index 7fb06247c..78ab40bc6 100644 --- a/solara/website/pages/api/plotly.py +++ b/solara/website/pages/documentation/components/viz/plotly.py @@ -10,6 +10,7 @@ """ import plotly.express as px + import solara df = px.data.iris() diff --git a/solara/website/pages/api/plotly_express.py b/solara/website/pages/documentation/components/viz/plotly_express.py similarity index 100% rename from solara/website/pages/api/plotly_express.py rename to solara/website/pages/documentation/components/viz/plotly_express.py diff --git a/solara/website/pages/examples/__init__.py b/solara/website/pages/documentation/examples/__init__.py similarity index 51% rename from solara/website/pages/examples/__init__.py rename to solara/website/pages/documentation/examples/__init__.py index a54dc2015..680fe3941 100644 --- a/solara/website/pages/examples/__init__.py +++ b/solara/website/pages/documentation/examples/__init__.py @@ -1,52 +1,12 @@ -# import inspect -# import urllib.parse - import solara +from solara.website.components import Gallery title = "Examples" @solara.component -def Page(): - # show a gallery of all the examples - router = solara.use_router() - route_current = router.path_routes[-2] - - for route in route_current.children: - if route.children: - solara.Markdown(f"## {route.label}\n" + (route.module.__doc__ or "")) - with solara.ColumnsResponsive(12, 6, 6, 6, 4): - for child in route.children: - path = route.path + "/" + child.path - if child.path in [ - "tokenizer", - "sine", - "authorization", - "layout_demo", - "multipage", - "scatter", - "scrolling", - "tutorial_streamlit", - "login_oauth", - "pokemon_search", - "altair", - "bqplot", - "ipyleaflet", - "calculator", - "countdown_timer", - "todo", - ]: - image = route.path + "/" + child.path + ".png" - image_url = "https://dxhl76zpt6fap.cloudfront.net/public/examples/" + image - else: - image_url = "https://dxhl76zpt6fap.cloudfront.net/public/logo.svg" - - path = getattr(child.module, "redirect", path) - if path: - with solara.Card(child.label, style="height: 100%;"): - with solara.Link(path): - with solara.Column(align="center"): - solara.Image(image_url, width="120px" if image_url.endswith(".svg") else "100%") +def Page(route_external=None): + Gallery(route_external) @solara.component diff --git a/solara/website/pages/examples/ai/__init__.py b/solara/website/pages/documentation/examples/ai/__init__.py similarity index 100% rename from solara/website/pages/examples/ai/__init__.py rename to solara/website/pages/documentation/examples/ai/__init__.py diff --git a/solara/website/pages/examples/ai/chatbot.py b/solara/website/pages/documentation/examples/ai/chatbot.py similarity index 100% rename from solara/website/pages/examples/ai/chatbot.py rename to solara/website/pages/documentation/examples/ai/chatbot.py diff --git a/solara/website/pages/examples/ai/tokenizer.py b/solara/website/pages/documentation/examples/ai/tokenizer.py similarity index 100% rename from solara/website/pages/examples/ai/tokenizer.py rename to solara/website/pages/documentation/examples/ai/tokenizer.py diff --git a/solara/website/pages/examples/basics/__init__.py b/solara/website/pages/documentation/examples/basics/__init__.py similarity index 100% rename from solara/website/pages/examples/basics/__init__.py rename to solara/website/pages/documentation/examples/basics/__init__.py diff --git a/solara/website/pages/examples/basics/sine.py b/solara/website/pages/documentation/examples/basics/sine.py similarity index 100% rename from solara/website/pages/examples/basics/sine.py rename to solara/website/pages/documentation/examples/basics/sine.py diff --git a/solara/website/pages/examples/fullscreen/__init__.py b/solara/website/pages/documentation/examples/fullscreen/__init__.py similarity index 100% rename from solara/website/pages/examples/fullscreen/__init__.py rename to solara/website/pages/documentation/examples/fullscreen/__init__.py diff --git a/solara/website/pages/examples/fullscreen/authorization.py b/solara/website/pages/documentation/examples/fullscreen/authorization.py similarity index 100% rename from solara/website/pages/examples/fullscreen/authorization.py rename to solara/website/pages/documentation/examples/fullscreen/authorization.py diff --git a/solara/website/pages/examples/fullscreen/layout_demo.py b/solara/website/pages/documentation/examples/fullscreen/layout_demo.py similarity index 100% rename from solara/website/pages/examples/fullscreen/layout_demo.py rename to solara/website/pages/documentation/examples/fullscreen/layout_demo.py diff --git a/solara/website/pages/examples/fullscreen/multipage.py b/solara/website/pages/documentation/examples/fullscreen/multipage.py similarity index 100% rename from solara/website/pages/examples/fullscreen/multipage.py rename to solara/website/pages/documentation/examples/fullscreen/multipage.py diff --git a/solara/website/pages/examples/fullscreen/scatter.py b/solara/website/pages/documentation/examples/fullscreen/scatter.py similarity index 100% rename from solara/website/pages/examples/fullscreen/scatter.py rename to solara/website/pages/documentation/examples/fullscreen/scatter.py diff --git a/solara/website/pages/examples/fullscreen/scrolling.py b/solara/website/pages/documentation/examples/fullscreen/scrolling.py similarity index 100% rename from solara/website/pages/examples/fullscreen/scrolling.py rename to solara/website/pages/documentation/examples/fullscreen/scrolling.py diff --git a/solara/website/pages/examples/fullscreen/tutorial_streamlit.py b/solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py similarity index 100% rename from solara/website/pages/examples/fullscreen/tutorial_streamlit.py rename to solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py diff --git a/solara/website/pages/examples/general/__init__.py b/solara/website/pages/documentation/examples/general/__init__.py similarity index 100% rename from solara/website/pages/examples/general/__init__.py rename to solara/website/pages/documentation/examples/general/__init__.py diff --git a/solara/website/pages/examples/general/custom_storage.py b/solara/website/pages/documentation/examples/general/custom_storage.py similarity index 100% rename from solara/website/pages/examples/general/custom_storage.py rename to solara/website/pages/documentation/examples/general/custom_storage.py diff --git a/solara/website/pages/examples/general/deploy_model.py b/solara/website/pages/documentation/examples/general/deploy_model.py similarity index 94% rename from solara/website/pages/examples/general/deploy_model.py rename to solara/website/pages/documentation/examples/general/deploy_model.py index 38e642250..40d11afe4 100644 --- a/solara/website/pages/examples/general/deploy_model.py +++ b/solara/website/pages/documentation/examples/general/deploy_model.py @@ -1,7 +1,8 @@ """# Deploy model demo -This show off a combination of [solara.lab.Menu](/api/menu) and [solara.lab.ConfirmationDialog](/api/confirmation_dialog) -and [solara.use_thread](/api/use_thread) to demonstrate how to tune, fit and deploy a model. +This show off a combination of [solara.lab.Menu](/documentation/components/lab/menu) and + [solara.lab.ConfirmationDialog](/documentation/components/lab/confirmation_dialog) +and [solara.use_thread](/documentation/api/hooks/use_thread) to demonstrate how to tune, fit and deploy a model. The actually deployment is not real, but simulated by a thread that returns a boolean value on success and sleep for a while to similate the deployment taking time. @@ -15,7 +16,6 @@ import numpy as np import pandas as pd import plotly.express as px - import solara import solara.lab diff --git a/solara/website/pages/examples/general/live_update.py b/solara/website/pages/documentation/examples/general/live_update.py similarity index 100% rename from solara/website/pages/examples/general/live_update.py rename to solara/website/pages/documentation/examples/general/live_update.py diff --git a/solara/website/pages/examples/general/login_oauth.py b/solara/website/pages/documentation/examples/general/login_oauth.py similarity index 97% rename from solara/website/pages/examples/general/login_oauth.py rename to solara/website/pages/documentation/examples/general/login_oauth.py index 138c686a0..5cbabd0c4 100644 --- a/solara/website/pages/examples/general/login_oauth.py +++ b/solara/website/pages/documentation/examples/general/login_oauth.py @@ -54,7 +54,7 @@ def Page(): This is the raw user data from the auth provider. - We use the `picture` field to display an avatar in the [AppBar](/api/appbar). + We use the `picture` field to display an avatar in the [AppBar](/documentation/components/layout/app_bar). """ ) sl.Preformatted(pprint.pformat(auth.user.value)) diff --git a/solara/website/pages/examples/general/mycard.vue b/solara/website/pages/documentation/examples/general/mycard.vue similarity index 100% rename from solara/website/pages/examples/general/mycard.vue rename to solara/website/pages/documentation/examples/general/mycard.vue diff --git a/solara/website/pages/examples/general/pokemon_search.py b/solara/website/pages/documentation/examples/general/pokemon_search.py similarity index 100% rename from solara/website/pages/examples/general/pokemon_search.py rename to solara/website/pages/documentation/examples/general/pokemon_search.py diff --git a/solara/website/pages/examples/general/vue_component.py b/solara/website/pages/documentation/examples/general/vue_component.py similarity index 93% rename from solara/website/pages/examples/general/vue_component.py rename to solara/website/pages/documentation/examples/general/vue_component.py index 6aa5cf011..10862caf1 100644 --- a/solara/website/pages/examples/general/vue_component.py +++ b/solara/website/pages/documentation/examples/general/vue_component.py @@ -4,7 +4,7 @@ It can also be beneficial for performance, since instead of creating many widgets from the Python side we only send data to the frontend. If event handling is also done on the frontend, this reduces latency and makes you app feel much smoother. -See [the API documentation on component_vue](/api/component_vue) for more information. +See [the API documentation on component_vue](/documentation/api/utilities/component_vue) for more information. This example is based on [the vuetify docs](https://v2.vuetifyjs.com/en/components/sparklines/#custom-labels), Note that the "Go to report" button does not do anything yet. @@ -14,7 +14,6 @@ from typing import Callable import numpy as np - import solara seed = solara.reactive(42) diff --git a/solara/website/pages/examples/ipycanvas.py b/solara/website/pages/documentation/examples/ipycanvas.py similarity index 100% rename from solara/website/pages/examples/ipycanvas.py rename to solara/website/pages/documentation/examples/ipycanvas.py diff --git a/solara/website/pages/examples/libraries/__init__.py b/solara/website/pages/documentation/examples/libraries/__init__.py similarity index 100% rename from solara/website/pages/examples/libraries/__init__.py rename to solara/website/pages/documentation/examples/libraries/__init__.py diff --git a/solara/website/pages/examples/libraries/altair.py b/solara/website/pages/documentation/examples/libraries/altair.py similarity index 93% rename from solara/website/pages/examples/libraries/altair.py rename to solara/website/pages/documentation/examples/libraries/altair.py index be33dc1b0..e1f0e75b7 100644 --- a/solara/website/pages/examples/libraries/altair.py +++ b/solara/website/pages/documentation/examples/libraries/altair.py @@ -2,16 +2,15 @@ [Altair](https://altair-viz.github.io/index.html) is a declarative statistical visualization library for Python. -This example show how to use the [on_click handler](/api/altair) to display data for a specific day in the chart. +This example show how to use the [on_click handler](/documentation/components/viz/altair) to display data for a specific day in the chart. Based on [an Altair example](https://altair-viz.github.io/gallery/annual_weather_heatmap.html) """ import altair as alt import pandas as pd -from vega_datasets import data - import solara +from vega_datasets import data # title = "Altair visualization" source = data.seattle_weather() diff --git a/solara/website/pages/examples/libraries/bqplot.py b/solara/website/pages/documentation/examples/libraries/bqplot.py similarity index 100% rename from solara/website/pages/examples/libraries/bqplot.py rename to solara/website/pages/documentation/examples/libraries/bqplot.py diff --git a/solara/website/pages/examples/libraries/ipyleaflet.py b/solara/website/pages/documentation/examples/libraries/ipyleaflet.py similarity index 100% rename from solara/website/pages/examples/libraries/ipyleaflet.py rename to solara/website/pages/documentation/examples/libraries/ipyleaflet.py diff --git a/solara/website/pages/examples/libraries/ipyleaflet_advanced.py b/solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py similarity index 94% rename from solara/website/pages/examples/libraries/ipyleaflet_advanced.py rename to solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py index 29c48aaa0..4cb64db98 100644 --- a/solara/website/pages/examples/libraries/ipyleaflet_advanced.py +++ b/solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py @@ -1,7 +1,7 @@ """ # ipyleaflet advanced -Extends the [basic ipyleaflet example](/examples/libraries/ipyleaflet) with a marker that can be dragged around, and a +Extends the [basic ipyleaflet example](/documentation/examples/libraries/ipyleaflet) with a marker that can be dragged around, and a dropdown to select the map style. Two buttons allow to reset the map to the default zoom and center and to zoom to the marker. """ diff --git a/solara/website/pages/examples/utilities/__init__.py b/solara/website/pages/documentation/examples/utilities/__init__.py similarity index 100% rename from solara/website/pages/examples/utilities/__init__.py rename to solara/website/pages/documentation/examples/utilities/__init__.py diff --git a/solara/website/pages/examples/utilities/calculator.py b/solara/website/pages/documentation/examples/utilities/calculator.py similarity index 100% rename from solara/website/pages/examples/utilities/calculator.py rename to solara/website/pages/documentation/examples/utilities/calculator.py diff --git a/solara/website/pages/examples/utilities/countdown_timer.py b/solara/website/pages/documentation/examples/utilities/countdown_timer.py similarity index 94% rename from solara/website/pages/examples/utilities/countdown_timer.py rename to solara/website/pages/documentation/examples/utilities/countdown_timer.py index d6e01a976..fc94b92ee 100644 --- a/solara/website/pages/examples/utilities/countdown_timer.py +++ b/solara/website/pages/documentation/examples/utilities/countdown_timer.py @@ -1,6 +1,6 @@ """# Countdown timer. -This example shows how to use [use_thread](/api/use_thread) to create a countdown timer. +This example shows how to use [use_thread](/documentation/api/hooks/use_thread) to create a countdown timer. The UI code demonstrates a lot of conditional rendering. diff --git a/solara/website/pages/examples/utilities/todo.py b/solara/website/pages/documentation/examples/utilities/todo.py similarity index 100% rename from solara/website/pages/examples/utilities/todo.py rename to solara/website/pages/documentation/examples/utilities/todo.py diff --git a/solara/website/pages/examples/visualization/__init__.py b/solara/website/pages/documentation/examples/visualization/__init__.py similarity index 100% rename from solara/website/pages/examples/visualization/__init__.py rename to solara/website/pages/documentation/examples/visualization/__init__.py diff --git a/solara/website/pages/examples/visualization/annotator.py b/solara/website/pages/documentation/examples/visualization/annotator.py similarity index 100% rename from solara/website/pages/examples/visualization/annotator.py rename to solara/website/pages/documentation/examples/visualization/annotator.py diff --git a/solara/website/pages/examples/visualization/linked_views.py b/solara/website/pages/documentation/examples/visualization/linked_views.py similarity index 100% rename from solara/website/pages/examples/visualization/linked_views.py rename to solara/website/pages/documentation/examples/visualization/linked_views.py diff --git a/solara/website/pages/examples/visualization/plotly.py b/solara/website/pages/documentation/examples/visualization/plotly.py similarity index 93% rename from solara/website/pages/examples/visualization/plotly.py rename to solara/website/pages/documentation/examples/visualization/plotly.py index 8ecb7d36f..d837350fb 100644 --- a/solara/website/pages/examples/visualization/plotly.py +++ b/solara/website/pages/documentation/examples/visualization/plotly.py @@ -8,12 +8,11 @@ ## Note Solara supports plotly and plotly express. Create your figure (not a figure widget) -and pass it to the [FigurePlotly](/api/plotly) component. +and pass it to the [FigurePlotly](/documentation/components/viz/plotly) component. """ import pandas as pd import plotly.express as px - import solara title = "Scatter plot using Plotly" diff --git a/solara/website/pages/documentation/faq/__init__.py b/solara/website/pages/documentation/faq/__init__.py new file mode 100644 index 000000000..6e3c18b41 --- /dev/null +++ b/solara/website/pages/documentation/faq/__init__.py @@ -0,0 +1,11 @@ +from pathlib import Path + +import solara + +title = "FAQ" +HERE = Path(__file__) + + +@solara.component +def Page(route_external=None): + solara.Markdown(Path(HERE.parent / "content" / "99-faq.md").read_text()) diff --git a/solara/website/pages/docs/content/99-faq.md b/solara/website/pages/documentation/faq/content/99-faq.md similarity index 100% rename from solara/website/pages/docs/content/99-faq.md rename to solara/website/pages/documentation/faq/content/99-faq.md diff --git a/solara/website/pages/docs/__init__.py b/solara/website/pages/documentation/getting_started/__init__.py similarity index 64% rename from solara/website/pages/docs/__init__.py rename to solara/website/pages/documentation/getting_started/__init__.py index 758b25440..060ee3c57 100644 --- a/solara/website/pages/docs/__init__.py +++ b/solara/website/pages/documentation/getting_started/__init__.py @@ -1,9 +1,15 @@ from pathlib import Path +import solara from solara.autorouting import generate_routes_directory -title = "Docs" +title = "Getting Started" HERE = Path(__file__) # if we didn't put the content in the subdirectory, but pointed to the current file # we would include the current file recursively, causing an infinite loop routes = generate_routes_directory(HERE.parent / "content") + + +@solara.component +def Page(route_external=None): + solara.Markdown(Path(HERE.parent / "content" / "00-introduction.md").read_text()) diff --git a/solara/website/pages/docs/content/03-quickstart.md b/solara/website/pages/documentation/getting_started/content/00-quickstart.md similarity index 93% rename from solara/website/pages/docs/content/03-quickstart.md rename to solara/website/pages/documentation/getting_started/content/00-quickstart.md index ffb5fb6b1..7c52b7d6c 100644 --- a/solara/website/pages/docs/content/03-quickstart.md +++ b/solara/website/pages/documentation/getting_started/content/00-quickstart.md @@ -7,12 +7,12 @@ This 1-minute quickstart will get you to: * Run your script using Solara server. * (Optional) Reuse your code in the Jupyter notebook. -If you are an existing ipywidget user and do not want to learn the component based method, you might want to skip the quickstart and directly go to the [IPywidgets user tutorial](/docs/tutorial/ipywidgets). +If you are an existing ipywidget user and do not want to learn the component based method, you might want to skip the quickstart and directly go to the [IPywidgets user tutorial](/documentation/getting_started/tutorials/ipywidgets). ## Installation -Run `pip install solara`, or follow the [Installation instructions](/docs/installing) for more detailed instructions. +Run `pip install solara`, or follow the [Installation instructions](/documentation/getting_started/installing) for more detailed instructions. ## First script diff --git a/solara/website/pages/docs/content/00-introduction.md b/solara/website/pages/documentation/getting_started/content/01-introduction.md similarity index 62% rename from solara/website/pages/docs/content/00-introduction.md rename to solara/website/pages/documentation/getting_started/content/01-introduction.md index dca354820..f8a218554 100644 --- a/solara/website/pages/docs/content/00-introduction.md +++ b/solara/website/pages/documentation/getting_started/content/01-introduction.md @@ -5,7 +5,7 @@ Solara is an Open Source library that lets you use and build data-focused web apps (data apps) using reusable UI components. Your app will work in the Jupyter notebook and production-grade web frameworks (FastAPI, Starlette, Flask, ...). -Solara uses proven technologies and mature standards. Grow from a one-off experiment in the Jupyter notebook to a dynamic data portal in production. Built on top of [Reacton](/docs/understanding/reacton) to keep your code complexity under control and [IPywidgets](/docs/understanding/ipywidgets) to access a rich set of UI libraries without having to write Javascript or CSS. +Solara uses proven technologies and mature standards. Grow from a one-off experiment in the Jupyter notebook to a dynamic data portal in production. Built on top of [Reacton](/documentation/advanced/understanding/reacton) to keep your code complexity under control and [IPywidgets](/documentation/advanced/understanding/ipywidgets) to access a rich set of UI libraries without having to write Javascript or CSS. We care about developer experience. Solara will give your hot code reloading and type hints for faster development. @@ -17,19 +17,19 @@ Many frameworks only solve a specific set of problems. Once you step outside of On the other extreme, you might be working with a library with no clear patterns that let you do anything. You may only be weeks away from a total code complexity nightmare, which slowly kills your project. -At the same time, starting a new framework from scratch would be unwise. We prefer to build on top of solid, battle-tested libraries, such as [IPywidgets](/docs/understanding/ipywidgets). +At the same time, starting a new framework from scratch would be unwise. We prefer to build on top of solid, battle-tested libraries, such as [IPywidgets](/documentation/advanced/understanding/ipywidgets). ## Why use Solara? Instead of inventing a new API with an unknown track record, we take a different approach. We look at the JavaScript world. React is a technology that has proven itself for many years. It has shown to be a good all-around model for building complex UIs. -[Reacton](/docs/understanding/reacton) is the equivalent of ReactJS for Python (and IPywidgets). It allows us to use the same reusable components and hooks as in the ReactJS ecosystem. Using Reacton, we build web/data applications without suffering from complex code bases. +[Reacton](/documentation/advanced/understanding/reacton) is the equivalent of ReactJS for Python (and IPywidgets). It allows us to use the same reusable components and hooks as in the ReactJS ecosystem. Using Reacton, we build web/data applications without suffering from complex code bases. Looking again at the JavaScript world, we see software such as NextJS is putting a framework around ReactJS. NextJS is more opinionated than ReactJS and adds more "batteries" such as routing. Solara plays a similar role as NextJS. It builds on top of Reacton but handles things like routing for you. -But Solara is also different and is even more opinionated than NextJS. The reason for this is its focus on the data-heavy Python ecosystem. For this reason, it comes with many components and hooks that make building beautiful data apps easier (see our [API](/api)). +But Solara is also different and is even more opinionated than NextJS. The reason for this is its focus on the data-heavy Python ecosystem. For this reason, it comes with many components and hooks that make building beautiful data apps easier (see our [Documentation](/documentation)). Solara is a clear, systematic, Python-based web framework using industry-trusted technology. Smooth developer experience and enforced code modularity will allow you to build a data app at any scale while maintaining simple code. @@ -37,7 +37,7 @@ Solara is a clear, systematic, Python-based web framework using industry-trusted For your understanding, it might be good just to run an example. -Follow the [installation instructions](/docs/installing) or do the TLDR: +Follow the [installation instructions](/documentation/getting_started/installing) or do the TLDR: $ pip install solara @@ -78,18 +78,18 @@ The browser should open http://127.0.0.1:8765 Solara is actually two things. ### Solara server -[Solara server](/docs/understanding/solara-server) renders ipywidgets in the browser in a very efficient manner and takes care of many other things -such as [routing](/docs/understanding/routing) and [Static Site Generation](/docs/reference/static-site-generation). +[Solara server](/documentation/advanced/understanding/solara-server) renders ipywidgets in the browser in a very efficient manner and takes care of many other things +such as [routing](/documentation/advanced/understanding/routing) and [Static Site Generation](/documentation/getting_started/reference/static-site-generation). ### Solara UI -The UI part is built on top of [Reacton](/docs/understanding/reacton), which uses the existing IPyWidgets stack. It gives a consistent set +The UI part is built on top of [Reacton](/documentation/advanced/understanding/reacton), which uses the existing IPyWidgets stack. It gives a consistent set of modern UI components with the Material Design look, as well as a set of routines to make application development of data heavy web apps easier. ### Overview -If you use Jupyter, then you probably use the Jupyter notebook, Lab, or [Voila](/docs/understanding/voila) to get your widgets into the browser. You may not care about [Solara server](/docs/understanding/solara-server) and can focus on just the UI part. +If you use Jupyter, then you probably use the Jupyter notebook, Lab, or [Voila](/documentation/advanced/understanding/voila) to get your widgets into the browser. You may not care about [Solara server](/documentation/advanced/understanding/solara-server) and can focus on just the UI part. If you don't use Jupyter, don't know what it is, or are an ML Ops, Dev Ops, or Sys Admin, you are probably more interested in the Solara server. @@ -99,19 +99,19 @@ If you don't use Jupyter, don't know what it is, or are an ML Ops, Dev Ops, or S We recommend going through the documentation linearly following the arrows on the bottom, meaning you will go through: - * [Installing](/docs/installing) - * [Quick start](/docs/quickstart) - * [Tutorials](/docs/tutorial) + * [Installing](/documentation/getting_started/installing) + * [Quick start](/documentation/getting_started) + * [Tutorials](/documentation/getting_started/tutorials) -If you want to know more about specific parts, you can go through the [How-to section](/docs/howto) to learn more. Feel free to skip chapters, and go back to topics when you need to. +If you want to know more about specific parts, you can go through the [How-to section](/documentation/advanced/howto) to learn more. Feel free to skip chapters, and go back to topics when you need to. -If you want to know what components or hooks are available, or want to know more about a specific component, check out the [API](/api) which includes live code examples. Other reference documentation can be found at the [reference section](/docs/reference) +If you want to know what components or hooks are available, or want to know more about a specific component, check out the [Documentation](/documentation) which includes live code examples. Other reference documentation can be found at the [reference section](/documentation/getting_started/reference) -If you feel like you miss some basic understanding and want to give a bit deeper into the what and why feel free to explore the [Understanding section](/docs/understanding). +If you feel like you miss some basic understanding and want to give a bit deeper into the what and why feel free to explore the [Understanding section](/documentation/advanced/understanding). -[Our examples](/examples) may help you see how particular problems can be solved using Solara, or as inspiration. If you want to contribute an example, contact us on GitHub or directly open a [Pull Request](https://github.com/widgetti/solara/). +[Our examples](/documentation/examples) may help you see how particular problems can be solved using Solara, or as inspiration. If you want to contribute an example, contact us on GitHub or directly open a [Pull Request](https://github.com/widgetti/solara/). ## Where can I hire an expert? diff --git a/solara/website/pages/docs/content/02-installing.md b/solara/website/pages/documentation/getting_started/content/02-installing.md similarity index 97% rename from solara/website/pages/docs/content/02-installing.md rename to solara/website/pages/documentation/getting_started/content/02-installing.md index 1c34c8b07..074e26f5b 100644 --- a/solara/website/pages/docs/content/02-installing.md +++ b/solara/website/pages/documentation/getting_started/content/02-installing.md @@ -44,7 +44,7 @@ solara @ https://github.com/widgetti/solara/package/archive/master.tar.gz ``` -If you want to do development on Solara, read the [development documentation](/docs/development). +If you want to do development on Solara, read the [development documentation](/documentation/advanced/development/setup). ## Air-gapped installation / Firewalled network diff --git a/solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md b/solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md new file mode 100644 index 000000000..fb9032c67 --- /dev/null +++ b/solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md @@ -0,0 +1,9 @@ +# Tutorials + +Instead of having one tutorial, we have tutorials for different audiences. + + * [Jupyter Dashboard](/documentation/getting_started/tutorials/jupyter-dashboard-part1): Learn to create a dashboard in the Jupyter notebook. + * [Data science](/documentation/getting_started/tutorials/data-science): In this tutorial, we will introduce Solara from the perspective of a data scientist or when you are thinking of using Solara for a data science app. + * [Web app](/documentation/getting_started/tutorials/web-app): You are not a data scientist, but you are interested in using Solara to create a web app using Pure Python. + * [IPywidgets user](/documentation/getting_started/tutorials/ipywidgets): If you are already using [ipywidgets](/documentation/advanced/understanding/ipywidgets) you will learn how to use the [Solara server](/documentation/advanced/understanding/solara-server) to render your regular ipywidget applications. + * [Streamlit](/documentation/getting_started/tutorials/streamlit): If you are an existing Streamlit user, this might appeal more to you. diff --git a/solara/website/pages/docs/content/04-tutorial/10_data_science.py b/solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py similarity index 100% rename from solara/website/pages/docs/content/04-tutorial/10_data_science.py rename to solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py diff --git a/solara/website/pages/docs/content/04-tutorial/20-web-app.md b/solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md similarity index 83% rename from solara/website/pages/docs/content/04-tutorial/20-web-app.md rename to solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md index 898bc4138..6788402ec 100644 --- a/solara/website/pages/docs/content/04-tutorial/20-web-app.md +++ b/solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md @@ -5,7 +5,7 @@ In this tutorial, you will learn how to use Solara to create a tiny web app usin ## You should know This tutorial will assume you have successfully installed Solara. -If not, please follow the [Installation guide](/docs/installing). +If not, please follow the [Installation guide](/documentation/getting_started/installing). ## Generate a script file The simplest way to get started is to run the command @@ -40,7 +40,7 @@ def Page(): ## Run the script -Using [Solara server](/docs/understanding/solara-server), we can now run our Python script using: +Using [Solara server](/documentation/advanced/understanding/solara-server), we can now run our Python script using: ```bash $ solara run sol.py @@ -50,7 +50,7 @@ Solara server is starting at http://localhost:8765 If you open the URL in your browser ([or click here](http://localhost:8765)), you should see the same example as above. Solara will run your script once, and will look for the `Page` component. Solara expects this component to exist -and be a [Reacton](/docs/understanding/reacton) component. (See the [IPywidget tutorial](/docs/tutorial/ipywidgets) to learn how to render a regular ipywidget). +and be a [Reacton](/documentation/advanced/understanding/reacton) component. (See the [IPywidget tutorial](/documentation/getting_started/tutorials/ipywidgets) to learn how to render a regular ipywidget). Since your script is only run once, you could put in the main body of your script code that only needs to run once (e.g. loading data from disk) @@ -68,7 +68,7 @@ Lets modify the script a little bit, possibly in this way: ``` If we save the script, Solara will automatically reload your script and update -your browser (we call this feature [hot reloading](/docs/reference/reloading)). +your browser (we call this feature [hot reloading](/documentation/getting_started/reference/reloading)). Note that Solara will remember your state (e.g., the number of buttons clicked) when the app reloads. diff --git a/solara/website/pages/docs/content/04-tutorial/30-ipywidgets.md b/solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md similarity index 69% rename from solara/website/pages/docs/content/04-tutorial/30-ipywidgets.md rename to solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md index b3a59dfaa..37751baa7 100644 --- a/solara/website/pages/docs/content/04-tutorial/30-ipywidgets.md +++ b/solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md @@ -1,15 +1,15 @@ # Tutorial: IPywidgets -If you are already using [ipywidgets](/docs/understanding/ipywidgets) in the notebook, possibly using [Voila](/docs/understanding/voila), you might be pleased to know that you -can also use the [Solara server](/docs/understanding/solara-server) to render your regular ipywidget application. +If you are already using [ipywidgets](/documentation/advanced/understanding/ipywidgets) in the notebook, possibly using [Voila](/documentation/advanced/understanding/voila), you might be pleased to know that you +can also use the [Solara server](/documentation/advanced/understanding/solara-server) to render your regular ipywidget application. -We recommend you learn how to write applications using [Reacton](/docs/understanding/reacton). However, if you have already written an application in -pure [ipywidgets](/docs/understanding/ipywidgets), this approach will let you gradually move from pure ipywidgets to Reacton. +We recommend you learn how to write applications using [Reacton](/documentation/advanced/understanding/reacton). However, if you have already written an application in +pure [ipywidgets](/documentation/advanced/understanding/ipywidgets), this approach will let you gradually move from pure ipywidgets to Reacton. ## You should know This tutorial will assume you have successfully installed Solara. -If not, please follow the [Installation guide](/docs/installing). +If not, please follow the [Installation guide](/documentation/getting_started/installing). ## Your first ipywidget based Solara app @@ -70,10 +70,10 @@ Try making the following code change (remove the first, add the last), and watch ## Using Solara components -There are a lot of [valuable components in Solara](/api), but they are written as [Reacton/Solara components](/docs/understanding/reacton-basics), not +There are a lot of [valuable components in Solara](/documentation/components), but they are written as [Reacton/Solara components](/documentation/advanced/understanding/reacton-basics), not classic ipywidgets. -Use the [.widget(...)](/api/widget) method on a component to create a widget that can be used in your existing classic ipywidget application. +Use the [.widget(...)](/documentation/api/utilities/widget) method on a component to create a widget that can be used in your existing classic ipywidget application. ```python @@ -111,10 +111,10 @@ Note that we did not include the `:page` here, since solara will automatically l ## What you have learned - * [Solara server](/docs/understanding/solara-server) can render [ipywidgets](/docs/understanding/ipywidgets). + * [Solara server](/documentation/advanced/understanding/solara-server) can render [ipywidgets](/documentation/advanced/understanding/ipywidgets). * Running `$ solara run filename.py:variablename` tells Solara which script to execute and which variable name from the script to render. * The script is executed: * Once, when the solara server starts. * On each page request. * For each open browser page/tab, when the script is saved (hot reloading). - * Using the [.widget(...)](/api/widget) method we can start using Solara components in classic ipywidget app. + * Using the [.widget(...)](/documentation/api/utilities/widget) method we can start using Solara components in classic ipywidget app. diff --git a/solara/website/pages/docs/content/04-tutorial/40-streamlit.md b/solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md similarity index 65% rename from solara/website/pages/docs/content/04-tutorial/40-streamlit.md rename to solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md index 926ee22c6..73548f034 100644 --- a/solara/website/pages/docs/content/04-tutorial/40-streamlit.md +++ b/solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md @@ -18,8 +18,8 @@ st.markdown(f"{x} squared = {x_squared}") ## Translated to Solara -We now translate this to the equivalent in Solara. The largest difference is we need to explicitly create (application) state using [`solara.reactive`](/api/reactive). By passing the -reactive variable to the [SliderInt](/api/slider) via `value=x` we set up a two way binding between the component and the reactive variable. The generated text is passed down to the [Markdown](/api/markdown) component. +We now translate this to the equivalent in Solara. The largest difference is we need to explicitly create (application) state using [`solara.reactive`](/documentation/api/utilities/reactive). By passing the +reactive variable to the [SliderInt](/documentation/components/input/slider) via `value=x` we set up a two way binding between the component and the reactive variable. The generated text is passed down to the [Markdown](/documentation/components/output/markdown) component. ```solara @@ -49,7 +49,7 @@ You will see: Because we do some styling and because the sidebar is already used up, our preview on this page looks slightly different. -[Navigate to /apps/tutorial-streamlit](/apps/tutorial-streamlit) to see this app fullscreen. +[Navigate to /apps/tutorial-streamlit](/documentation/examples/fullscreen/tutorial_streamlit) to see this app fullscreen. ### Running this example in the notebook @@ -61,7 +61,7 @@ Again, slightly different for a different environment. ## Hot reloading -If you are using [Solara server](/docs/understanding/solara-server), try editing `sol.py`, and watch the page reload automatically after you save your file. Notebook users can simply edit and re-run. +If you are using [Solara server](/documentation/advanced/understanding/solara-server), try editing `sol.py`, and watch the page reload automatically after you save your file. Notebook users can simply edit and re-run. (*Note: Upgrade to solara 1.14.0 for a fix in hot reloading using `pip install "solara>=1.14.0"`*) @@ -69,13 +69,13 @@ If you are using [Solara server](/docs/understanding/solara-server), try editing ### Execution model As the introduction says, Solara does not re-execute your whole script after user interactions. -The main script is executed only once. With Solara you can use your main script to read large dataframes, or do some pre-calculations without the need for [caching](/docs/reference/caching). +The main script is executed only once. With Solara you can use your main script to read large dataframes, or do some pre-calculations without the need for [caching](/documentation/getting_started/reference/caching). -When a user navigates to a Solara server, the `Page` component (basically a function) will get executed. The `Page` component will call (lazily) new components like [solara.Markdown](/api/markdown) to build up the page. If state changes due to user input, Solara will trigger a cascade of re-excecutions of components which inputs or state changed, but never your whole script, nor every component. +When a user navigates to a Solara server, the `Page` component (basically a function) will get executed. The `Page` component will call (lazily) new components like [solara.Markdown](/documentation/components/output/markdown) to build up the page. If state changes due to user input, Solara will trigger a cascade of re-excecutions of components which inputs or state changed, but never your whole script, nor every component. ### State -With Solara (and [Reacton](/docs/understanding/reacton)) state does not live in a UI component (like a slider). Application state created with [`solara.reactive`](/api/reactive) lives on its own. Connecting the state to the UI component (in this case a slider) is a separate step, done via `value=x` in the above example. In general we recommend organising your components -similarly as in the example: [First use_state and other hooks, then calculations, at last the UI components](/docs/understanding/anatomy). +With Solara (and [Reacton](/documentation/advanced/understanding/reacton)) state does not live in a UI component (like a slider). Application state created with [`solara.reactive`](/documentation/api/utilities/reactive) lives on its own. Connecting the state to the UI component (in this case a slider) is a separate step, done via `value=x` in the above example. In general we recommend organising your components +similarly as in the example: [First use_state and other hooks, then calculations, at last the UI components](/documentation/advanced/understanding/anatomy). For complex situations, it is important to separate the state and the UI. Especially when you need the state of a UI component as input of the UI component itself, you can get stuck with streamlit. In Solara this follows naturally. @@ -83,8 +83,8 @@ For complex situations, it is important to separate the state and the UI. Especi ## Creating a reusable component -A big advantage of Solara is that you can create reusable components. A single component can be seen as the equivalent of a single streamlit script. However, in that case, we need to modify our component to have its own state, rather than using global application state, for this you can use the [`use_reactive`](/api/use_reactive), or [`use_state`](/api/use_state) hook. -Read more about state management in the [state management](/docs/fundamentals/state-management) section. +A big advantage of Solara is that you can create reusable components. A single component can be seen as the equivalent of a single streamlit script. However, in that case, we need to modify our component to have its own state, rather than using global application state, for this you can use the [`use_reactive`](/documentation/api/hooks/use_reactive), or [`use_state`](/documentation/api/hooks/use_state) hook. +Read more about state management in the [state management](/documentation/getting_started/fundamentals/state-management) section. ```solara import solara @@ -129,8 +129,8 @@ Changing that "y" to "x" will lead to an error, however. If this is a problem in ### Long running function -In Streamlit, it is normal for your main script to block execution. In Solara, the functions bodies of your components ([called render functions](/docs/understanding/anatomy)) should not block. Functions that block, or take a long time to execute, should be executed in a thread, such that rendering can continue. Using threads may sound scary, but using the -[use_thread](/api/use_thread) hook will help a lot. +In Streamlit, it is normal for your main script to block execution. In Solara, the functions bodies of your components ([called render functions](/documentation/advanced/understanding/anatomy)) should not block. Functions that block, or take a long time to execute, should be executed in a thread, such that rendering can continue. Using threads may sound scary, but using the +[use_thread](/documentation/api/hooks/use_thread) hook will help a lot. ## What you have learned @@ -138,4 +138,4 @@ In Streamlit, it is normal for your main script to block execution. In Solara, t * Solara will re-execute components instead, only what needs to. * State in Solara is separate from the UI components, unlike streamlit, where they are strongly linked. * State can be on the application level (global) for simplicity or on the component level (local) for creating reusable components. - * Solara should not block the render loop. Long-running functions should be executed in a thread using [use_thread](/api/use_thread). + * Solara should not block the render loop. Long-running functions should be executed in a thread using [use_thread](/documentation/api/hooks/use_thread). diff --git a/solara/website/pages/docs/content/04-tutorial/50-dash.md b/solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md similarity index 86% rename from solara/website/pages/docs/content/04-tutorial/50-dash.md rename to solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md index 241fb1b6f..2fb55a588 100644 --- a/solara/website/pages/docs/content/04-tutorial/50-dash.md +++ b/solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md @@ -36,7 +36,7 @@ This small app creates a dropdown (what we call Select in Solara), and some mark ## Translated to Solara -In Solara, we need to explicitly create application state using [`solara.reactive`](/api/reactive). We wire this up with the [Select][/api/select] via `value=color` and pass the color value down to the [Markdown](/api/markdown) component. +In Solara, we need to explicitly create application state using [`solara.reactive`](/documentation/api/utilities/reactive). We wire this up with the [Select][/documentation/components/input/select] via `value=color` and pass the color value down to the [Markdown](/documentation/components/output/markdown) component. ```solara import solara @@ -50,7 +50,7 @@ def Page(): solara.Markdown("## Hello World", style={"color": color.value}) ``` -Since this component combines two components, we have to put them together in a [container](/docs/understanding/containers) component, here implicitly a [Column](/api/column). +Since this component combines two components, we have to put them together in a [container](/documentation/advanced/understanding/containers) component, here implicitly a [Column](/documentation/components/layout/column). ## Making a re-usable component @@ -115,7 +115,7 @@ if __name__ == "__main__": ### In Solara -A big advantage of Solara is that components are reusable by default. However, we need to modify our component to have its own state, rather than using global application state. Creating local component state with [`use_reactive`](/api/use_reactive), or [`use_state`](/api/use_state) hook. Read more about state management in the [state management](/docs/fundamentals/state-management) section. +A big advantage of Solara is that components are reusable by default. However, we need to modify our component to have its own state, rather than using global application state. Creating local component state with [`use_reactive`](/documentation/api/hooks/use_reactive), or [`use_state`](/documentation/api/hooks/use_state) hook. Read more about state management in the [state management](/documentation/getting_started/fundamentals/state-management) section. We will rename (from `Page` to `MarkdownWithColor`) the component, add local state, and put in the markdown text as an argument. diff --git a/solara/website/pages/docs/content/04-tutorial/60-jupyter-dashboard-part1.py b/solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py similarity index 100% rename from solara/website/pages/docs/content/04-tutorial/60-jupyter-dashboard-part1.py rename to solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py diff --git a/solara/website/pages/docs/content/04-tutorial/SF_crime_sample.csv.gz b/solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz similarity index 100% rename from solara/website/pages/docs/content/04-tutorial/SF_crime_sample.csv.gz rename to solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz diff --git a/solara/website/pages/docs/content/04-tutorial/_data_science.ipynb b/solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb similarity index 96% rename from solara/website/pages/docs/content/04-tutorial/_data_science.ipynb rename to solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb index e27f2e703..659f518aa 100644 --- a/solara/website/pages/docs/content/04-tutorial/_data_science.ipynb +++ b/solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb @@ -16,7 +16,7 @@ " * You have successfully installed Solara\n", " * You know how to display a Solara component in a notebook or script\n", "\n", - "If not, please follow the [Quick start](/docs/quickstart).\n", + "If not, please follow the [Quick start](/documentation/getting_started).\n", "\n", "## Extra packages you need to install\n", "\n", @@ -85,7 +85,7 @@ "fig = px.scatter(df, \"sepal_length\", \"sepal_width\")\n", "```\n", "\n", - "To display this figure in a Solara component, we should return an element that can render the plotly figure. [FigurePlotly](/api/plotly) will do the job for us.\n", + "To display this figure in a Solara component, we should return an element that can render the plotly figure. [FigurePlotly](/documentation/components/viz/plotly) will do the job for us.\n", "\n", "Putting this together" ] @@ -133,7 +133,7 @@ "x_axis = solara.reactive(\"sepal_length\")\n", "```\n", "\n", - "This code creates a reactive variable. You can use this reactive variable in your component and pass it to a [`Select`]((/api/select)) component to control the selected column.\n", + "This code creates a reactive variable. You can use this reactive variable in your component and pass it to a [`Select`](/documentation/components/input/select) component to control the selected column.\n", "\n", "\n", "```python\n", @@ -196,7 +196,7 @@ "\n", "#### State\n", "\n", - "Understanding state management and how Solara re-renders component is crucial for understanding building larger applications. If you don't fully graps it now, that is ok. You should first get used to the pattern, and consider reading [About state management](/docs/fundamentals/state-management) later on to get a deeper understanding.\n", + "Understanding state management and how Solara re-renders component is crucial for understanding building larger applications. If you don't fully graps it now, that is ok. You should first get used to the pattern, and consider reading [About state management](/documentation/getting_started/fundamentals/state-management) later on to get a deeper understanding.\n", "\n" ] }, @@ -358,7 +358,7 @@ " return df.sort_values('distance')[1:n+1]\n", "```\n", "\n", - "We now only find the nearest neighbours if `click_data.value` is not None, and display the dataframe using the [`DataFrame`](/api/dataframe) component.\n" + "We now only find the nearest neighbours if `click_data.value` is not None, and display the dataframe using the [`DataFrame`](/documentation/components/data/dataframe) component.\n" ] }, { diff --git a/solara/website/pages/docs/content/04-tutorial/_jupyter_dashboard_1.ipynb b/solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb similarity index 100% rename from solara/website/pages/docs/content/04-tutorial/_jupyter_dashboard_1.ipynb rename to solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb diff --git a/solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md b/solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md new file mode 100644 index 000000000..ff2da10d1 --- /dev/null +++ b/solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md @@ -0,0 +1,7 @@ +# Fundamentals + +If you want to dive deeper into Solara, this section is for you. We will cover the following topics: + + * [Components](/documentation/getting_started/fundamentals/components) + * Hooks (soon) + * [State management](/documentation/getting_started/fundamentals/state-management) diff --git a/solara/website/pages/docs/content/07-fundamentals/10-components.md b/solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md similarity index 97% rename from solara/website/pages/docs/content/07-fundamentals/10-components.md rename to solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md index 9052bbfda..f1b8f24ee 100644 --- a/solara/website/pages/docs/content/07-fundamentals/10-components.md +++ b/solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md @@ -19,9 +19,9 @@ In Solara, there are two main types of components: Widget Components and Functio Widget Components correspond to ipywidgets and are responsible for rendering visual elements in the browser, such as buttons, sliders, or performing layout tasks. These components are the foundation of your user interface and provide the essential building blocks for creating interactive applications. -Solara mainly uses the [ipyvuetify library](/docs/understanding/ipyvuetify) for its widget components. It provides a set of high-level components that can be used to create rich, interactive user interfaces. +Solara mainly uses the [ipyvuetify library](/documentation/advanced/understanding/ipyvuetify) for its widget components. It provides a set of high-level components that can be used to create rich, interactive user interfaces. -See the [API docs](/docs/api) for a complete list of basic UI components. +See the [components page](/documentation/components) for a complete list of basic UI components. ## Function Components diff --git a/solara/website/pages/docs/content/07-fundamentals/50-state-management.md b/solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md similarity index 77% rename from solara/website/pages/docs/content/07-fundamentals/50-state-management.md rename to solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md index c6e867068..ae5766d7b 100644 --- a/solara/website/pages/docs/content/07-fundamentals/50-state-management.md +++ b/solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md @@ -1,12 +1,12 @@ # Introduction -State management is a crucial aspect of building data-focused web applications with Solara. By effectively managing state, you can create interactive and responsive applications that react to changes in data and user input. In Solara, there are two primary ways to define state: global application state using [`solara.reactive`](/api/reactive) and local component state using [`solara.use_state`](/api/use_state) or [`solara.use_reactive`](/api/use_reactive). This article will discuss these two approaches and provide examples of how to use them in your Solara applications. +State management is a crucial aspect of building data-focused web applications with Solara. By effectively managing state, you can create interactive and responsive applications that react to changes in data and user input. In Solara, there are two primary ways to define state: global application state using [`solara.reactive`](/documentation/api/utilities/reactive) and local component state using [`solara.use_state`](/documentation/api/hooks/use_state) or [`solara.use_reactive`](/documentation/api/hooks/use_reactive). This article will discuss these two approaches and provide examples of how to use them in your Solara applications. ## Two main ways of defining state in Solara ### Global application state using solara.reactive -Using [`solara.reactive`](/api/reactive) allows you to create global state variables that can be accessed and modified from any component within your application. This approach is useful when you need to manage state that is shared across multiple components or when you want to maintain consistency throughout your application. +Using [`solara.reactive`](/documentation/api/utilities/reactive) allows you to create global state variables that can be accessed and modified from any component within your application. This approach is useful when you need to manage state that is shared across multiple components or when you want to maintain consistency throughout your application. Example: @@ -30,7 +30,7 @@ In this case, the `SomeAppSpecificComponent` is not reusable in the sense that a ## Local component state using solara.use_state -[`solara.use_state`](/api/use_state) is a hook that allows you to manage local state within a specific component. This approach is beneficial when you want to encapsulate state within a component, making it self-contained and modular. Local state management is suitable for situations where state changes only affect the component and do not need to be shared across the application. +[`solara.use_state`](/documentation/api/hooks/use_state) is a hook that allows you to manage local state within a specific component. This approach is beneficial when you want to encapsulate state within a component, making it self-contained and modular. Local state management is suitable for situations where state changes only affect the component and do not need to be shared across the application. Example: ```solara diff --git a/solara/website/pages/documentation/getting_started/content/06-reference/00-overview.md b/solara/website/pages/documentation/getting_started/content/06-reference/00-overview.md new file mode 100644 index 000000000..fba1ef5a4 --- /dev/null +++ b/solara/website/pages/documentation/getting_started/content/06-reference/00-overview.md @@ -0,0 +1,3 @@ +# Reference documentation + +Our reference documentation informs you about how certain parts in Solara work. diff --git a/solara/website/pages/docs/content/15-reference/40-static_files.md b/solara/website/pages/documentation/getting_started/content/06-reference/40-static_files.md similarity index 100% rename from solara/website/pages/docs/content/15-reference/40-static_files.md rename to solara/website/pages/documentation/getting_started/content/06-reference/40-static_files.md diff --git a/solara/website/pages/docs/content/15-reference/41-asset-files.md b/solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md similarity index 90% rename from solara/website/pages/docs/content/15-reference/41-asset-files.md rename to solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md index 1e8f5739f..27de66f67 100644 --- a/solara/website/pages/docs/content/15-reference/41-asset-files.md +++ b/solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md @@ -29,4 +29,4 @@ All assets files are served under `/static/assets/`, but how the asset Putting the `assets` directory 1 level higher than the `pages` directory avoids name collision with pages. -Although the `assets` directory can be used for serving arbitrary files, we recommend using the [static files](/docs/reference/static-files) directory instead, to avoid name collisions. +Although the `assets` directory can be used for serving arbitrary files, we recommend using the [static files](/documentation/getting_started/reference/static-files) directory instead, to avoid name collisions. diff --git a/solara/website/pages/docs/content/15-reference/60-static-site-generation.md b/solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md similarity index 96% rename from solara/website/pages/docs/content/15-reference/60-static-site-generation.md rename to solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md index 5959968e4..78e2c473e 100644 --- a/solara/website/pages/docs/content/15-reference/60-static-site-generation.md +++ b/solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md @@ -29,7 +29,7 @@ Using the command $ solara ssg your.awesome.app ``` -Will run the solara server and use playwright to fetch all known pages and save them to the `../build` directory. Solara knows about your pages because of its [routing support](/docs/understanding/routing). +Will run the solara server and use playwright to fetch all known pages and save them to the `../build` directory. Solara knows about your pages because of its [routing support](/documentation/advanced/understanding/routing). All HTML files in the `../build` will be used to pre-populate the HTML served to the user. diff --git a/solara/website/pages/docs/content/15-reference/70-search.md b/solara/website/pages/documentation/getting_started/content/06-reference/70-search.md similarity index 70% rename from solara/website/pages/docs/content/15-reference/70-search.md rename to solara/website/pages/documentation/getting_started/content/06-reference/70-search.md index e84789902..08ef850d9 100644 --- a/solara/website/pages/docs/content/15-reference/70-search.md +++ b/solara/website/pages/documentation/getting_started/content/06-reference/70-search.md @@ -1,6 +1,6 @@ # Search -Solara can provide search, if [SSG](/docs/reference/static-site-generation) is enabled. This allows you to add a search box to you website, which performs a full-text search to provide quick access to pages. The solara website itself uses the +Solara can provide search, if [SSG](/documentation/getting_started/reference/static-site-generation) is enabled. This allows you to add a search box to you website, which performs a full-text search to provide quick access to pages. The solara website itself uses the search feature as well in the toolbar. ## Using Solara's Search feature. diff --git a/solara/website/pages/docs/content/15-reference/80-reloading.md b/solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md similarity index 82% rename from solara/website/pages/docs/content/15-reference/80-reloading.md rename to solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md index 7ab26e15b..e387b7c0a 100644 --- a/solara/website/pages/docs/content/15-reference/80-reloading.md +++ b/solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md @@ -13,18 +13,18 @@ When a `.vue` file is saved, the widgets get updated automatically, without need ## Reloading of .vue files -The [Style component](/api/style) accepts a Path as argument, when that is used and the server is in development mode (the default), also +The [Style component](/documentation/components/advanced/style) accepts a Path as argument, when that is used and the server is in development mode (the default), also CSS files will be hot reloaded. ## Restarting the server after changes to the solara packages -You don't need to care about this feature if you only use solara, this is only relevant for development on solara itself, [see also development instructions](/docs/development). +You don't need to care about this feature if you only use solara, this is only relevant for development on solara itself, [see also development instructions](/documentation/advanced/development/setup). If the `--auto-restart/-a` flag is passed to solara-server and any changes occur in the `solara` package (excluding `solara.webpage`), solara-server will restart. This speeds up development on `solara-server` for developers since you do not need to manually restart the server in the terminal. ## Disabling reloading -In production mode (pass the `--production` argument to `solara run`) watching of files is disabled, and no reloading of files or vue templates will occur. If you run solara integrated in flask or uvicorn as laid out in [deployment documentation](https://solara.dev/docs/deploying/self-hosted) +In production mode (pass the `--production` argument to `solara run`) watching of files is disabled, and no reloading of files or vue templates will occur. If you run solara integrated in flask or uvicorn as laid out in [deployment documentation](https://solara.dev/documentation/getting_started/deploying/self-hosted) diff --git a/solara/website/pages/docs/content/15-reference/90-notebook-support.md b/solara/website/pages/documentation/getting_started/content/06-reference/90-notebook-support.md similarity index 100% rename from solara/website/pages/docs/content/15-reference/90-notebook-support.md rename to solara/website/pages/documentation/getting_started/content/06-reference/90-notebook-support.md diff --git a/solara/website/pages/docs/content/15-reference/95-caching.md b/solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md similarity index 96% rename from solara/website/pages/docs/content/15-reference/95-caching.md rename to solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md index 5b4f9d0d5..16cfa8fbd 100644 --- a/solara/website/pages/docs/content/15-reference/95-caching.md +++ b/solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md @@ -11,7 +11,7 @@ assert "my-key" in solara.cache.storage Note that at any time later on, the key may be removed from this object, as a cache always has a limited capacity. -The `solara.cache.storage` cache object is used by [memoize](/api/memoize), if no storage argument is passed to this decorator. +The `solara.cache.storage` cache object is used by [memoize](/documentation/api/utilities/memoize), if no storage argument is passed to this decorator. ## Types of cache diff --git a/solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md b/solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md new file mode 100644 index 000000000..4a719842b --- /dev/null +++ b/solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md @@ -0,0 +1,3 @@ +# Deploying a solara app + +A Solara app can be [self hosted](/documentation/getting_started/deploying/self-hosted) or [cloud hosted](/documentation/getting_started/deploying/cloud-hosted). diff --git a/solara/website/pages/docs/content/30-deploying/10-self-hosted.md b/solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md similarity index 95% rename from solara/website/pages/docs/content/30-deploying/10-self-hosted.md rename to solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md index 10c7a26c1..196fdc2b8 100644 --- a/solara/website/pages/docs/content/30-deploying/10-self-hosted.md +++ b/solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md @@ -48,7 +48,7 @@ Instead, start your chosen web framework as directed by their documentation and $ export SOLARA_APP=sol.py # run flask or starlette -or look at the examples below for more detailed instructions per web framework. Note that when solara is used this way it [by default runs in production mode](https://solara.dev/docs/understanding/solara-server). +or look at the examples below for more detailed instructions per web framework. Note that when solara is used this way it [by default runs in production mode](https://solara.dev/documentation/advanced/understanding/solara-server). ## Flask @@ -180,7 +180,7 @@ display(element) Or consider using [Voila-vuetify](https://github.com/voila-dashboards/voila-vuetify). -Solara apps in Voila do not have support for [routing](/docs/understanding/routing)/[multipage](/docs/howto/multipage). +Solara apps in Voila do not have support for [routing](/documentation/advanced/understanding/routing)/[multipage](/documentation/advanced/howto/multipage). ## Panel @@ -211,7 +211,7 @@ For development/testing purposes, run this script as: $ panel serve solara_in_panel.py -Solara apps in Panel do not have support for [routing](/docs/understanding/routing)/[multipage](/docs/howto/multipage). +Solara apps in Panel do not have support for [routing](/documentation/advanced/understanding/routing)/[multipage](/documentation/advanced/howto/multipage). ## Nginx diff --git a/solara/website/pages/docs/content/30-deploying/20-cloud-hosted.md b/solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md similarity index 98% rename from solara/website/pages/docs/content/30-deploying/20-cloud-hosted.md rename to solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md index 26110cf86..9259e4f03 100644 --- a/solara/website/pages/docs/content/30-deploying/20-cloud-hosted.md +++ b/solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md @@ -73,4 +73,4 @@ Sign up for our waiting list to get early access. You can use [Ploomber Cloud](https://www.platform.ploomber.io) to deploy Solara apps for free (no credit card required). -To learn more, check out their [documentation.](https://docs.cloud.ploomber.io/en/latest/apps/solara.html) \ No newline at end of file +To learn more, check out their [documentation.](https://docs.cloud.ploomber.io/en/latest/apps/solara.html) diff --git a/solara/website/pages/docs/content/lab/00-what-is-lab.md b/solara/website/pages/documentation/getting_started/content/08-lab/00-what-is-lab.md similarity index 100% rename from solara/website/pages/docs/content/lab/00-what-is-lab.md rename to solara/website/pages/documentation/getting_started/content/08-lab/00-what-is-lab.md diff --git a/solara/website/pages/docs/content/90-troubleshoot.md b/solara/website/pages/documentation/getting_started/content/90-troubleshoot.md similarity index 100% rename from solara/website/pages/docs/content/90-troubleshoot.md rename to solara/website/pages/documentation/getting_started/content/90-troubleshoot.md diff --git a/solara/website/pages/documentation/getting_started/content/__init__.py b/solara/website/pages/documentation/getting_started/content/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/solara/website/pages/showcase/__init__.py b/solara/website/pages/showcase/__init__.py index 5580ef204..9cb443662 100644 --- a/solara/website/pages/showcase/__init__.py +++ b/solara/website/pages/showcase/__init__.py @@ -9,7 +9,7 @@ def Page(): with solara.Card("Wanderlust", style={"height": "100%"}): solara.Markdown( """ - [Wanderlust](./wanderlust) is a reproduction of the travel assistant demo shown at the + [Wanderlust](/showcase/wanderlust) is a reproduction of the travel assistant demo shown at the [OpenAI DevDay](https://devday.openai.com/) 2023, built using Solara and the OpenAI Assistants API. """ ) diff --git a/solara/website/pages/showcase/domino_code_assist.py b/solara/website/pages/showcase/domino_code_assist.py index d58844f5f..82a7fdefd 100644 --- a/solara/website/pages/showcase/domino_code_assist.py +++ b/solara/website/pages/showcase/domino_code_assist.py @@ -50,7 +50,7 @@ def Page(): # App deploying - To deploy apps we use [solara server](/docs/understanding/solara-server) which can + To deploy apps we use [solara server](/documentation/advanced/understanding/solara-server) which can render the same UI as in the notebook, but now sharable with non-technical users. Many users have deployed apps at Domino using Solara with diff --git a/solara/website/pages/showcase/solara_dev.py b/solara/website/pages/showcase/solara_dev.py index 4fe159cd5..e678211cf 100644 --- a/solara/website/pages/showcase/solara_dev.py +++ b/solara/website/pages/showcase/solara_dev.py @@ -22,7 +22,7 @@ def Page(): Solara.dev is designed to be responsive, working seamlessly on both desktop and mobile devices. On smaller screens, the top navigation bar is replaced with a drawer for easy navigation. - The [`ColumnsResponsive`](/api/columns_responsive) component can be used to create responsive content layouts. + The [`ColumnsResponsive`](/documentation/components/layout/columns_responsive) component can be used to create responsive content layouts. """ ) diff --git a/solara/website/public/social/discord.svg b/solara/website/public/social/discord.svg new file mode 100644 index 000000000..5ea93965b --- /dev/null +++ b/solara/website/public/social/discord.svg @@ -0,0 +1 @@ + diff --git a/solara/website/public/social/github.svg b/solara/website/public/social/github.svg new file mode 100644 index 000000000..c679c236f --- /dev/null +++ b/solara/website/public/social/github.svg @@ -0,0 +1 @@ + diff --git a/solara/website/public/social/twitter.svg b/solara/website/public/social/twitter.svg new file mode 100644 index 000000000..437e2bfdd --- /dev/null +++ b/solara/website/public/social/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/tests/integration/api_test.py b/tests/integration/api_test.py index 264ae17d1..3b3d68d8d 100644 --- a/tests/integration/api_test.py +++ b/tests/integration/api_test.py @@ -20,27 +20,27 @@ def test_api_markdown_editor(page_session: playwright.sync_api.Page, solara_server, solara_app): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/") + page_session.goto(solara_server.base_url + "/documentation/components/") page_session.locator("text=Markdown Editor").first.click() page_session.locator('h1:has-text("Large heading")').wait_for() def test_api_file_browser(page_session: playwright.sync_api.Page, solara_server, solara_app): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/") + page_session.goto(solara_server.base_url + "/documentation/components/") page_session.locator("text=File Browser").first.click() page_session.locator("text=You are in directory").wait_for() def test_api_matplotlib(page_session: playwright.sync_api.Page, solara_server, solara_app): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/matplotlib") + page_session.goto(solara_server.base_url + "/documentation/components/viz/matplotlib") page_session.locator("text=Arguments").first.wait_for() def test_api_style(page_session: playwright.sync_api.Page, solara_server, solara_app): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/style") + page_session.goto(solara_server.base_url + "/documentation/components/advanced/style") page_session.locator("text=Add a custom piece of CSS").first.wait_for() expect(page_session.locator(".mybutton")).to_have_css("color", "rgb(76, 175, 80)") @@ -55,7 +55,7 @@ def test_api_style(page_session: playwright.sync_api.Page, solara_server, solara def test_api_cross_filter_select(page_session: playwright.sync_api.Page, solara_server, solara_app): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/cross_filter_select") + page_session.goto(solara_server.base_url + "/documentation/api/cross_filter/cross_filter_select") page_session.locator("text=244").wait_for() select_sex = page_session.locator('_vue=v-autocomplete[label="Select values in sex having values:"]') select_sex.click() @@ -65,7 +65,7 @@ def test_api_cross_filter_select(page_session: playwright.sync_api.Page, solara_ def test_dataframe(page_session: playwright.sync_api.Page, solara_server, solara_app): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/dataframe") + page_session.goto(solara_server.base_url + "/documentation/components/data/dataframe") datatable_value_counts = page_session.locator(".solara-data-table").nth(1) datatable_value_counts.wait_for() diff --git a/tests/integration/enterprise/oauth_test.py b/tests/integration/enterprise/oauth_test.py index 0e95c19d5..c3def0d09 100644 --- a/tests/integration/enterprise/oauth_test.py +++ b/tests/integration/enterprise/oauth_test.py @@ -22,7 +22,7 @@ def test_oauth_from_app_auth0(page_session: playwright.sync_api.Page, solara_ser settings.oauth.client_secret = settings.AUTH0_TEST_CLIENT_SECRET settings.oauth.api_base_url = settings.AUTH0_TEST_API_BASE_URL settings.oauth.logout_path = settings.AUTH0_LOGOUT_PATH - page_session.goto(solara_server.base_url + "/examples/general/login_oauth") + page_session.goto(solara_server.base_url + "/documentation/examples/general/login_oauth") page_session.locator("_vue=v-btn >> text=Login").click() page_session.locator('css=input[name="username"]').fill(os.environ["AUTH0_USERNAME"]) page_session.locator('css=input[name="password"]').fill(os.environ["AUTH0_PASSWORD"]) @@ -46,7 +46,7 @@ def test_oauth_from_app_fief(page_session: playwright.sync_api.Page, solara_serv settings.oauth.client_secret = settings.FIEF_TEST_CLIENT_SECRET settings.oauth.api_base_url = settings.FIEF_TEST_API_BASE_URL settings.oauth.logout_path = settings.FIEF_LOGOUT_PATH - page_session.goto(solara_server.base_url + "/examples/general/login_oauth") + page_session.goto(solara_server.base_url + "/documentation/examples/general/login_oauth") page_session.locator("_vue=v-btn >> text=Login").click() page_session.locator('css=input[name="email"]').fill(os.environ["FIEF_USERNAME"]) page_session.locator('css=input[name="password"]').fill(os.environ["FIEF_PASSWORD"]) @@ -70,7 +70,7 @@ def test_oauth_private(page_session: playwright.sync_api.Page, solara_server, so assert response is not None assert response.status == 401 assert page_session.goto(solara_server.base_url + "/invalid_url").status == 401 - page_session.goto(solara_server.base_url + "/api/style") + page_session.goto(solara_server.base_url + "/documentation/components/advanced/style") page_session.locator('css=input[name="username"]').fill(os.environ["AUTH0_USERNAME"]) page_session.locator('css=input[name="password"]').fill(os.environ["AUTH0_PASSWORD"]) page_session.locator('css=button[name="action"]').nth(-1).click() @@ -78,7 +78,7 @@ def test_oauth_private(page_session: playwright.sync_api.Page, solara_server, so response = page_session.goto(solara_server.base_url + "/static/public/beach.jpeg") assert response is not None assert str(response.status)[0] == "2" # check 2xx - page_session.goto(get_logout_url("/api/style")) + page_session.goto(get_logout_url("/documentation/components/advanced/style")) page_session.locator('css=input[name="username"]').fill(os.environ["AUTH0_USERNAME"]) response = page_session.goto(solara_server.base_url + "/static/public/beach.jpeg?cache=off") assert response is not None diff --git a/tests/integration/file_download_test.py b/tests/integration/file_download_test.py index 5f7688b12..1631c7a61 100644 --- a/tests/integration/file_download_test.py +++ b/tests/integration/file_download_test.py @@ -7,7 +7,7 @@ def test_download(browser: playwright.sync_api.Browser, page_session: playwright.sync_api.Page, solara_server, solara_app, tmpdir: Path): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/file_download") + page_session.goto(solara_server.base_url + "/documentation/components/output/file_download") with page_session.expect_download() as download_info: page_session.locator('button:has-text("Download file")').click() target = tmpdir / "downloaded.txt" diff --git a/tests/integration/router_test.py b/tests/integration/router_test.py index 8fe9c3319..a27fa2d8b 100644 --- a/tests/integration/router_test.py +++ b/tests/integration/router_test.py @@ -7,8 +7,8 @@ def test_landing(page_session: playwright.sync_api.Page, solara_server, solara_a with solara_app("solara.website.pages"): page_session.goto(solara_server.base_url) page_session.locator("text=React-style web framework").wait_for() - page_session.locator("text=API").first.click() - page_session.locator("text=Matplotlib").first.wait_for() + page_session.get_by_role("link", name="Documentation").click() + page_session.locator("text=Search the Solara Documentation").first.wait_for() page_session.go_back() page_session.locator("text=React-style web framework").wait_for() @@ -16,7 +16,7 @@ def test_landing(page_session: playwright.sync_api.Page, solara_server, solara_a def test_docs_basics(page_session: playwright.sync_api.Page, solara_server, solara_app): # with screenshot_on_error(page, 'tmp/test_docs_basics.png'): with solara_app("solara.website.pages"): - page_session.goto(solara_server.base_url + "/api/use_route/fruit/banana") + page_session.goto(solara_server.base_url + "/documentation/api/routing/use_route/fruit/banana") page_session.locator("text=You chose banana").wait_for() page_session.locator('button:has-text("kiwi")').click() page_session.locator("text=You chose kiwi").wait_for() diff --git a/tests/integration/server_test.py b/tests/integration/server_test.py index 338a67b5e..8816287f1 100644 --- a/tests/integration/server_test.py +++ b/tests/integration/server_test.py @@ -23,16 +23,21 @@ def test_large_cookie(browser: playwright.sync_api.Browser, page_session: playwr def test_docs_basics(page_session: playwright.sync_api.Page, solara_server, solara_app): with solara_app("solara.website.pages"): page_session.goto(solara_server.base_url) - page_session.locator("text=Examples").first.click() + page_session.get_by_role("link", name="Documentation").click() + page_session.locator("text=Search the Solara Documentation").wait_for() + page_session.locator(".docs-card", has_text="Examples").first.click() page_session.locator("text=Calculator").first.click() page_session.locator("text=+/-").wait_for() page_session.screenshot(path="tmp/screenshot_calculator.png") + page_session.locator("text=Examples").first.click() + page_session.locator("text=Libraries").first.click() page_session.locator("text=Bqplot").first.click() page_session.locator("text=Exponent").wait_for() page_session.screenshot(path="tmp/screenshot_bqplot.png") + page_session.locator("text=Visualization").first.click() page_session.locator("text=Scatter plot using Plotly").first.click() page_session.locator("text=plotly express").first.wait_for() page_session.screenshot(path="tmp/screenshot_plotly.png") diff --git a/tests/unit/autorouting_test.py b/tests/unit/autorouting_test.py index ce1c88ba6..70d6fb532 100644 --- a/tests/unit/autorouting_test.py +++ b/tests/unit/autorouting_test.py @@ -6,9 +6,9 @@ import solara import solara.autorouting import solara.template.portal.solara_portal.pages -import solara.website.pages.api.button -import solara.website.pages.docs -import solara.website.pages.examples +import solara.website.pages.documentation +import solara.website.pages.documentation.components.input.button +import solara.website.pages.documentation.getting_started import solara.widgets from solara.components.title import TitleWidget from solara.server.app import AppScript @@ -89,7 +89,7 @@ def test_routes_portal(): def test_routes_examples_api_button(): - routes = solara.autorouting.generate_routes(solara.website.pages.api.button) + routes = solara.autorouting.generate_routes(solara.website.pages.documentation.components.input.button) assert len(routes) == 1 assert routes[0].path == "/" @@ -102,12 +102,12 @@ def test_routes_examples_api_button(): assert not rc._find(v.NavigationDrawer) -def test_routes_examples_docs(): - routes = solara.autorouting.generate_routes(solara.website.pages.docs) +def test_routes_examples_getting_started(): + routes = solara.autorouting.generate_routes(solara.website.pages.documentation.getting_started) - assert len(routes) == 16 + assert len(routes) == 9 assert routes[0].path == "/" - assert routes[0].label == "Introduction" + assert routes[0].label == "Quickstart" main_object = solara.autorouting.RenderPage() solara_context = solara.RoutingProvider(children=[main_object], routes=routes, pathname="/") diff --git a/tests/unit/solara_test_apps/multipage/01-home.py b/tests/unit/solara_test_apps/multipage/01-home.py index 8fcbb3c5c..4b2de62a5 100644 --- a/tests/unit/solara_test_apps/multipage/01-home.py +++ b/tests/unit/solara_test_apps/multipage/01-home.py @@ -1,3 +1,3 @@ -import solara.website.pages.api.button as mod +import solara.website.pages.documentation.components.input.button as mod Page = mod.Page diff --git a/tests/unit/solara_test_apps/multipage/02-my_fruit.py b/tests/unit/solara_test_apps/multipage/02-my_fruit.py index 56bb5b4eb..96af33ead 100644 --- a/tests/unit/solara_test_apps/multipage/02-my_fruit.py +++ b/tests/unit/solara_test_apps/multipage/02-my_fruit.py @@ -1,4 +1,4 @@ -import solara.website.pages.api.use_route as mod +import solara.website.pages.documentation.api.routing.use_route as mod routes = mod.routes Page = mod.Page diff --git a/tests/unit/solara_test_apps/multipage/04-a_directory/01-not-an-app.py b/tests/unit/solara_test_apps/multipage/04-a_directory/01-not-an-app.py index d26049f6c..c02e10ed4 100644 --- a/tests/unit/solara_test_apps/multipage/04-a_directory/01-not-an-app.py +++ b/tests/unit/solara_test_apps/multipage/04-a_directory/01-not-an-app.py @@ -1,3 +1,3 @@ -import solara.website.pages.api.griddraggable as mod +import solara.website.pages.documentation.components.layout.griddraggable as mod Page = mod.Page