Hi
I’m trying to implement a custom FastButton based on the fast-button web component.
The strategy is to inherit from the existing Panel and Bokeh button classes. But I cannot get it working. And I don’t know where to look.
The .gif shows where I am. The problems are that
- Nothing happens when I click or select before I refresh the browser.
- When I refresh after having selected a new appearance I get a
bokeh.min.js?v=16636fdaaea87a3216e9adf3b34ca3c7:551 [bokeh] Failed to repull session Error: property awesome_panel_extensions.bokeh_extensions.fast.fast_button.FastButton.appearance wasn't declared
error. But as far as I can see it’s declared in all panel and bokeh files.
Code
bokeh fast_button.ts
import {Button, ButtonView} from "@bokehjs/models/widgets/button"
import * as p from "@bokehjs/core/properties"
export class FastButtonView extends ButtonView {
model: FastButton
}
export namespace FastButton {
export type Attrs = p.AttrsOf<Props>
export type Props = Button.Props & {
appearance: p.Property<string>
autofocus: p.Property<boolean>
}
}
export interface FastButton extends FastButton.Attrs {}
export class FastButton extends Button {
properties: FastButton.Props
__view_type__: FastButtonView
constructor(attrs?: Partial<FastButton.Attrs>) {
super(attrs)
}
static __module__ = "awesome_panel_extensions.bokeh_extensions.fast.fast_button"
static init_FastButton(): void {
this.prototype.default_view = FastButtonView
this.define<FastButton.Props>({
appearance: [p.String, ],
autofocus: [p.Boolean, ],
})
}
}
bokeh fast_button.py
from bokeh.models import Button as _BkButton
from bokeh.core import properties
class FastButton(_BkButton):
appearance = properties.String(
default="neutral",
help="The appearance attribute",
)
autofocus = properties.Bool(
default=False,
help="The autofocus attribute",
)
panel fast_button.py
"""The FastButton extends the Panel Button to a Fast Design Framework Button.
It is built on the the fast-button web component. The component supports several visual apperances
(accent, lightweight, neutral, outline, stealth).
For more information view the [component specification]\
(https://github.com/microsoft/fast/tree/master/packages/web-components/fast-foundation/\
src/button/button.spec.md).
See also https://explore.fast.design/components/fast-button.
"""
import param
from panel.widgets import Button
from awesome_panel_extensions.bokeh_extensions.fast.fast_button import FastButton as _BkFastButton
FAST_BUTTON_APPEARENCES = [
"accent",
"lightweight",
"neutral",
"outline",
"stealth",
]
DEFAULT_FAST_BUTTON_APPEARANCE = "neutral"
BUTTON_TYPE_TO_APPEARANCE = {
"default": "neutral",
"primary": "accent",
"success": "outline",
"warning": "accent",
"danger": "accent",
}
class FastButton(Button):
"""The FastButton extends the Panel Button into the Fast Design Framework.
It is built on the the fast-button web component. The component supports several visual apperances
(accent, lightweight, neutral, outline, stealth).
For more information view the [component specification]\
(https://github.com/microsoft/fast/tree/master/packages/web-components/fast-foundation/\
src/button/button.spec.md).
See also https://explore.fast.design/components/fast-button.
"""
appearance = param.ObjectSelector(
default=DEFAULT_FAST_BUTTON_APPEARANCE,
objects=FAST_BUTTON_APPEARENCES,
doc="The appearance attribute",
allow_None=True,
)
autofocus = param.Boolean(default=False, doc="The autofocus attribute",)
_widget_type = _BkFastButton
def __init__(self, **params):
if "button_type" in params and "appearance" not in params:
params["appearance"] = BUTTON_TYPE_TO_APPEARANCE[params["button_type"]]
super().__init__(**params)
@param.depends("button_type", watch=True)
def _update_accent(self, *_):
self.appearance = BUTTON_TYPE_TO_APPEARANCE[self.button_type]
app code
import panel as pn
from awesome_panel_extensions.frameworks.fast import config
from awesome_panel_extensions.frameworks.fast import FastButton
pn.Column(
FastButton(name="Hello World"),
pn.Param(FastButton, parameters=["button_type", "clicks", "autofocus", "appearance"]),
config.get_fast_js_panel(),
).servable()