Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Align JSON and CodeEditor default theme with overall theme #7406

Merged
merged 8 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/reference/panes/JSON.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"* **``depth``** (int): Depth to which the JSON structure is expanded on initialization (`depth=-1` indicates full expansion)\n",
"* **``hover_preview``** (bool): Whether to enable hover preview for collapsed nodes \n",
"* **``object``** (str or object): JSON string or JSON serializable object\n",
"* **``theme``** (string): The color scheme, one of 'light' or 'dark'\n",
"* **``theme``** (string): If no value is provided, it defaults to the current theme set by pn.config.theme, as specified in the JSON.THEME_CONFIGURATION dictionary. If not defined there, it falls back to the default parameter value ('light').\n",
"\n",
"___"
]
Expand Down
2 changes: 1 addition & 1 deletion examples/reference/widgets/CodeEditor.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"* **``language``** (str): A string declaring which language to use for code syntax highlighting (default: 'text')\n",
"* **``on_keyup``** (bool): Whether to update the value on every key press or only upon loss of focus / hotkeys.\n",
"* **``print_margin``** (boolean): Whether to show a print margin in the editor\n",
"* **``theme``** (str): theme of the editor (default: 'chrome')\n",
"* **``theme``** (str): If no value is provided, it defaults to the current theme set by pn.config.theme, as specified in the CodeEditor.THEME_CONFIGURATION dictionary. If not defined there, it falls back to the default parameter value ('chrome').\n",
"* **``readonly``** (boolean): Whether the editor should be opened in read-only mode\n",
"* **``value``** (str): State of the current code in the editor if `on_keyup`. Otherwise, only upon loss of focus, i.e. clicking outside the editor, or pressing <Ctrl+Enter> or <Cmd+Enter>.\n",
"* **``value_input``** (str): State of the current code updated on every key press. Identical to `value` if `on_keyup`.\n",
Expand Down
21 changes: 17 additions & 4 deletions panel/pane/markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import param # type: ignore

from ..config import config
from ..io.resources import CDN_DIST
from ..models.markup import HTML as _BkHTML, JSON as _BkJSON, HTMLStreamEvent
from ..util import HTML_SANITIZER, escape, prefix_length
Expand Down Expand Up @@ -482,8 +483,6 @@ def _process_param_change(self, params):
params['css_classes'] = ['markdown'] + params['css_classes']
return super()._process_param_change(params)



class JSON(HTMLBasePane):
"""
The `JSON` pane allows rendering arbitrary JSON strings, dicts and other
Expand All @@ -505,8 +504,11 @@ class JSON(HTMLBasePane):
hover_preview = param.Boolean(default=False, doc="""
Whether to display a hover preview for collapsed nodes.""")

theme = param.ObjectSelector(default="dark", objects=["light", "dark"], doc="""
Whether the JSON tree view is expanded by default.""")
theme = param.ObjectSelector(default="light", objects=["light", "dark"], doc="""
If no value is provided, it defaults to the current theme
set by pn.config.theme, as specified in the
JSON.THEME_CONFIGURATION dictionary. If not defined there, it
falls back to the default parameter value.""")

priority: ClassVar[float | bool | None] = None

Expand All @@ -526,6 +528,13 @@ class JSON(HTMLBasePane):
f'{CDN_DIST}css/json.css'
]

THEME_CONFIGURATION: ClassVar[dict[str,str]] = {"default": "light", "dark": "dark"}

def __init__(self, object=None, **params):
if "theme" not in params:
params["theme"]=self._get_theme(config.theme)
super().__init__(object=object, **params)

@classmethod
def applies(cls, obj: Any, **params) -> float | bool | None:
if isinstance(obj, (list, dict)):
Expand Down Expand Up @@ -559,3 +568,7 @@ def _process_param_change(self, params: dict[str, Any]) -> dict[str, Any] :
if 'depth' in params:
params['depth'] = None if params['depth'] < 0 else params['depth']
return params

@classmethod
def _get_theme(cls, config_theme: str)->str:
return cls.THEME_CONFIGURATION.get(config_theme, cls.param.theme.default)
19 changes: 19 additions & 0 deletions panel/tests/pane/test_markup.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import base64
import json
import sys

from unittest.mock import patch

import numpy as np
import pandas as pd
import pytest

from panel import config
from panel.pane import (
HTML, JSON, DataFrame, Markdown, PaneBase, Str,
)
Expand Down Expand Up @@ -314,3 +319,17 @@ def test_json_pane_rerenders_on_depth_change(document, comm):
pane.depth = -1

assert model.depth is None

@pytest.mark.skipif(sys.version_info < (3, 11), reason="Patch dot import resolution does not work for Python <=3.10")
def test_json_theme():
assert JSON({"x": 1}).theme == JSON.param.theme.default
assert JSON({"x": 1}, theme="dark").theme == "dark"

with patch('panel.config._config.theme', new_callable=lambda: "default"):
assert JSON({"x": 1}).theme == JSON.param.theme.default

with patch('panel.config._config.theme', new_callable=lambda: "dark"):
assert JSON({"x": 1}).theme == JSON.THEME_CONFIGURATION[config.theme]

with patch('panel.config._config.theme', new_callable=lambda: "dark"):
assert JSON({"x": 1}, theme="light").theme == "light"
21 changes: 21 additions & 0 deletions panel/tests/widgets/test_codeeditor.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import sys

from unittest.mock import patch

import pytest

from panel import config
from panel.widgets import CodeEditor


Expand All @@ -23,3 +30,17 @@ def test_ace_input(document, comm):
editor.value = ""
assert editor.value == ""
assert editor.value_input == ""

@pytest.mark.skipif(sys.version_info < (3, 11), reason="Patch dot import resolution does not work for Python <=3.10")
def test_code_editor_theme():
assert CodeEditor(value="My theme is appropriate").theme == CodeEditor.param.theme.default
assert CodeEditor(value="My theme is appropriate", theme="dracula").theme == "dracula"

with patch('panel.config._config.theme', new_callable=lambda: "default"):
assert CodeEditor(value="My theme is appropriate").theme == CodeEditor.param.theme.default

with patch('panel.config._config.theme', new_callable=lambda: "dark"):
assert CodeEditor(value="My theme is appropriate").theme == CodeEditor.THEME_CONFIGURATION[config.theme]

with patch('panel.config._config.theme', new_callable=lambda: "dark"):
assert CodeEditor(value="My theme is appropriate", theme="chrome").theme == "chrome"
15 changes: 13 additions & 2 deletions panel/widgets/codeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from pyviz_comms import JupyterComm

from ..config import config
from ..models.enums import ace_themes
from ..util import lazy_load
from .base import Widget
Expand All @@ -20,7 +21,6 @@
from bokeh.model import Model
from pyviz_comms import Comm


class CodeEditor(Widget):
"""
The CodeEditor widget allows displaying and editing code in the
Expand Down Expand Up @@ -50,7 +50,10 @@ class CodeEditor(Widget):
Define if editor content can be modified. Alias for disabled.""")

theme = param.ObjectSelector(default="chrome", objects=list(ace_themes),
doc="Theme of the editor")
doc="""If no value is provided, it defaults to the current theme
set by pn.config.theme, as specified in the
CodeEditor.THEME_CONFIGURATION dictionary. If not defined there, it
falls back to the default parameter value.""")

value = param.String(default="", doc="""
State of the current code in the editor if `on_keyup`. Otherwise, only upon loss of focus,
Expand All @@ -61,11 +64,15 @@ class CodeEditor(Widget):

_rename: ClassVar[Mapping[str, str | None]] = {"value": "code", "value_input": "code_input", "name": None}

THEME_CONFIGURATION: ClassVar[dict[str,str]] = {"dark": "chaos"}

def __init__(self, **params):
if 'readonly' in params:
params['disabled'] = params['readonly']
elif 'disabled' in params:
params['readonly'] = params['disabled']
if "theme" not in params:
params["theme"]=self._get_theme(config.theme)
super().__init__(**params)
self._internal_callbacks.append(
self.param.watch(self._update_disabled, ['disabled', 'readonly'])
Expand Down Expand Up @@ -93,3 +100,7 @@ def _update_disabled(self, *events: param.parameterized.Event):
self.readonly = event.new
elif event.name == 'readonly':
self.disabled = event.new

@classmethod
def _get_theme(cls, config_theme: str)->str:
return cls.THEME_CONFIGURATION.get(config_theme, cls.param.theme.default)
Loading