Source code for panel.theme.fast

from __future__ import annotations

import pathlib

import param

from bokeh.themes import Theme as _BkTheme

from ..config import config
from ..io.resources import CDN_DIST
from ..layout import Accordion
from ..reactive import ReactiveHTML
from ..viewable import Viewable
from ..widgets import Tabulator
from ..widgets.indicators import Dial, Number, String
from .base import (
    DarkTheme, DefaultTheme, Design, Inherit,
)

COLLAPSED_SVG_ICON = """
<svg style="stroke: var(--accent-fill-rest);" width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" slot="collapsed-icon">
  <path d="M15.2222 1H2.77778C1.79594 1 1 1.79594 1 2.77778V15.2222C1 16.2041 1.79594 17 2.77778 17H15.2222C16.2041 17 17 16.2041 17 15.2222V2.77778C17 1.79594 16.2041 1 15.2222 1Z" stroke-linecap="round" stroke-linejoin="round"></path>
  <path d="M9 5.44446V12.5556" stroke-linecap="round" stroke-linejoin="round"></path>
  <path d="M5.44446 9H12.5556" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
""" # noqa

EXPANDED_SVG_ICON = """
<svg style="stroke: var(--accent-fill-rest);" width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" slot="expanded-icon">
  <path d="M15.2222 1H2.77778C1.79594 1 1 1.79594 1 2.77778V15.2222C1 16.2041 1.79594 17 2.77778 17H15.2222C16.2041 17 17 16.2041 17 15.2222V2.77778C17 1.79594 16.2041 1 15.2222 1Z" stroke-linecap="round" stroke-linejoin="round"></path>
  <path d="M5.44446 9H12.5556" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
""" # noqa

FONT_URL = "//fonts.googleapis.com/css?family=Open+Sans"


[docs]class FastStyle(param.Parameterized): """ The FastStyle class provides the different colors and icons used to style the Fast Templates. """ background_color = param.String(default="#ffffff") neutral_color = param.String(default="#000000") accent_base_color = param.String(default="#0072B5") collapsed_icon = param.String(default=COLLAPSED_SVG_ICON) expanded_icon = param.String(default=EXPANDED_SVG_ICON) color = param.String(default="#2B2B2B") neutral_fill_card_rest = param.String(default="#F7F7F7") neutral_focus = param.String(default="#888888") neutral_foreground_rest = param.String(default="#2B2B2B") header_background = param.String(default="#0072B5") header_neutral_color = param.String(default="#ffffff") header_accent_base_color = param.String(default="#ffffff") header_color = param.String(default="#ffffff") font = param.String(default="Open Sans, sans-serif") font_url = param.String(default=FONT_URL) corner_radius = param.Integer(default=3) shadow = param.Boolean(default=True) luminance = param.Magnitude(default=1.0)
[docs] def create_bokeh_theme(self): """Returns a custom bokeh theme based on the style parameters Returns: Dict: A Bokeh Theme """ return { "attrs": { "figure": { "background_fill_color": self.background_color, "border_fill_color": self.neutral_fill_card_rest, "border_fill_alpha": 0, "outline_line_color": self.neutral_focus, "outline_line_alpha": 0.5, "outline_line_width": 1, }, "Grid": {"grid_line_color": self.neutral_focus, "grid_line_alpha": 0.25}, "Axis": { "major_tick_line_alpha": 0.5, "major_tick_line_color": self.neutral_foreground_rest, "minor_tick_line_alpha": 0.25, "minor_tick_line_color": self.neutral_foreground_rest, "axis_line_alpha": 0.1, "axis_line_color": self.neutral_foreground_rest, "major_label_text_color": self.neutral_foreground_rest, "major_label_text_font": self.font, "major_label_text_font_size": "1.025em", "axis_label_standoff": 10, "axis_label_text_color": self.neutral_foreground_rest, "axis_label_text_font": self.font, "axis_label_text_font_size": "1.25em", "axis_label_text_font_style": "normal", }, "Legend": { "spacing": 8, "glyph_width": 15, "label_standoff": 8, "label_text_color": self.neutral_foreground_rest, "label_text_font": self.font, "label_text_font_size": "1.025em", "border_line_alpha": 0.5, "border_line_color": self.neutral_focus, "background_fill_alpha": 0.25, "background_fill_color": self.neutral_fill_card_rest, }, "ColorBar": { "background_fill_color": self.background_color, "title_text_color": self.neutral_foreground_rest, "title_text_font": self.font, "title_text_font_size": "1.025em", "title_text_font_style": "normal", "major_label_text_color": self.neutral_foreground_rest, "major_label_text_font": self.font, "major_label_text_font_size": "1.025em", "major_tick_line_alpha": 0, "bar_line_alpha": 0, }, "Title": { "text_color": self.neutral_foreground_rest, "text_font": self.font, "text_font_size": "1.15em", }, } }
[docs]class FastWrapper(ReactiveHTML): """ Wraps any Panel component and initializes the Fast design provider. Wrapping a component in this way ensures that so that any children using the Fast design system have access to the Fast CSS variables. """ object = param.ClassSelector(class_=Viewable) style = param.ClassSelector(class_=FastStyle) _template = '<div id="fast-wrapper" class="fast-wrapper">${object}</div>' _scripts = { 'render': """ let accent, bg, luminance if (window._JUPYTERLAB) { accent = getComputedStyle(document.body).getPropertyValue('--jp-brand-color0').trim(); bg = getComputedStyle(document.body).getPropertyValue('--jp-layout-color0').trim(); let color = getComputedStyle(document.body).getPropertyValue('--jp-ui-font-color0').trim(); luminance = color == 'rgba(255, 255, 255, 1)' ? 0.23 : 1.0; } else { accent = data.style.accent_base_color; bg = data.style.background_color; luminance = data.style.luminance; } bg = bg === 'white' ? '#ffffff' : bg; bg = bg === 'black' ? '#000000' : bg; state.design = design = new window.fastDesignProvider(view.el) design.setLuminance(luminance); design.setNeutralColor(data.style.neutral_color); design.setAccentColor(accent); design.setBackgroundColor(bg); design.setCornerRadius(data.style.corner_radius); """ }
DEFAULT_STYLE = FastStyle() DARK_STYLE = FastStyle( background_color="#181818", #242424 color="#ffffff", header_color="#ffffff", luminance=0.1, neutral_fill_card_rest="#212121", neutral_focus="#717171", neutral_foreground_rest="#e5e5e5", shadow = False, )
[docs]class FastThemeMixin(param.Parameterized): css = param.Filename(default=pathlib.Path(__file__).parent / 'css' / 'fast_variables.css')
[docs]class FastDefaultTheme(DefaultTheme): style = param.ClassSelector(default=DEFAULT_STYLE, class_=FastStyle) __abstract = True @property def bokeh_theme(self): return _BkTheme(json=self.style.create_bokeh_theme())
[docs]class FastDarkTheme(DarkTheme): style = param.ClassSelector(default=DARK_STYLE, class_=FastStyle) modifiers = { Dial: { 'label_color': 'white' }, Number: { 'default_color': 'var(--neutral-foreground-rest)' }, String: { 'default_color': 'var(--neutral-foreground-rest)' } } __abstract = True @property def bokeh_theme(self): return _BkTheme(json=self.style.create_bokeh_theme())
[docs]class Fast(Design): modifiers = { Accordion: { 'active_header_background': 'var(--neutral-fill-active)' }, Tabulator: { 'theme': 'fast' }, Viewable: { 'stylesheets': [Inherit, f'{CDN_DIST}bundled/theme/fast.css'] } } _resources = { 'font': { 'opensans': f'https:{FONT_URL}', }, 'js_modules': { 'fast': f'{config.npm_cdn}/@microsoft/fast-components@2.30.6/dist/fast-components.js', 'fast-design': 'js/fast_design.js' }, 'bundle': True, 'tarball': { 'fast': { 'tar': 'https://registry.npmjs.org/@microsoft/fast-components/-/fast-components-2.30.6.tgz', 'src': 'package/', 'dest': '@microsoft/fast-components@2.30.6', 'exclude': ['*.d.ts', '*.json', '*.md', '*/esm/*'] } } } _themes = { 'default': FastDefaultTheme, 'dark': FastDarkTheme } def _wrapper(self, model): return FastWrapper(design=None, object=model, style=self.theme.style)