From daf4bef8334d4fa44a2ad6b8d0b74990d502bb52 Mon Sep 17 00:00:00 2001 From: Tim Monko Date: Wed, 22 Apr 2026 15:03:40 -0500 Subject: [PATCH 1/5] fix migration guide syntax --- docs/plugins/advanced_topics/npe2_migration_guide.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/plugins/advanced_topics/npe2_migration_guide.md b/docs/plugins/advanced_topics/npe2_migration_guide.md index 982e52059..cca119ea0 100644 --- a/docs/plugins/advanced_topics/npe2_migration_guide.md +++ b/docs/plugins/advanced_topics/npe2_migration_guide.md @@ -413,7 +413,9 @@ def get_new_theme() -> Dict[str, Dict[str, Union[str, Tuple, List]]: return themes ``` -becomes this theme contribution in the plugin manifest: +becomes this theme contribution in the plugin manifest. Note that `type` +selects the base light/dark theme, omitted color keys inherit from that base, +and `syntax_style` stays at the top level rather than under `colors`: ```yaml name: my-plugin @@ -422,6 +424,7 @@ contributions: - label: Super dark id: super_dark type: dark + syntax_style: "native" colors: background: "rgb(12, 12, 12)" foreground: "rgb(65, 72, 81)" @@ -432,7 +435,6 @@ contributions: icon: "rgb(209, 210, 212)" warning: "rgb(153, 18, 31)" current: "rgb(0, 122, 204)" - syntax_style: "native" console: "rgb(0, 0, 0)" canvas: "black" ``` From afeabfddb3863b872c5d1be633ea5e1c7a805aac Mon Sep 17 00:00:00 2001 From: Tim Monko Date: Fri, 24 Apr 2026 15:37:38 -0500 Subject: [PATCH 2/5] update viewer guide theme quip --- docs/getting_started/viewer.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/getting_started/viewer.md b/docs/getting_started/viewer.md index 2cdb04daf..b0b2cd549 100644 --- a/docs/getting_started/viewer.md +++ b/docs/getting_started/viewer.md @@ -714,7 +714,11 @@ viewer.theme = 'dark' You can also change the theme using the "Toggle theme" keyboard shortcut, by default {kbd}`Command/Control+Shift+T`. Note that changing the theme using this shortcut will only change the *current* viewer theme. If you wish to make the change permanent for all viewers, make sure to also change your settings in the **Appearance** tab of the [**Preferences** dialog](napari-preferences). -Adding your own custom theme isn't too hard but it requires creating your own color `palette` and rebuilding the icons. It's also possible for [plugins to contribute a theme](contributions-themes). If people want more themes, we're happy to add them or you can look at our [contributing guidelines](napari-contributing) for more information about building the icons and add one yourself! +Custom themes can be prototyped directly in Python or distributed declaratively +from a plugin. +[Plugins can contribute a theme](contributions-themes) by declaring a light or +dark base theme and overriding only the colors they need. See +[Creating and testing themes](napari-themes) for both workflows. +++ From 387ea5d117e52743d17455bf699616a64a936e22 Mon Sep 17 00:00:00 2001 From: Tim Monko Date: Fri, 24 Apr 2026 15:38:08 -0500 Subject: [PATCH 3/5] simplify themes page and use theme sample example --- docs/howtos/themes.md | 55 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/docs/howtos/themes.md b/docs/howtos/themes.md index b2548ad9f..582603dc1 100644 --- a/docs/howtos/themes.md +++ b/docs/howtos/themes.md @@ -2,43 +2,42 @@ # Creating and testing themes -A theme is a set of colors used throughout napari. See, for example, the -builtin themes in `napari/utils/theme.py`. To make a new theme, create a new -`dict` with the same keys as one of the existing themes, and -replace the values with your new colors. For example +A napari theme is a named collection of colors and style values used across the +viewer canvas, widgets, icons, and console. If you want to programmatically +prototype a theme, check out the {ref}`shpx_glr_gallery_new_theme.py` example. +However, the `npe2` theme contribution allows declaratively +defining themes and enables easy distribution to others. -```python -from napari.utils.theme import get_theme, register_theme +If you want other people to install and reuse your theme, prefer the plugin +workflow. The programmatic workflow is still useful for local experiments and +rapid iteration. +(preview-themes)= +## Preview themes in a full napari UI -blue_theme = get_theme('dark') -blue_theme.update( - background='rgb(28, 31, 48)', - foreground='rgb(45, 52, 71)', - primary='rgb(80, 88, 108)', - current='rgb(184, 112, 0)', -) +The most complete theme preview tool lives in the example gallery as +{ref}`sphx_glr_gallery_theme_sample.py`. It opens napari with a dock widget +that shows the theme color roles, common widget states, and a theme selector +that includes plugin-contributed themes after plugins are initialized. -register_theme('blue', blue_theme) -``` +You can download the python script from the example page and drag'n'drop it onto napari to run it. -To test out the theme, use the -`qt_theme_sample.py` file from the command line as follows: +If you are working from a local checkout of `napari/napari`, you can run it +directly: ```sh -python -m napari._qt.widgets.qt_theme_sample +python examples/theme_sample.py ``` -*note*: you may specify a theme with one additional argument on the command line: - -```sh -python -m napari._qt.widgets.qt_theme_sample dark -``` +## Ship a theme in a plugin -(providing no arguments will show all themes in `theme.py`) +The supported way to distribute a theme is via a [plugin](plugins-index) +[theme contribution](contributions-themes). A theme contribution uses the plugin manifest +(`napari.yaml`) to declaratively define properties of a theme. -## Sharing your theme via a plugin +After the plugin is installed, the contributed theme becomes available in +napari's appearance settings and can also be selected with `viewer.theme`. +For richer visual testing, use the [theme preview sample](preview-themes). -You can also share your theme with the community via a [plugin](plugins-index) -by adding a [theme contribution](contributions-themes). See the -[plugin](plugins-index) documentation for details on creating a plugin. +If you are contributing a builtin theme to napari itself rather than shipping a +plugin, see the core theme definitions in `napari/utils/theme.py`. From e3f04385bbf3713aa682732351d6aa718fcf439b Mon Sep 17 00:00:00 2001 From: Tim Monko Date: Thu, 21 May 2026 17:36:45 -0500 Subject: [PATCH 4/5] Apply suggestion from @brisvag Co-authored-by: Lorenzo Gaifas --- docs/plugins/advanced_topics/npe2_migration_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/advanced_topics/npe2_migration_guide.md b/docs/plugins/advanced_topics/npe2_migration_guide.md index cca119ea0..5f7de50a9 100644 --- a/docs/plugins/advanced_topics/npe2_migration_guide.md +++ b/docs/plugins/advanced_topics/npe2_migration_guide.md @@ -414,7 +414,7 @@ def get_new_theme() -> Dict[str, Dict[str, Union[str, Tuple, List]]: ``` becomes this theme contribution in the plugin manifest. Note that `type` -selects the base light/dark theme, omitted color keys inherit from that base, +indicates whether the theme is light or dark, omitted color keys inherit from that base, and `syntax_style` stays at the top level rather than under `colors`: ```yaml From 68305d4a10d6ed7cfb4f92fd413addf437f92f22 Mon Sep 17 00:00:00 2001 From: Tim Monko Date: Thu, 21 May 2026 17:45:13 -0500 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com> --- docs/howtos/themes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/howtos/themes.md b/docs/howtos/themes.md index 582603dc1..2642aa5cc 100644 --- a/docs/howtos/themes.md +++ b/docs/howtos/themes.md @@ -4,9 +4,9 @@ A napari theme is a named collection of colors and style values used across the viewer canvas, widgets, icons, and console. If you want to programmatically -prototype a theme, check out the {ref}`shpx_glr_gallery_new_theme.py` example. +prototype a theme, check out the {ref}`sphx_glr_gallery_new_theme.py` example. However, the `npe2` theme contribution allows declaratively -defining themes and enables easy distribution to others. +defining themes and enables easy distribution to others via plugins. If you want other people to install and reuse your theme, prefer the plugin workflow. The programmatic workflow is still useful for local experiments and