diff --git a/src/panel_material_ui/base.py b/src/panel_material_ui/base.py index 8ca7204..cdea765 100644 --- a/src/panel_material_ui/base.py +++ b/src/panel_material_ui/base.py @@ -21,9 +21,30 @@ const [defaultTheme] = props.model.useState('theme') const theme = createTheme({{ + cssVariables: {{ + rootSelector: ':host', + colorSchemeSelector: 'class', + }}, colorSchemes: {{ dark: defaultTheme === "dark", }}, + components: {{ + MuiPopover: {{ + defaultProps: {{ + container: props.view.container, + }}, + }}, + MuiPopper: {{ + defaultProps: {{ + container: props.view.container, + }}, + }}, + MuiModal: {{ + defaultProps: {{ + container: props.view.container, + }}, + }}, + }} }}); return ( @@ -44,8 +65,8 @@ class MaterialComponent(ReactComponent): _importmap = { "imports": { - "@mui/material/": "https://esm.sh/@mui/material@6.1.7/", - "@mui/icons-material/": "https://esm.sh/@mui/icons-material@6.1.7/", + "@mui/material/": "https://esm.sh/@mui/material@6.4.0/", + "@mui/icons-material/": "https://esm.sh/@mui/icons-material@6.4.0/", } } diff --git a/src/panel_material_ui/chat/input.py b/src/panel_material_ui/chat/input.py index fc4ea38..c7a7d10 100644 --- a/src/panel_material_ui/chat/input.py +++ b/src/panel_material_ui/chat/input.py @@ -45,7 +45,7 @@ class ChatAreaInput(TextAreaInput): rows = param.Integer(default=1) - _esm = "ChatArea.jsx" + _esm_base = "ChatArea.jsx" def _handle_msg(self, msg) -> None: """ diff --git a/src/panel_material_ui/layout/Dialog.jsx b/src/panel_material_ui/layout/Dialog.jsx index 6e1b52a..9e9e4bc 100644 --- a/src/panel_material_ui/layout/Dialog.jsx +++ b/src/panel_material_ui/layout/Dialog.jsx @@ -8,12 +8,8 @@ export function render({model, view}) { const [title] = model.useState("title"); const objects = model.get_child("objects"); - model.on("after_render", () => { - document.head.append(...view.style_cache.children) - }) - return ( - + {title} diff --git a/src/panel_material_ui/layout/base.py b/src/panel_material_ui/layout/base.py index 3bc4b0c..0e11a7b 100644 --- a/src/panel_material_ui/layout/base.py +++ b/src/panel_material_ui/layout/base.py @@ -39,7 +39,7 @@ class Paper(MaterialListLike): elevation = param.Integer(default=1, bounds=(0, None)) - _esm = "Paper.jsx" + _esm_base = "Paper.jsx" class Card(MaterialListLike): @@ -101,7 +101,7 @@ class Card(MaterialListLike): outlined = param.Boolean(default=False) - _esm = "Card.jsx" + _esm_base = "Card.jsx" def select(self, selector: type | Callable[[Viewable], bool] | None = None) -> list[Viewable]: return ([] if self.header is None else self.header.select(selector)) + super().select(selector) @@ -142,7 +142,7 @@ class Accordion(MaterialNamedListLike): _names = param.List(default=[]) - _esm = "Accordion.jsx" + _esm_base = "Accordion.jsx" def __init__(self, *objects, **params): if "objects" not in params: @@ -191,7 +191,7 @@ class Tabs(MaterialNamedListLike): _names = param.List(default=[]) - _esm = "Tabs.jsx" + _esm_base = "Tabs.jsx" def __init__(self, *objects, **params): if "objects" not in params: @@ -233,7 +233,7 @@ class Divider(MaterialListLike): variant = param.Selector(default="fullWidth", objects=["fullWidth", "inset", "middle"]) - _esm = "Divider.jsx" + _esm_base = "Divider.jsx" class Alert(MaterialListLike): @@ -250,7 +250,7 @@ class Alert(MaterialListLike): variant = param.Selector(default="filled", objects=["filled", "outlined"]) - _esm = "Alert.jsx" + _esm_base = "Alert.jsx" class Backdrop(MaterialListLike): @@ -271,7 +271,7 @@ class Backdrop(MaterialListLike): open = param.Boolean(default=False) - _esm = "Backdrop.jsx" + _esm_base = "Backdrop.jsx" class Dialog(MaterialListLike): @@ -296,4 +296,4 @@ class Dialog(MaterialListLike): title = param.String(default="") - _esm = "Dialog.jsx" + _esm_base = "Dialog.jsx" diff --git a/src/panel_material_ui/pane/base.py b/src/panel_material_ui/pane/base.py index 8b22ac8..015f5c3 100644 --- a/src/panel_material_ui/pane/base.py +++ b/src/panel_material_ui/pane/base.py @@ -18,7 +18,7 @@ class Chip(MaterialComponent): variant = param.Selector(objects=["filled", "outlined"], default="filled") - _esm = "Chip.jsx" + _esm_base = "Chip.jsx" _stylesheets = ["https://fonts.googleapis.com/icon?family=Material+Icons"] @@ -42,7 +42,7 @@ class Avatar(MaterialComponent): variant = param.Selector(objects=["rounded", "square"], default="rounded") - _esm = "Avatar.jsx" + _esm_base = "Avatar.jsx" class Skeleton(MaterialComponent): @@ -52,4 +52,4 @@ class Skeleton(MaterialComponent): width = param.Integer(default=0) - _esm = "Skeleton.jsx" + _esm_base = "Skeleton.jsx" diff --git a/src/panel_material_ui/template/base.py b/src/panel_material_ui/template/base.py index 5514abf..1598059 100644 --- a/src/panel_material_ui/template/base.py +++ b/src/panel_material_ui/template/base.py @@ -17,6 +17,6 @@ class AppBar(MaterialListLike): position = param.Selector(default="static", objects=["fixed", "static", "sticky"]) - _esm = "AppBar.jsx" + _esm_base = "AppBar.jsx" _stylesheets = ["https://fonts.googleapis.com/icon?family=Material+Icons"] diff --git a/src/panel_material_ui/widgets/MultiChoice.jsx b/src/panel_material_ui/widgets/MultiChoice.jsx new file mode 100644 index 0000000..e34fdc1 --- /dev/null +++ b/src/panel_material_ui/widgets/MultiChoice.jsx @@ -0,0 +1,66 @@ +import Box from "@mui/material/Box"; +import OutlinedInput from "@mui/material/OutlinedInput"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +import Select from "@mui/material/Select"; +import Chip from "@mui/material/Chip"; + +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; + +const MenuProps = { + disablePortal: true, // Ensures menu doesn't render outside of shadow DOM + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 250, + }, + }, +}; + +export function render({model, view}) { + const [disabled] = model.useState("disabled"); + const [label] = model.useState("label"); + const [options] = model.useState("options"); + const [value, setValue] = model.useState("value"); + + const handleChange = (event) => { + const { + target: { value }, + } = event; + setValue( + // On autofill we get a stringified value. + typeof value === "string" ? value.split(",") : value, + ); + }; + + return ( + + {label} + + + ); +} diff --git a/src/panel_material_ui/widgets/Slider.jsx b/src/panel_material_ui/widgets/Slider.jsx index 18a63c0..2333873 100644 --- a/src/panel_material_ui/widgets/Slider.jsx +++ b/src/panel_material_ui/widgets/Slider.jsx @@ -3,17 +3,20 @@ import Slider from "@mui/material/Slider" import Typography from "@mui/material/Typography" export function render({model}) { + const [bar_color] = model.useState("bar_color") const [color] = model.useState("color") const [disabled] = model.useState("disabled") const [end] = model.useState("end") const [format] = model.useState("format") const [label] = model.useState("label") const [orientation] = model.useState("orientation") + const [show_value] = model.useState("show_value") const [start] = model.useState("start") const [step] = model.useState("step") const [tooltips] = model.useState("tooltips") const [track] = model.useState("track") const [value, setValue] = model.useState("value") + const [value_throttled, setValueThrottled] = model.useState("value_throttled") const [value_label, setValueLabel] = React.useState() @@ -33,9 +36,11 @@ export function render({model}) { {label && `${label}: `} - - {value_label} - + { show_value && + + {value_label} + + } setValue(newValue)} + onChangeCommitted={(event, newValue) => setValueThrottled(newValue)} + sx={{ + "& .MuiSlider-track": { + backgroundColor: bar_color, + borderColor: bar_color + }, + "& .MuiSlider-rail": { + backgroundColor: bar_color, + }, + }} /> ) diff --git a/src/panel_material_ui/widgets/ToggleIcon.jsx b/src/panel_material_ui/widgets/ToggleIcon.jsx index a9b91ae..6c187d7 100644 --- a/src/panel_material_ui/widgets/ToggleIcon.jsx +++ b/src/panel_material_ui/widgets/ToggleIcon.jsx @@ -6,6 +6,7 @@ export function render({model, el}) { const [active_icon] = model.useState("active_icon") const [color] = model.useState("color") const [description] = model.useState("description") + const [description_delay] = model.useState("description_delay") const [disabled] = model.useState("disabled") const [icon] = model.useState("icon") const [size] = model.useState("size") @@ -29,6 +30,7 @@ export function render({model, el}) { >> Button(name='Click me', icon='caret-right', button_type='primary') @@ -87,7 +82,7 @@ class Button(_ButtonBase, _ClickButton): value = param.Event(doc="Toggles from False to True while the event is being processed.") - _esm = "Button.jsx" + _esm_base = "Button.jsx" _rename: ClassVar[Mapping[str, str | None]] = {"label": "label", "button_style": "button_style"} @@ -133,12 +128,6 @@ class Toggle(_ButtonBase): This widget is interchangeable with the `Checkbox` widget. - Some missing and extra features (if any) when comparing with the corresponding - panel Toggle widget [panel.widgets.Toggle](https://panel.holoviz.org/reference/widgets/Toggle.html): - - No missing features - - Extra features: clicks, description, label, on_event, on_msg, theme - - :Example: >>> Toggle(name='Toggle', button_type='success') @@ -152,60 +141,4 @@ class Toggle(_ButtonBase): value = param.Boolean(default=False) - _esm = "ToggleButton.jsx" - - -class ButtonIcon(_ButtonBase): - """ - The `ButtonIcon` widget facilitates event triggering upon button clicks. - - This widget displays a default `icon` initially. Upon being clicked, an `active_icon` appears - for a specified `toggle_duration`. - - For instance, the `ButtonIcon` can be effectively utilized to implement a feature akin to - ChatGPT's copy-to-clipboard button. - - The button incorporates a `value` attribute, which alternates between `False` and `True` as the - click event is processed. - - Furthermore, it includes an `clicks` attribute, enabling subscription to click events for - further actions or monitoring. - - Some missing and extra features (if any) when comparing with the corresponding - panel ButtonIcon widget [panel.widgets.ButtonIcon](https://panel.holoviz.org/reference/widgets/ButtonIcon.html): - - Missing features: description_delay, js_on_click, on_click - - Extra features: button_style, button_type, edge, label, on_event, on_msg, theme - - :Example: - - >>> button_icon = ButtonIcon( - ... icon='favorite', - ... active_icon='check', - ... description='Copy', - ... toggle_duration=2000 - ... ) - """ - - active_icon = param.String( - default="", - doc=""" - The name of the icon to display when toggled from - [tabler-icons.io](https://tabler-icons.io)/ or an SVG.""", - ) - - edge = param.Selector(objects=["start", "end", False], default=False) - - size = param.String( - default="1em", - doc=""" - Size of the icon as a string, e.g. 12px or 1em.""", - ) - - toggle_duration = param.Integer( - default=75, - doc=""" - The number of milliseconds the active_icon should be shown for - and how long the button should be disabled for.""", - ) - - _esm = "IconButton.jsx" + _esm_base = "ToggleButton.jsx" diff --git a/src/panel_material_ui/widgets/icon.py b/src/panel_material_ui/widgets/icon.py index 2a01303..0a5ff04 100644 --- a/src/panel_material_ui/widgets/icon.py +++ b/src/panel_material_ui/widgets/icon.py @@ -1,12 +1,40 @@ from __future__ import annotations +from collections.abc import Callable + import param from ..base import COLORS from .base import MaterialWidget +from .button import _ButtonBase + +class _ClickableIcon(MaterialWidget): + + active_icon = param.String( + default="", + doc=""" + The name of the icon to display when toggled from + https://mui.com/material-ui/material-icons or an SVG.""", + ) -class ToggleIcon(MaterialWidget): + icon = param.String( + default="heart", + doc=""" + The name of the icon to display from + https://mui.com/material-ui/material-icons or an SVG.""", + ) + + size = param.Selector(objects=["small", "medium", "large"], default="medium") + + value = param.Boolean( + default=False, + doc=""" + Whether the icon is toggled on or off.""", + ) + + +class ToggleIcon(_ClickableIcon): """ The `ToggleIcon` widget allows toggling a single condition between True/False states. This widget is interchangeable with the `Checkbox` and `Switch` widget. @@ -24,32 +52,85 @@ class ToggleIcon(MaterialWidget): ... ) """ - active_icon = param.String( - default="", - doc=""" - The name of the icon to display when toggled from - [tabler-icons.io](https://tabler-icons.io)/ or an SVG.""", - ) - color = param.Selector(objects=COLORS, default="primary") - icon = param.String( - default="heart", - doc=""" - The name of the icon to display from - [tabler-icons.io](https://tabler-icons.io)/ or an SVG.""", - ) + description_delay = param.Integer(default=5000, doc=""" + Delay (in milliseconds) to display the tooltip after the cursor has + hovered over the Button, default is 500ms.""") - size = param.Selector(objects=["small", "medium", "large"], default="medium") + width = param.Boolean(default=None) - value = param.Boolean( - default=False, + _esm_base = "ToggleIcon.jsx" + + +class ButtonIcon(_ClickableIcon, _ButtonBase): + """ + The `ButtonIcon` widget facilitates event triggering upon button clicks. + + This widget displays a default `icon` initially. Upon being clicked, an `active_icon` appears + for a specified `toggle_duration`. + + For instance, the `ButtonIcon` can be effectively utilized to implement a feature akin to + ChatGPT's copy-to-clipboard button. + + The button incorporates a `value` attribute, which alternates between `False` and `True` as the + click event is processed. + + Furthermore, it includes an `clicks` attribute, enabling subscription to click events for + further actions or monitoring. + + :Example: + + >>> button_icon = ButtonIcon( + ... icon='favorite', + ... active_icon='check', + ... description='Copy', + ... toggle_duration=2000 + ... ) + """ + + clicks = param.Integer(default=0, doc=""" + The number of times the button has been clicked.""") + + edge = param.Selector(objects=["start", "end", False], default=False) + + size = param.String( + default="1em", doc=""" - Whether the icon is toggled on or off.""", + Size of the icon as a string, e.g. 12px or 1em.""", ) - width = param.Boolean(default=None) - - _esm = "ToggleIcon.jsx" + toggle_duration = param.Integer( + default=75, + doc=""" + The number of milliseconds the active_icon should be shown for + and how long the button should be disabled for.""", + ) - _stylesheets = ["https://fonts.googleapis.com/icon?family=Material+Icons"] + _esm_base = "IconButton.jsx" + + def __init__(self, **params): + click_handler = params.pop('on_click', None) + super().__init__(**params) + if click_handler: + self.on_click(click_handler) + + def on_click( + self, callback: Callable[[param.parameterized.Event], None] + ) -> param.parameterized.Watcher: + """ + Register a callback to be executed when the button is clicked. + + The callback is given an `Event` argument declaring the number of clicks. + + Arguments + --------- + callback: (Callable[[param.parameterized.Event], None]) + The function to run on click events. Must accept a positional `Event` argument + + Returns + ------- + watcher: param.Parameterized.Watcher + A `Watcher` that executes the callback when the MenuButton is clicked. + """ + return self.param.watch(callback, 'clicks', onlychanged=False) diff --git a/src/panel_material_ui/widgets/indicators.py b/src/panel_material_ui/widgets/indicators.py index a7f0a0b..fc2b866 100644 --- a/src/panel_material_ui/widgets/indicators.py +++ b/src/panel_material_ui/widgets/indicators.py @@ -22,7 +22,7 @@ class LoadingIndicator(MaterialWidget): variant = param.Selector(default="indeterminate", objects=["determinate", "indeterminate"]) - _esm = "CircularProgress.jsx" + _esm_base = "CircularProgress.jsx" class Progress(MaterialWidget): @@ -45,4 +45,4 @@ class Progress(MaterialWidget): variant = param.Selector(default="determinate", objects=["determinate", "indeterminate", "buffer", "query"]) - _esm = "LinearProgress.jsx" + _esm_base = "LinearProgress.jsx" diff --git a/src/panel_material_ui/widgets/input.py b/src/panel_material_ui/widgets/input.py index f44331d..8781321 100644 --- a/src/panel_material_ui/widgets/input.py +++ b/src/panel_material_ui/widgets/input.py @@ -76,7 +76,7 @@ class TextInput(_TextInputBase): enter_pressed = param.Event(doc=""" Event when the enter key has been pressed.""") - _esm = "TextField.jsx" + _esm_base = "TextField.jsx" def _handle_enter(self, event: DOMEvent): self.param.trigger('enter_pressed') @@ -94,7 +94,7 @@ class PasswordInput(_TextInputBase): >>> PasswordInput(label='Password', placeholder='Enter your password here ...') """ - _esm = "PasswordField.jsx" + _esm_base = "PasswordField.jsx" class TextAreaInput(_TextInputBase): @@ -148,7 +148,7 @@ class TextAreaInput(_TextInputBase): Can only be set during initialization.""", ) - _esm = "TextArea.jsx" + _esm_base = "TextArea.jsx" class Checkbox(MaterialWidget): @@ -174,7 +174,7 @@ class Checkbox(MaterialWidget): value = param.Boolean(default=False) - _esm = "Checkbox.jsx" + _esm_base = "Checkbox.jsx" class Switch(MaterialWidget): @@ -202,7 +202,7 @@ class Switch(MaterialWidget): width = param.Boolean(default=None) - _esm = "Switch.jsx" + _esm_base = "Switch.jsx" class FileInput(MaterialWidget, _PnFileInput): @@ -225,7 +225,7 @@ class FileInput(MaterialWidget, _PnFileInput): width = param.Integer(default=None) - _esm = "FileInput.jsx" + _esm_base = "FileInput.jsx" def __init__(self, **params): super().__init__(**params) diff --git a/src/panel_material_ui/widgets/select.py b/src/panel_material_ui/widgets/select.py index 61f9757..cf553f5 100644 --- a/src/panel_material_ui/widgets/select.py +++ b/src/panel_material_ui/widgets/select.py @@ -69,7 +69,7 @@ class AutocompleteInput(MaterialSingleSelectBase): _allows_none = True - _esm = "Autocomplete.jsx" + _esm_base = "Autocomplete.jsx" _rename = {"name": "name"} @@ -113,7 +113,7 @@ class Select(MaterialSingleSelectBase): variant = param.Selector(objects=["filled", "outlined", "standard"], default="outlined") - _esm = "Select.jsx" + _esm_base = "Select.jsx" _rename = {"name": "name"} @@ -128,7 +128,7 @@ class RadioGroup(MaterialWidget): Button group orientation, either 'horizontal' (default) or 'vertical'.""", ) - _esm = "RadioGroup.jsx" + _esm_base = "RadioGroup.jsx" _rename = {"name": "name"} @@ -205,7 +205,7 @@ class ButtonGroup(MaterialWidget): width = param.Integer(default=None, doc="""""") - _esm = "ButtonGroup.jsx" + _esm_base = "ButtonGroup.jsx" _rename = {"name": "name"} @@ -260,3 +260,55 @@ class CheckButtonGroup(ButtonGroup, MaterialMultiSelectBase): """ _constants = {"exclusive": False} + + +class MultiChoice(MaterialMultiSelectBase): + """ + The `MultiChoice` widget allows selecting multiple values from a list of + `options`. + + It falls into the broad category of multi-value, option-selection widgets + that provide a compatible API and include the `MultiSelect`, + `CrossSelector`, `CheckBoxGroup` and `CheckButtonGroup` widgets. + + The `MultiChoice` widget provides a much more compact UI than + `MultiSelect`. + + Reference: https://panel.holoviz.org/reference/widgets/MultiChoice.html + + :Example: + + >>> MultiChoice( + ... name='Favourites', value=['Panel', 'hvPlot'], + ... options=['Panel', 'hvPlot', 'HoloViews', 'GeoViews', 'Datashader', 'Param', 'Colorcet'], + ... max_items=2 + ... ) + """ + + delete_button = param.Boolean(default=True, doc=""" + Whether to display a button to delete a selected option.""") + + max_items = param.Integer(default=None, bounds=(1, None), doc=""" + Maximum number of options that can be selected.""") + + option_limit = param.Integer(default=None, bounds=(1, None), doc=""" + Maximum number of options to display at once.""") + + search_option_limit = param.Integer(default=None, bounds=(1, None), doc=""" + Maximum number of options to display at once if search string is entered.""") + + placeholder = param.String(default='', doc=""" + String displayed when no selection has been made.""") + + solid = param.Boolean(default=True, doc=""" + Whether to display widget with solid or light style.""") + + width = param.Integer(default=300, allow_None=True, doc=""" + Width of this component. If sizing_mode is set to stretch + or scale mode this will merely be used as a suggestion.""") + + value = param.List(default=[]) + + _rename = {"name": None} + + _esm_base = "MultiChoice.jsx" diff --git a/src/panel_material_ui/widgets/sliders.py b/src/panel_material_ui/widgets/sliders.py index db7ed52..cb4948b 100644 --- a/src/panel_material_ui/widgets/sliders.py +++ b/src/panel_material_ui/widgets/sliders.py @@ -1,16 +1,23 @@ import param from bokeh.models.formatters import NumeralTickFormatter, TickFormatter from panel.util import edit_readonly +from panel.widgets.slider import _SliderBase from param.parameterized import resolve_value from ..base import COLORS from .base import MaterialWidget -class _ContinuousSlider(MaterialWidget): +class _ContinuousSlider(MaterialWidget, _SliderBase): + + bar_color = param.Color(default=None, doc="Color of the bar") color = param.Selector(objects=COLORS, default="primary") + direction = param.Selector(default='ltr', objects=['ltr', 'rtl'], doc=""" + Whether the slider should go from left-to-right ('ltr') or + right-to-left ('rtl').""") + start = param.Number(default=0) end = param.Number(default=100) @@ -20,15 +27,15 @@ class _ContinuousSlider(MaterialWidget): step = param.Number(default=1) - orientation = param.Selector(objects=["horizontal", "vertical"], default="horizontal") - - tooltips = param.Boolean(default=True) - track = param.Selector(objects=["normal", "inverted", False], default="normal") value = param.Number(default=0) - _esm = "Slider.jsx" + value_throttled = param.Number(default=0, constant=True) + + _esm_base = "Slider.jsx" + + _rename = {"name": "name"} __abstract = True @@ -46,11 +53,6 @@ class IntSlider(_ContinuousSlider): The IntSlider widget allows selecting an integer value within a set of bounds using a slider. - Some missing and extra features (if any) when comparing with the corresponding - panel IntSlider widget [panel.widgets.IntSlider](https://panel.holoviz.org/reference/widgets/IntSlider.html): - - Missing features: bar_color, direction, format, show_value, value_throttled - - Extra features: color, description, label, on_event, on_msg, theme, track - :Example: >>> IntSlider(value=5, start=0, end=10, step=1, name="Integer Value") @@ -60,7 +62,11 @@ class IntSlider(_ContinuousSlider): start = param.Integer(default=1) - step = param.Integer(default=1) + step = param.Integer(default=1, readonly=True) + + value = param.Integer(default=0) + + value_throttled = param.Integer(default=0, constant=True) class FloatSlider(_ContinuousSlider): @@ -68,11 +74,6 @@ class FloatSlider(_ContinuousSlider): The FloatSlider widget allows selecting a floating-point value within a set of bounds using a slider. - Some missing and extra features (if any) when comparing with the corresponding - panel IntSlider widget [panel.widgets.FloatSlider](https://panel.holoviz.org/reference/widgets/FloatSlider.html): - - Missing features: bar_color, direction, format, show_value, value_throttled - - Extra features: color, description, label, on_event, on_msg, theme, track - :Example: >>> FloatSlider(value=0.5, start=0.0, end=1.0, step=0.1, name="Float value") @@ -82,8 +83,11 @@ class FloatSlider(_ContinuousSlider): class _RangeSliderBase(_ContinuousSlider): + value = param.Range(default=(0, 100)) + value_throttled = param.Range(default=(0, 100), readonly=True) + value_start = param.Parameter(readonly=True, doc="""The lower value of the selected range.""") value_end = param.Parameter(readonly=True, doc="""The upper value of the selected range.""") @@ -111,11 +115,6 @@ class RangeSlider(_RangeSliderBase): The RangeSlider widget allows selecting a floating-point range using a slider with two handles. - Some missing and extra features (if any) when comparing with the corresponding - panel IntSlider widget [panel.widgets.RangeSlider](https://panel.holoviz.org/reference/widgets/RangeSlider.html): - - Missing features: bar_color, direction, format, show_value, value_throttled - - Extra features: color, description, label, on_event, on_msg, theme, track - :Example: >>> RangeSlider( @@ -129,11 +128,6 @@ class IntRangeSlider(_RangeSliderBase): The IntRangeSlider widget allows selecting an integer range using a slider with two handles. - Some missing and extra features (if any) when comparing with the corresponding - panel IntSlider widget [panel.widgets.IntRangeSlider](https://panel.holoviz.org/reference/widgets/IntRangeSlider.html): - - Missing features: bar_color, direction, format, show_value, value_throttled - - Extra features: color, description, label, on_event, on_msg, theme, track - :Example: >>> IntRangeSlider( @@ -169,7 +163,7 @@ class Rating(MaterialWidget): value = param.Number(default=0, allow_None=True, bounds=(0, 5)) - _esm = "Rating.jsx" + _esm_base = "Rating.jsx" @param.depends("end", watch=True, on_init=True) def _update_value_bounds(self):