UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

120 lines 4.29 kB
import { Pane, PaneView } from "../ui/pane"; import { div, px, InlineStyleSheet } from "../../core/dom"; import { Location } from "../../core/enums"; import { UIGestures } from "../../core/ui_gestures"; import { Or, Float, CSSLength } from "../../core/kinds"; import { assert } from "../../core/util/assert"; import { isNumber } from "../../core/util/types"; import * as drawers_css from "../../styles/drawers.css"; import * as icons_css from "../../styles/icons.css"; const { max } = Math; const CSSSize = Or(Float, CSSLength); export class DrawerView extends PaneView { static __name__ = "DrawerView"; constructor(options) { super(options); this.on_pan_start = this.on_pan_start.bind(this); this.on_pan = this.on_pan.bind(this); this.on_pan_end = this.on_pan_end.bind(this); } sizing = new InlineStyleSheet("", "sizing"); stylesheets() { return [...super.stylesheets(), icons_css.default, drawers_css.default, this.sizing]; } handle_el = div({ class: drawers_css.handle }); contents_el = div({ class: drawers_css.contents }); toggle_el; ui_gestures = new UIGestures(this.handle_el, this); connect_signals() { super.connect_signals(); this.ui_gestures.connect_signals(); const { location, open, resizable } = this.model.properties; this.on_change(open, () => { this.toggle(this.model.open); }); this.on_change(location, () => { this.class_list.remove(drawers_css.left, drawers_css.right, drawers_css.above, drawers_css.below); this.class_list.add(drawers_css[this.model.location]); }); this.on_change(resizable, () => { this.class_list.toggle(drawers_css.resizable, this.model.resizable); }); } get self_target() { return this.contents_el; } title(open) { return open ? "Collapse" : "Expand"; } render() { super.render(); const { location, open, size, resizable } = this.model; this.class_list.add(drawers_css[location]); this.class_list.toggle(drawers_css.open, open); this.class_list.toggle(drawers_css.resizable, resizable); const icon_el = div({ class: drawers_css.chevron }); const title = this.title(open); this.toggle_el = div({ class: drawers_css.toggle, title }, icon_el); this.toggle_el.addEventListener("click", () => this.toggle()); this.shadow_el.append(this.contents_el, this.toggle_el, this.handle_el); this.sizing.replace(` :host { --drawer-size: ${isNumber(size) ? px(size) : size}; } `); } toggle(open) { open = this.class_list.toggle(drawers_css.open, open); this.toggle_el.title = this.title(open); this.model.open = open; } state = null; on_pan_start(_event) { assert(this.state == null); const styles = getComputedStyle(this.el); this.state = { width: parseFloat(styles.width), height: parseFloat(styles.height), }; this.class_list.add(drawers_css.resizing); } on_pan(event) { assert(this.state != null); const size = (() => { const { width, height } = this.state; const { dx, dy } = event; switch (this.model.location) { case "left": return max(width + dx, 0); case "right": return max(width - dx, 0); case "above": return max(height + dy, 0); case "below": return max(height - dy, 0); } })(); this.sizing.replace(` :host { --drawer-size: ${size}px; } `); } on_pan_end(_event) { assert(this.state != null); this.state = null; this.class_list.remove(drawers_css.resizing); } } export class Drawer extends Pane { static __name__ = "Drawer"; constructor(attrs) { super(attrs); } static { this.prototype.default_view = DrawerView; this.define(({ Bool }) => ({ location: [Location], open: [Bool, false], size: [CSSSize, 300], resizable: [Bool, false], })); } } //# sourceMappingURL=drawer.js.map