Skip to content

Commit e350db0

Browse files
committed
Revert defaulting to adding clear_button by default
1 parent 6fd3bbb commit e350db0

File tree

2 files changed

+27
-18
lines changed

2 files changed

+27
-18
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2727

2828
* `playwright.controller.InputActionButton` gains a `expect_icon()` method. As a result, the already existing `expect_label()` no longer includes the icon. (#2020)
2929

30-
### Changes
30+
* `ui.input_selectize()`'s `remove_button` parameter gains a supported value of `"both"`, which adds both of the `"remove_button"` and `"clear_button"` selectize plugins. This is most useful when `multiple=True`, allowing for clearing of individual as well as _all_ selected items. (#2064)
3131

32-
* `ui.input_selectize()` now defaults to `remove_button=True`, which includes both the `"remove_button"` and `"clear_button"` selectize plugins. This means, it's now easier for the user to clear the selection (when `multiple=False`) as well as _all_ selections (when `multiple=True`). (#2064)
32+
### Changes
3333

3434
* `express.ui.insert_accordion_panel()`'s function signature has changed to be more ergonomic. Now you can pass the `panel_title` and `panel_contents` directly instead of `ui.hold()`ing the `ui.accordion_panel()` context manager. (#2042)
3535

shiny/ui/_input_select.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"input_selectize",
1111
)
1212
import json
13-
from typing import Mapping, Optional, Union, cast
13+
from typing import Literal, Mapping, Optional, Union, cast
1414

1515
from htmltools import Tag, TagChild, TagList, css, div, tags
1616

@@ -58,7 +58,7 @@ def input_selectize(
5858
selected: Optional[str | list[str]] = None,
5959
multiple: bool = False,
6060
width: Optional[str] = None,
61-
remove_button: bool = True,
61+
remove_button: Optional[Literal[True, False, "both"]] = None,
6262
options: Optional[dict[str, Jsonifiable | JSEval]] = None,
6363
) -> Tag:
6464
"""
@@ -84,10 +84,16 @@ def input_selectize(
8484
width
8585
The CSS width, e.g. '400px', or '100%'
8686
remove_button
87-
Whether to add a remove button. When `True` (the default), both the
88-
'clear_button' and 'remove_button' plugins are included. If you want just one
89-
plugin, set this to `False` and specify the desired plugin in the `options`
90-
argument (i.e., `options = {"plugins": ["remove_button"]}`).
87+
Whether to include remove button(s). The following values are supported:
88+
89+
- `None` (the default): The 'remove_button' selection plugin is included when
90+
`multiple=True`.
91+
- `True`: Same as `None` in the `multiple=True` case, but when `multiple=False`,
92+
the 'clear_button' plugin is included.
93+
- `False`: No plugins are included.
94+
- `"both"`: Both 'remove_button' and 'clear_button' plugins are included. This
95+
is useful for being able to clear each and all selected items when
96+
`multiple=True`.
9197
options
9298
A dictionary of options. See the documentation of selectize.js for possible options.
9399
If you want to pass a JavaScript function, wrap the string in `ui.JS`.
@@ -201,8 +207,8 @@ def input_select(
201207
"Use `input_selectize()` instead of passing `selectize=True`."
202208
)
203209

204-
if isinstance(remove_button, MISSING_TYPE) or remove_button is None:
205-
remove_button = True
210+
if isinstance(remove_button, MISSING_TYPE):
211+
remove_button = None
206212
else:
207213
warn_deprecated(
208214
"`remove_button` parameter of `input_select()` is deprecated. "
@@ -245,7 +251,7 @@ def _input_select_impl(
245251
selectize: bool = False,
246252
width: Optional[str] = None,
247253
size: Optional[str] = None,
248-
remove_button: bool = True,
254+
remove_button: Literal[True, False, "both", None] = None,
249255
options: Optional[dict[str, Jsonifiable | JSEval]] = None,
250256
) -> Tag:
251257
if options is not None and selectize is False:
@@ -262,15 +268,18 @@ def _input_select_impl(
262268
if options is None:
263269
options = {}
264270

265-
# Although 'remove_button' is primarily for multiple=True and 'clear_button' is for
266-
# multiple=False, we include both in either case since:
267-
# 1. When multiple=True, 'clear_button' can be used to clear _all_ selected items.
268-
# 2. When multiple=False, 'remove_button' is effectively a no-op.
269-
# 3. By including both, we can simplify the client-side logic needed to retain
270-
# these plugins across update_selectize(options=...) calls
271+
if remove_button is None:
272+
remove_button = multiple
273+
274+
# Translate remove_button into default selectize plugins
275+
# N.B. remove_button is primarily for multiple=True and clear_button is for
276+
# multiple=False, but both can also be useful in the multiple=True case (i.e., clear
277+
# _all_ selected items)
271278
default_plugins = None
272-
if remove_button or remove_button is None:
279+
if remove_button == "both":
273280
default_plugins = json.dumps(["remove_button", "clear_button"])
281+
elif remove_button:
282+
default_plugins = json.dumps(["remove_button" if multiple else "clear_button"])
274283

275284
choices_tags = _render_choices(choices_, selected)
276285

0 commit comments

Comments
 (0)