import param
import panel as pn
js_files = {
'mdc': 'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js'
}
css_files = [
'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css'
]
pn.extension(js_files=js_files, css_files=css_files)
from panel.viewable import Viewer
class EditableRange(Viewer):
value = param.Range(doc="A numeric range.")
width = param.Integer(default=300)
def __init__(self, **params):
self._start_input = pn.widgets.FloatInput()
self._end_input = pn.widgets.FloatInput(align='end')
super().__init__(**params)
self._layout = pn.Row(self._start_input, self._end_input)
self._sync_widgets()
def __panel__(self):
return self._layout
@param.depends('value', 'width', watch=True)
def _sync_widgets(self):
self._start_input.name = self.name
self._start_input.value = self.value[0]
self._end_input.value = self.value[1]
self._start_input.width = self.width//2
self._end_input.width = self.width//2
@param.depends('_start_input.value', '_end_input.value', watch=True)
def _sync_params(self):
self.value = (self._start_input.value, self._end_input.value)
range_widget = EditableRange(name='Range', value=(0, 10))
pn.Column(
'## This is a custom widget',
range_widget
)
from panel.reactive import ReactiveHTML
class Slideshow(ReactiveHTML):
index = param.Integer(default=0)
_template = '
'
def _img_click(self, event):
self.index += 1
Slideshow(width=800, height=300)
class JSSlideshow(ReactiveHTML):
index = param.Integer(default=0)
_template = """
"""
_scripts = {'click': 'data.index += 1'}
JSSlideshow(width=800, height=300)
class Select(ReactiveHTML):
options = param.List(doc="Options to choose from.")
value = param.String(doc="Current selected option")
_template = """
"""
_dom_events = {'select': ['change']}
select = Select(options=['A', 'B', 'C'])
select
class Canvas(ReactiveHTML):
color = param.Color(default='#000000')
line_width = param.Number(default=1, bounds=(0.1, 10))
uri = param.String()
_template = """
"""
_scripts = {
'render': """
state.ctx = canvas.getContext("2d")
""",
'start': """
state.start = event
state.ctx.beginPath()
state.ctx.moveTo(state.start.offsetX, state.start.offsetY)
""",
'draw': """
if (state.start == null)
return
state.ctx.lineTo(event.offsetX, event.offsetY)
state.ctx.stroke()
""",
'end': """
delete state.start
""",
'clear': """
state.ctx.clearRect(0, 0, canvas.width, canvas.height);
""",
'save': """
data.uri = canvas.toDataURL();
""",
'line_width': """
state.ctx.lineWidth = data.line_width;
""",
'color': """
state.ctx.strokeStyle = data.color;
"""
}
canvas = Canvas(width=400, height=400)
# We create a separate HTML element which syncs with the uri parameter of the Canvas
png_view = pn.pane.HTML()
canvas.jslink(png_view, code={'uri': "target.text = `
`"})
pn.Column(
'# Drag on canvas to draw\n To export the drawing to a png click save.',
pn.Row(
canvas.controls(['color', 'line_width']),
canvas,
png_view
)
)
class MaterialTextField(ReactiveHTML):
value = param.String(default='')
_template = """
"""
_dom_events = {'text-input': ['change']}
_scripts = {
'render': "mdc.textField.MDCTextField.attachTo(text_field);"
}
__javascript__ = [
'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js'
]
__css__ = [
'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css'
]
text_field = MaterialTextField()
text_field