UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

113 lines 4.22 kB
import { Model } from "../../model"; import { Node } from "../coordinates/node"; import { Styles } from "../dom/styles"; import { StyleSheet as BaseStyleSheet } from "../dom/stylesheets"; import { DOMComponentView } from "../../core/dom_view"; import { apply_styles } from "../../core/css"; import { InlineStyleSheet } from "../../core/dom"; import { entries } from "../../core/util/object"; import { isNumber, isString } from "../../core/util/types"; import { List, Or, Ref, Str, Dict, Nullable } from "../../core/kinds"; export const StylesLike = Or(Dict(Nullable(Str)), Ref(Styles)); // TODO: add validation for CSSStyles export const StyleSheets = List(Or(Ref(BaseStyleSheet), Str, Dict(StylesLike))); export const CSSVariables = Dict(Or(Ref(Node), Str)); export class StyledElementView extends DOMComponentView { static __name__ = "StyledElementView"; /** * Computed styles applied to self. */ style = new InlineStyleSheet("", "style"); // TODO rename to `self_style` /** * Computed styles append by the parent. */ parent_style = new InlineStyleSheet("", "parent", true); computed_stylesheets() { return [...super.computed_stylesheets(), this.style, this.parent_style]; } connect_signals() { super.connect_signals(); const { html_attributes, html_id, styles, css_classes, css_variables, stylesheets } = this.model.properties; this.on_change([html_attributes, html_id, css_classes, styles], () => this._apply_html_attributes()); this.on_transitive_change(css_variables, () => this._apply_html_attributes()); this.on_transitive_change(stylesheets, () => this._update_stylesheets()); } *_css_classes() { yield* super._css_classes(); yield* this.model.css_classes; } *_css_variables() { yield* super._css_variables(); for (const [key, val] of entries(this.model.css_variables)) { if (val instanceof Node) { const value = this.resolve_coordinate(val); if (isNumber(value)) { yield [key, `${value}px`]; } else if (isString(value)) { yield [key, value]; } } else { yield [key, val]; } } } user_stylesheets() { return [...super.user_stylesheets(), ...this._user_stylesheets()]; } *_user_stylesheets() { for (const stylesheet of this.model.stylesheets) { if (stylesheet instanceof BaseStyleSheet) { yield stylesheet.underlying(); } else { yield new InlineStyleSheet(stylesheet); } } } _apply_html_attributes() { for (const key of this._applied_html_attributes) { this.el.removeAttribute(key); } this._applied_html_attributes = []; this._update_css_classes(); for (const [key, val] of entries(this.model.html_attributes)) { if (key == "class") { const classes = val.split(/ +/); this._applied_css_classes.push(...classes); this.class_list.add(...classes); } else { this.el.setAttribute(key, val); this._applied_html_attributes.push(key); } } const id = this.model.html_id; if (id != null) { this.el.setAttribute("id", id); this._applied_html_attributes.push("id"); } this._apply_styles(); this._update_css_variables(); } _apply_styles() { apply_styles(this.el.style, this.model.styles); } } export class StyledElement extends Model { static __name__ = "StyledElement"; constructor(attrs) { super(attrs); } static { this.define({ html_attributes: [Dict(Str), {}], html_id: [Nullable(Str), null], css_classes: [List(Str), []], css_variables: [CSSVariables, {}], styles: [StylesLike, {}], stylesheets: [StyleSheets, []], }); } } //# sourceMappingURL=styled_element.js.map