diff --git a/skills/panel-material-ui/SKILL.md b/skills/panel-material-ui/SKILL.md index 5b85d18..f60c8cc 100644 --- a/skills/panel-material-ui/SKILL.md +++ b/skills/panel-material-ui/SKILL.md @@ -87,7 +87,6 @@ class HelloWorld(pn.viewable.Viewer): self._outputs = pmui.Column(self.model) self._panel = pmui.Row(self._inputs, self._outputs) - # DO use caching to speed up bound methods that are expensive to compute or load data and return the same result for a given state of the class. @pn.cache # DO prefer .depends over .bind over .rx for reactivity methods on Parameterized classes as it can be typed and documented @@ -164,7 +163,81 @@ def test_characters_reactivity(): - DO use Material UI `sx` parameter for all css styling over `styles` and `stylesheets` - DO use panel-material-ui components instead of panel components for projects already using panel-material-ui and for new projects - DON'T configure the `design`, i.e. DO NOT `pn.extension(design='material')`. -- DO prefer professional Material UI icons over emojies +- DO prefer professional Material UI icons over emojis + +## Theming and Styling + +Panel Material UI supports four styling layers: + +- **`theme_config`**: App-wide theme for palette, typography, shape, and defaults. Prefer this for consistent styling across a page or app. +- **`sx`**: Local Material UI styling for a specific component, including nested Mui selectors and dark/light mode overrides. +- **`styles`**: Styles the outer Panel container, useful for spacing, borders, backgrounds, and shadows around a component. +- **`stylesheets`**: Custom CSS selectors for classic Panel internals. Use sparingly. + +**Recommended order of use:** prefer `theme_config` for global consistency, use `sx` for local component-level exceptions, use `styles` for outer container layout/styling, and reserve `stylesheets` for cases not covered by the other options. + +### `sx` + +- DO use `sx` for one-off component styling and nested Mui element overrides. +- DO use selectors like `& .MuiSlider-thumb` to target internal Material UI parts when needed. +- DO use `.mui-dark` and `.mui-light` selectors for mode-specific local styling. +- DON'T rely heavily on nested Mui class names unless necessary, as they may change across versions. + +### `theme_config` + +- DO use `theme_config` for app-wide palette, typography, shape, and component defaults. +* DO define `theme_config` at a top-level container such as `Page`, `Row`, `Column`, or `Card` so it inherits to children. +* DO use `"light"` and `"dark"` keys when separate light and dark themes are needed. +* DO prefer `theme_config` over repeated `sx` values when the same visual language should apply across the app. + +### `styles` + +* DO use `styles` for the outer wrapper box only. +* DO use it for spacing, borders, backgrounds, border radius, and shadows around a component. +* DON'T use `styles` when you actually want to style the internal Mui control; use `sx` instead. + +### Styling Guidance + +* DO use `sizing_mode` for layout behavior before reaching for CSS sizing in `sx`. +* DO use `sx` for Material UI component internals. +* DO use `theme_config` for consistency and maintainability. +* DO use `styles` only for wrapper-level styling. +* DO use `stylesheets` only when `sx`, `theme_config`, and `styles` are insufficient. + +### Example Pattern + +```python +app_theme = { + "light": { + "palette": {"primary": {"main": "#6a1b9a"}}, + "shape": {"borderRadius": 12}, + }, + "dark": { + "palette": {"primary": {"main": "#9575cd"}}, + "shape": {"borderRadius": 12}, + }, +} + +button_sx = { + "fontWeight": 700, + "&:hover": {"transform": "scale(1.02)"}, +} + +container_styles = { + "padding": "8px", + "background": "rgba(0,0,0,0.02)", +} + +pmui.Page( + main=[ + pmui.Paper( + pmui.Button("Submit", color="primary", sx=button_sx), + styles=container_styles, + ) + ], + theme_config=app_theme, +) +``` ## Component Instructions @@ -198,34 +271,6 @@ pmui.Page( ) ``` -#### Linking Dashboard Theme with Page Theme - -DO synchronize component themes with Page theme: - -```python - ... - - dark_theme = param.Boolean( - doc="""True if the theme is dark""", - # To enable providing parameters and bound function references - allow_refs=True - ) - - @classmethod - def create_app(cls, **params): - """Create app with synchronized theming.""" - component = cls(**params) - - page = pmui.Page( - ..., - dark_theme=component.dark_theme, # Pass theme to Page - ) - - # Synchronize Page theme to component theme - component.dark_theme = page.param.dark_theme - return page -``` - ### Grid - DO set `spacing=2` or higher to separate sub components in the grid. @@ -278,6 +323,7 @@ pmui.Paper.param.margin.default=10 ### Non-Existing Components - Do use `Column` instead of `Box`. The `Box` component does not exist. +- Do use `TextInput` instead of `TextField`. The `TextField` component does not exist. ## Material UI Examples @@ -295,6 +341,20 @@ pmui.Typography( pmui.IconButton(icon=icon, disabled=True, ...) ``` +### Icons in widget labels and options + +DO embed icons directly in widget labels and options using the `:material/...:` token syntax: + +``` +pmui.Select( + label="Mode", + options=[ + "Zoom :material/zoom:", + "Explore :material/explore@size=large,color=warning:", + ], +) +``` + ### Static Components Pattern (Material UI) ```python @@ -304,7 +364,7 @@ import param pn.extension() -pmui.Paper.param.margin.default=10 +pmui.Paper.param.margin.default = 10 class HelloWorld(pn.viewable.Viewer): characters = param.Integer(default=10, bounds=(1, 100), doc="Number of characters to display") @@ -350,4 +410,4 @@ if pn.state.served: HelloWorld().servable() ``` -**For all other Panel patterns (parameter-driven architecture, reactive updates, serving, etc.), refer tot the 'panel' skill.** +**For all other Panel patterns (parameter-driven architecture, reactive updates, serving, etc.), refer to the 'panel' skill.** diff --git a/skills/panel/SKILL.md b/skills/panel/SKILL.md index 7756d9c..747847c 100644 --- a/skills/panel/SKILL.md +++ b/skills/panel/SKILL.md @@ -23,30 +23,30 @@ Core dependencies provided with the `panel` Python package: Optional panel-extensions: -- **panel-material-ui**: Modern Material UI components. To replace the panel native widgets within the next two years. +- **panel-material-ui**: Modern Material UI components. Will replace the panel native widgets within the next two years. - **panel-graphic-walker**: Modern Tableau like interface. Can offload computations to the server and thus scale to large datasets. -Optional dependencies from the HoloViz Ecosystem: +Optional HoloViz ecosystem dependencies: -- **colorcet**: Perceptually uniform colormaps collection. Best for: scientific visualization requiring accurate color representation, avoiding rainbow colormaps, accessible color schemes. Integrates with hvPlot, HoloViews, Matplotlib, Bokeh. -- **datashader**: Renders large datasets (millions+ points) into images for visualization. Best for: big data visualization, geospatial datasets, scatter plots with millions of points, heatmaps of dense data. Requires hvPlot or HoloViews as frontend. -- **geoviews**: Geographic data visualization with map projections and tile sources. Best for: geographic/geospatial plots, map-based dashboards, when you need coordinate systems and projections. Built on HoloViews, works seamlessly with hvPlot. -- **holoviews**: Declarative data visualization library with composable elements. Best for: complex multi-layered plots, advanced interactivity (linked brushing, selection), when you need fine control over plot composition, scientific visualizations. More powerful but steeper learning curve than hvPlot. -- **holoviz-mcp**: Model Context Protocol server for HoloViz ecosystem. Provides access to detailed documentation, component search and agent skills. -- **hvplot**: High-level plotting API with Pandas `.plot()`-like syntax. Best for: quick exploratory visualizations, interactive plots from DataFrames/Xarray, when you want interactivity without verbose code. Built on HoloViews. -- **hvsampledata**: Shared datasets for the HoloViz projects. +* **hvPlot**: High-level interactive plotting for DataFrames and arrays. +* **HoloViews**: Composable, declarative visualizations for more advanced interactivity and plot composition. +* **Datashader**: Scalable rendering for very large datasets. +* **GeoViews**: Geospatial plotting with projections and map tiles. +* **colorcet**: Perceptually uniform, accessible colormaps. +* **holoviz-mcp**: Documentation, component search, and skill lookup tools for the HoloViz ecosystem. +* **hvsampledata**: Shared example datasets for HoloViz projects. -Optional dependencies from the wider PyData Ecosystem: +Optional wider PyData dependencies: -- **altair**: Declarative, grammar-of-graphics visualization library. Best for: statistical visualizations, interactive exploratory charts, when you need Vega-Lite's extensive chart gallery. Works well with Pandas/Polars DataFrames. -- **dask**: Parallel computing library for scaling Pandas DataFrames beyond memory. Best for: processing datasets larger than RAM, parallel computation across multiple cores/machines, lazy evaluation workflows. -- **duckdb**: High-performance analytical SQL database. Best for: fast SQL queries on DataFrames, aggregations on large datasets, when you need SQL interface, OLAP-style analytics. Much faster than Pandas for analytical queries. -- **matplotlib**: Low-level, highly customizable plotting library. Best for: publication-quality static plots, fine-grained control over every aspect of visualization, scientific plots, when you need pixel-perfect control. -- **pandas**: Industry-standard DataFrame library for tabular data. Best for: data cleaning, transformation, time series analysis, datasets that fit in memory. The default choice for most data work. -- **Plotly**: Interactive, publication-quality visualization library. Best for: 3D plots, complex interactive charts, animations, when you need hover tooltips and interactivity. Works well with Dash and Panel. -- **polars**: Modern, fast DataFrame library written in Rust. Best for: high-performance data processing, datasets that fit in memory but need speed, when you need lazy evaluation, better memory efficiency than Pandas. -- **xarray**: N-dimensional labeled arrays and datasets. Best for: multidimensional scientific data (climate, satellite imagery), data with multiple dimensions and coordinates, NetCDF/HDF5 files, geospatial raster data. -- **watchfiles**: Enables high performance file watching and autoreload for the panel server. +* **pandas**: Standard tabular data processing. +* **polars**: Faster, memory-efficient DataFrame processing. +* **duckdb**: Fast analytical SQL over local data and DataFrames. +* **dask**: Parallel and out-of-core computation for larger-than-memory workloads. +* **xarray**: Labeled N-dimensional arrays for scientific data. +* **Altair**: Declarative statistical visualization with Vega-Lite. +* **Plotly**: Rich interactive charts, including 3D and animation. +* **matplotlib**: Fine-grained static plotting. +* **watchfiles**: Fast file watching and autoreload for Panel development. ## Common Use Cases @@ -222,7 +222,7 @@ DO fix any errors identified. - DO use `param.Parameterized` or `pn.viewable.Viewer` classes to organize and manage state - DO create widgets with `.from_param()` method. DON'T do this for panes, i.e. pn.pane.Str has no from_param method. - DO use `@param.depends()` for reactive methods -- DO use `@param.depends(..., watch=True)` to update parameter/ state values and for side-effects like sending an email. +- DO use `@param.depends(..., watch=True)` to update parameter/ state values and for side-effects like logging. - DO group related parameters in separate `Parameterized` or `Viewable` classes ```python @@ -393,6 +393,7 @@ if __name__ == "__main__": - **Defer load**: Defer load to after the app is shown to the user: `pn.extension(defer_load=True, loading_indicator=True, ...)` - **Lazy-load components** using Tabs or Accordion for heavy content - **Use caching** with `@pn.cache` decorator for expensive computations +- **Batch Updates** with `pn.io.hold()` as a decorator or context manager when updating multiple components at once. - **Use async/await**: Implement asynchronous patterns for I/O operations - **Use faster frameworks**: Replace slower Pandas with faster Polars or DuckDB - **Offload to threads**: Consider using threading for CPU-intensive tasks @@ -524,11 +525,11 @@ def kpi_value(self): ### Markdown -- DO set `Markdown.disable_anchors=True` to avoid page flickr when hovering over headers. +- DO set `Markdown.disable_anchors=True` to avoid page flicker when hovering over headers. ### Bind -- DON't bind a function to nothing: `pn.bind(some_func)`. Just run the function instead `some_func()`. +- DON'T bind a function to nothing: `pn.bind(some_func)`. Just run the function instead `some_func()`. ## Plotting