@bokeh/bokehjs
Version:
Interactive, novel data visualization
122 lines • 4.35 kB
JavaScript
import { UIElement, UIElementView } from "../ui/ui_element";
import { IconLike } from "../common/kinds";
import { apply_icon } from "../common/resolve";
import { Tool } from "./tool";
import { ToolProxy } from "./tool_proxy";
import { ToolGroup } from "./tool_group";
import { UIGestures } from "../../core/ui_gestures";
import { div } from "../../core/dom";
import { ContextMenu } from "../../core/util/menus";
import { reversed } from "../../core/util/array";
import tool_button_css, * as tool_button from "../../styles/tool_button.css";
import icons_css from "../../styles/icons.css";
export class ToolButtonView extends UIElementView {
static __name__ = "ToolButtonView";
_menu;
_ui_gestures;
initialize() {
super.initialize();
const { location } = this.parent.model;
const reverse = location == "left" || location == "above";
const orientation = this.parent.model.horizontal ? "vertical" : "horizontal";
const items = this.model.tool.menu ?? [];
this._menu = new ContextMenu(!reverse ? items : reversed(items), {
target: this.parent.el,
orientation,
prevent_hide: (event) => {
return event.composedPath().includes(this.el);
},
labels: false,
});
this._ui_gestures = new UIGestures(this.el, {
on_tap: (event) => {
if (this._menu.is_open) {
this._menu.hide();
return;
}
if (event.native.composedPath().includes(this.el)) {
this.tap();
}
},
on_press: () => {
this.press();
},
});
this.el.addEventListener("keydown", (event) => {
switch (event.key) {
case "Enter": {
this.tap();
break;
}
case " ": {
this.press();
break;
}
default:
}
});
}
connect_signals() {
super.connect_signals();
this._ui_gestures.connect_signals();
this.connect(this.model.change, () => this.render());
this.connect(this.model.tool.change, () => this.render());
}
remove() {
this._ui_gestures.remove();
this._menu.remove();
super.remove();
}
stylesheets() {
return [...super.stylesheets(), tool_button_css, icons_css];
}
render() {
super.render();
const { tool } = this.model;
this.class_list.add(tool_button[this.parent.model.location]);
this.class_list.toggle(tool_button.hidden, !tool.visible);
this.class_list.toggle(tool_button.disabled, tool.disabled);
const icon_el = div({ class: tool_button.tool_icon });
this.shadow_el.append(icon_el);
const icon = this.model.icon ?? tool.computed_icon;
if (icon != null) {
apply_icon(icon_el, icon);
}
if (tool.menu != null) {
const chevron_el = div({ class: tool_button.tool_chevron });
this.shadow_el.append(chevron_el);
}
if (tool instanceof ToolGroup && tool.show_count) {
const count_el = div({ class: tool_button.count }, `${tool.tools.length}`);
this.shadow_el.append(count_el);
}
const tooltip = this.model.tooltip ?? tool.tooltip;
this.el.title = tooltip;
this.el.tabIndex = 0;
}
press() {
const at = (() => {
switch (this.parent.model.location) {
case "right": return { left_of: this.el };
case "left": return { right_of: this.el };
case "above": return { below: this.el };
case "below": return { above: this.el };
}
})();
this._menu.toggle(at);
}
}
export class ToolButton extends UIElement {
static __name__ = "ToolButton";
constructor(attrs) {
super(attrs);
}
static {
this.define(({ Str, Ref, Nullable, Or }) => ({
tool: [Or(Ref(Tool), Ref(ToolProxy))],
icon: [Nullable(IconLike), null],
tooltip: [Nullable(Str), null],
}));
}
}
//# sourceMappingURL=tool_button.js.map