streamlit-sortable-multiselect 0.7.9__tar.gz → 0.7.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {streamlit_sortable_multiselect-0.7.9/streamlit_sortable_multiselect.egg-info → streamlit_sortable_multiselect-0.7.10}/PKG-INFO +225 -11
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/README.md +224 -10
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/pyproject.toml +1 -1
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/streamlit_sortable_multiselect/__init__.py +124 -3
- streamlit_sortable_multiselect-0.7.10/streamlit_sortable_multiselect/frontend/build/assets/index-B3tedBLe.css +1 -0
- streamlit_sortable_multiselect-0.7.10/streamlit_sortable_multiselect/frontend/build/assets/index-BwjO0Ed7.js +67 -0
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/streamlit_sortable_multiselect/frontend/build/index.html +2 -2
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10/streamlit_sortable_multiselect.egg-info}/PKG-INFO +225 -11
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/streamlit_sortable_multiselect.egg-info/SOURCES.txt +3 -2
- streamlit_sortable_multiselect-0.7.10/tests/test_calendar.py +141 -0
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/tests/test_wrapper.py +1 -1
- streamlit_sortable_multiselect-0.7.9/streamlit_sortable_multiselect/frontend/build/assets/index-B1hHAom_.css +0 -1
- streamlit_sortable_multiselect-0.7.9/streamlit_sortable_multiselect/frontend/build/assets/index-CWWibq9B.js +0 -67
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/LICENSE +0 -0
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/MANIFEST.in +0 -0
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/setup.cfg +0 -0
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/streamlit_sortable_multiselect.egg-info/dependency_links.txt +0 -0
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/streamlit_sortable_multiselect.egg-info/requires.txt +0 -0
- {streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/streamlit_sortable_multiselect.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streamlit-sortable-multiselect
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.10
|
|
4
4
|
Summary: A Streamlit custom component for selecting and reordering multiple string values.
|
|
5
5
|
Author: Kentaro Aoki
|
|
6
6
|
License-Expression: MIT
|
|
@@ -28,7 +28,9 @@ Dynamic: license-file
|
|
|
28
28
|
|
|
29
29
|
# streamlit-sortable-multiselect
|
|
30
30
|
|
|
31
|
-
A Streamlit custom component for searching, selecting, and reordering
|
|
31
|
+
A Streamlit custom component for searching, selecting, and reordering options,
|
|
32
|
+
dates, months, and date/month ranges. Selected items can be reordered by dragging
|
|
33
|
+
or using move buttons, and are returned as an ordered `list[str]`.
|
|
32
34
|
|
|
33
35
|
## Install
|
|
34
36
|
|
|
@@ -58,6 +60,10 @@ npm run dev
|
|
|
58
60
|
|
|
59
61
|
## Usage
|
|
60
62
|
|
|
63
|
+
The default `input_mode="options"` provides searchable options. For calendar
|
|
64
|
+
inputs, see [Calendar Input](#calendar-input), including date ranges, single
|
|
65
|
+
months, selection bounds, and Japanese labels and messages.
|
|
66
|
+
|
|
61
67
|
```python
|
|
62
68
|
import streamlit as st
|
|
63
69
|
from streamlit_sortable_multiselect import sortable_multiselect
|
|
@@ -90,16 +96,22 @@ st.write(selected)
|
|
|
90
96
|
|
|
91
97
|
## Settings
|
|
92
98
|
|
|
93
|
-
`sortable_multiselect` returns
|
|
99
|
+
`sortable_multiselect` returns selected values as a `list[str]` in the current
|
|
100
|
+
display order. Calendar values use the formats in [Returned Values](#returned-values).
|
|
94
101
|
|
|
95
102
|
| Argument | Type | Default | Description |
|
|
96
103
|
| --- | --- | --- | --- |
|
|
97
104
|
| `label` | `str` | required | Label displayed above the component. |
|
|
98
|
-
| `options` | `Sequence[str \| Mapping[str, Any]]` |
|
|
99
|
-
| `default` | `Sequence[str] \| None` | `None` | Initially selected values, in the initial order. Changing the values or their order replaces the current selection.
|
|
105
|
+
| `options` | `Sequence[str \| Mapping[str, Any]]` | `()` | Available options. Each option can be a plain string, or a dictionary with `label`, `value`, and optional `icon_url` and `color`. Option values must be unique. In calendar modes, optional entries supply labels, icons, and colors for matching calendar values. |
|
|
106
|
+
| `default` | `Sequence[str] \| None` | `None` | Initially selected values, in the initial order. Changing the values or their order replaces the current selection. In options mode, values must exist in `options`. Calendar defaults must match the mode and bounds. Duplicates are not allowed. |
|
|
100
107
|
| `default_revision` | `str \| int \| None` | `None` | Change this value to reapply `default` when its values and order are unchanged. |
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
108
|
+
| `input_mode` | `str` | `"options"` | `"options"`, `"date"`, `"month"`, or `"date_month"`. Mixed mode offers one switch between date ranges and single months. Date-only and month-only modes offer Single/Range controls. |
|
|
109
|
+
| `min_value` | `str \| datetime.date \| None` | `None` | Inclusive lower bound in calendar modes. Accepts `YYYY-MM-DD`, `YYYY-MM`, or a date object. |
|
|
110
|
+
| `max_value` | `str \| datetime.date \| None` | `None` | Inclusive upper bound in calendar modes. Accepts `YYYY-MM-DD`, `YYYY-MM`, or a date object. |
|
|
111
|
+
| `max_range_days` | `int \| None` | `None` | Maximum number of days in each date range, including start and end. Must be positive. `None` means unlimited. Does not limit single values or month ranges. Requires a calendar mode. |
|
|
112
|
+
| `calendar_labels` | `Mapping[str, str] \| None` | `None` | Overrides calendar switches, the Add button, field labels, accessibility group names, and validation messages. See [Calendar Input](#calendar-input) for all keys. Unspecified entries retain their English defaults. |
|
|
113
|
+
| `placeholder` | `str` | `"Select..."` | Placeholder shown in the search/add input when options are available. Used in options mode. |
|
|
114
|
+
| `disabled` | `bool` | `False` | Disables searching, calendar inputs and switches, adding, removing, dragging, and move buttons. |
|
|
103
115
|
| `show_move_buttons` | `bool` | `True` | Shows up/down buttons on selected items. Drag sorting remains available unless `disabled=True`. |
|
|
104
116
|
| `show_numbers` | `bool` | `False` | Shows 1-based position numbers before selected item labels. |
|
|
105
117
|
| `base_color` | `str \| Mapping[str, str] \| None` | `None` | Fallback color for every selected item. See [Colors](#colors). |
|
|
@@ -110,13 +122,13 @@ st.write(selected)
|
|
|
110
122
|
| `tooltip_color` | `str \| Mapping[str, str] \| None` | `None` | Color of the tooltip shown for labels that do not fit. `None` uses the built-in dark tooltip. See [Labels](#labels). |
|
|
111
123
|
| `max_selections` | `int \| None` | `None` | Maximum number of selected items. `None` means no limit. Use `0` to prevent any selections. |
|
|
112
124
|
| `single_select_display` | `bool` | `False` | With `max_selections=1`, displays the selected item inside the search control and replaces it when another option is selected. |
|
|
113
|
-
| `max_selections_placeholder` | `str` | `"Selection limit reached"` | Placeholder shown when `max_selections` has been reached.
|
|
125
|
+
| `max_selections_placeholder` | `str` | `"Selection limit reached"` | Placeholder shown when `max_selections` has been reached in options mode; a status message in calendar modes. Takes precedence over other placeholders. Not shown in inline single-selection mode, which permits replacement. |
|
|
114
126
|
| `empty_message` | `str` | `"No items selected"` | Message shown where the selected list appears when no items are selected. |
|
|
115
|
-
| `no_options_placeholder` | `str` | `"No more options"` | Placeholder shown when every option is already selected and there are no more options to add. |
|
|
127
|
+
| `no_options_placeholder` | `str` | `"No more options"` | Placeholder shown when every option is already selected and there are no more options to add. Used in options mode. |
|
|
116
128
|
| `selected_position` | `str` | `"bottom"` | Position of the selected item list relative to the search/add input. Use `"bottom"` or `"top"`. |
|
|
117
129
|
| `icon_size` | `int` | `20` | Icon display size in pixels for `icon_url` images. Images are displayed inside a square area while preserving their aspect ratio. |
|
|
118
|
-
| `options_max_height` | `int` | `190` | Maximum height in pixels for the available options dropdown. |
|
|
119
|
-
| `suggestions_api_url` | `str \| None` | `None` | Absolute HTTP(S) endpoint used to fetch suggestions in the browser. `None` disables API suggestions. |
|
|
130
|
+
| `options_max_height` | `int` | `190` | Maximum height in pixels for the available options dropdown. Used in options mode. |
|
|
131
|
+
| `suggestions_api_url` | `str \| None` | `None` | Absolute HTTP(S) endpoint used to fetch suggestions in the browser. `None` disables API suggestions. Only supported in options mode. |
|
|
120
132
|
| `suggestions_query_param` | `str` | `"q"` | Query parameter name used to send the current search text. |
|
|
121
133
|
| `suggestions_response_path` | `str` | `""` | Dot-separated path to the suggestions array in the JSON response. Empty means the response root. |
|
|
122
134
|
| `suggestions_label_path` | `str` | `"label"` | Dot-separated path to each suggestion's display label. |
|
|
@@ -279,6 +291,182 @@ option replaces the current value instead of adding another one. Use the remove
|
|
|
279
291
|
inside the selected item to clear it. `single_select_display=True` without
|
|
280
292
|
`max_selections=1` raises `ValueError`.
|
|
281
293
|
|
|
294
|
+
In calendar modes, the selected item is displayed inside the calendar control.
|
|
295
|
+
Adding another calendar value replaces it. A date range counts as one selected item.
|
|
296
|
+
|
|
297
|
+
## Calendar Input
|
|
298
|
+
|
|
299
|
+
### Input Modes
|
|
300
|
+
|
|
301
|
+
`input_mode` selects the input method for the whole component:
|
|
302
|
+
|
|
303
|
+
| Mode | Picker controls | Items added |
|
|
304
|
+
| --- | --- | --- |
|
|
305
|
+
| `"options"` (default) | Searchable dropdown and optional API suggestions | Values from options or API results |
|
|
306
|
+
| `"date"` | Date input with a Single/Range switch | One date or one date range |
|
|
307
|
+
| `"month"` | Month input with a Single/Range switch | One month or one month range |
|
|
308
|
+
| `"date_month"` | One Date (range)/Month (single) switch | One date range or one month |
|
|
309
|
+
|
|
310
|
+
Use `input_mode="date_month"` to add date ranges and single months to one sortable
|
|
311
|
+
list. One switch selects Date (range) or Month (single). Date (range) shows Start
|
|
312
|
+
and End inputs; Month (single) shows one month input. Press Add to append the
|
|
313
|
+
selection. A range is one item, not an expanded sequence. Use `"date"` or `"month"`
|
|
314
|
+
for a fixed precision with a separate Single/Range switch.
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
import streamlit as st
|
|
318
|
+
from streamlit_sortable_multiselect import sortable_multiselect
|
|
319
|
+
|
|
320
|
+
selected = sortable_multiselect(
|
|
321
|
+
"Reporting periods",
|
|
322
|
+
input_mode="date_month",
|
|
323
|
+
min_value="2026-01-01",
|
|
324
|
+
max_value="2027-12-31",
|
|
325
|
+
max_range_days=31,
|
|
326
|
+
default=["2026-10-01/2026-10-24", "2026-11"],
|
|
327
|
+
show_numbers=True,
|
|
328
|
+
key="reporting_periods",
|
|
329
|
+
)
|
|
330
|
+
st.write("Selected order:", selected)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Mixed mode initially shows the date-range inputs. Switching to Month (single)
|
|
334
|
+
clears unfinished inputs and keeps items already added to the sortable list.
|
|
335
|
+
|
|
336
|
+
### Calendar Labels
|
|
337
|
+
|
|
338
|
+
Override `calendar_labels` to display Japanese or another language. The settings
|
|
339
|
+
apply to switch text, the Add button, field labels, accessibility group names,
|
|
340
|
+
and validation messages. They do not change returned values. Supported keys and
|
|
341
|
+
defaults are:
|
|
342
|
+
|
|
343
|
+
| Key | Default | Used in |
|
|
344
|
+
| --- | --- | --- |
|
|
345
|
+
| `date_range` | `"Date (range)"` | `date_month` |
|
|
346
|
+
| `month_single` | `"Month (single)"` | `date_month` |
|
|
347
|
+
| `single` | `"Single"` | `date`, `month` |
|
|
348
|
+
| `range` | `"Range"` | `date`, `month` |
|
|
349
|
+
| `add` | `"Add"` | Add button |
|
|
350
|
+
| `start` | `"Start"` | Range start field and its accessible name |
|
|
351
|
+
| `end` | `"End"` | Range end field and its accessible name |
|
|
352
|
+
| `date` | `"Date"` | Single-date field and its accessible name |
|
|
353
|
+
| `month` | `"Month"` | Single-month field and its accessible name |
|
|
354
|
+
| `calendar_input` | `"Calendar input"` | Accessible name of the mixed-mode switch group |
|
|
355
|
+
| `selection_kind` | `"Selection kind"` | Accessible name of the Single/Range switch group |
|
|
356
|
+
| `invalid_value` | `"Choose a valid value within the allowed range, with start on or before end."` | Invalid date, bounds, or reversed range |
|
|
357
|
+
| `duplicate_value` | `"This item is already selected."` | Exact duplicate selection |
|
|
358
|
+
| `incomplete_selection` | `"Complete the selection before adding it."` | Add or Enter with missing input |
|
|
359
|
+
| `range_too_long` | `"Choose a date range of at most {max_range_days} days (including both endpoints)."` | Date range longer than `max_range_days` |
|
|
360
|
+
|
|
361
|
+
Only specify the labels you want to override. Unknown keys, non-string values,
|
|
362
|
+
and empty or whitespace-only labels raise an error. In `range_too_long`, every
|
|
363
|
+
`{max_range_days}` placeholder is replaced with the configured limit; a message
|
|
364
|
+
without the placeholder is also allowed. Native calendar localization follows
|
|
365
|
+
the browser and operating system. Set `empty_message` for the empty selected
|
|
366
|
+
list and `max_selections_placeholder` for the selection-count limit message.
|
|
367
|
+
|
|
368
|
+
### Japanese Example
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
import streamlit as st
|
|
372
|
+
from streamlit_sortable_multiselect import sortable_multiselect
|
|
373
|
+
|
|
374
|
+
selected = sortable_multiselect(
|
|
375
|
+
"Reporting periods",
|
|
376
|
+
input_mode="date_month",
|
|
377
|
+
min_value="2026-01-01",
|
|
378
|
+
max_value="2027-12-31",
|
|
379
|
+
max_range_days=31,
|
|
380
|
+
default=["2026-10-01/2026-10-24", "2026-11", "2027-01"],
|
|
381
|
+
show_numbers=True,
|
|
382
|
+
max_selections=8,
|
|
383
|
+
calendar_labels={
|
|
384
|
+
"date_range": "日付(範囲)",
|
|
385
|
+
"month_single": "年月(単一)",
|
|
386
|
+
"single": "単一",
|
|
387
|
+
"range": "範囲",
|
|
388
|
+
"add": "追加",
|
|
389
|
+
"start": "開始日",
|
|
390
|
+
"end": "終了日",
|
|
391
|
+
"date": "日付",
|
|
392
|
+
"month": "年月",
|
|
393
|
+
"calendar_input": "入力方法",
|
|
394
|
+
"selection_kind": "選択方法",
|
|
395
|
+
"invalid_value": "選択範囲を確認してください。",
|
|
396
|
+
"duplicate_value": "この項目は選択済みです。",
|
|
397
|
+
"incomplete_selection": "追加する値をすべて入力してください。",
|
|
398
|
+
"range_too_long": "{max_range_days}日以内で指定してください。",
|
|
399
|
+
},
|
|
400
|
+
empty_message="期間が選択されていません。",
|
|
401
|
+
max_selections_placeholder="選択数の上限に達しました。",
|
|
402
|
+
key="periods",
|
|
403
|
+
)
|
|
404
|
+
st.write(selected)
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Returned Values
|
|
408
|
+
|
|
409
|
+
Across the calendar modes, the returned `list[str]` retains the selected order
|
|
410
|
+
and identifies precision by format:
|
|
411
|
+
|
|
412
|
+
| Selection | Returned value |
|
|
413
|
+
| --- | --- |
|
|
414
|
+
| Date | `"2026-10-24"` |
|
|
415
|
+
| Month | `"2026-10"` |
|
|
416
|
+
| Date range | `"2026-10-01/2026-10-31"` |
|
|
417
|
+
| Month range | `"2026-10/2026-12"` |
|
|
418
|
+
|
|
419
|
+
Ranges include both endpoints, require the same precision at each end, and must
|
|
420
|
+
start on or before their end. Overlapping ranges are allowed; identical items
|
|
421
|
+
cannot be added twice. Dates and months may coexist in mixed mode. Switching
|
|
422
|
+
precision clears the unfinished input and preserves added items.
|
|
423
|
+
|
|
424
|
+
### Bounds and Range Length
|
|
425
|
+
|
|
426
|
+
Bounds are optional. A `YYYY-MM` lower bound expands to the first day of that
|
|
427
|
+
month and an upper bound to its last day. Month selections compare by month:
|
|
428
|
+
`min_value="2026-01-15"` still permits the month `"2026-01"`, while date selections
|
|
429
|
+
must be on or after January 15. Changing bounds or input mode removes selected
|
|
430
|
+
items that are no longer valid.
|
|
431
|
+
|
|
432
|
+
Set `max_range_days=31` to allow at most 31 days in each date range. Both endpoints
|
|
433
|
+
count: January 1 through January 31 is 31 days; January 1 through February 1 is
|
|
434
|
+
32 days and cannot be added. `max_range_days=1` allows only same-day date ranges.
|
|
435
|
+
The end picker uses the earlier of `max_value` and the start date plus
|
|
436
|
+
`max_range_days - 1` days. Invalid defaults and option metadata values raise an
|
|
437
|
+
error, and reducing the limit removes date ranges that exceed it. This limit
|
|
438
|
+
does not restrict single months or month ranges; `min_value` and `max_value`
|
|
439
|
+
still apply. It is available only in calendar modes.
|
|
440
|
+
|
|
441
|
+
| Setting | What it limits | Example |
|
|
442
|
+
| --- | --- | --- |
|
|
443
|
+
| `min_value` / `max_value` | Earliest/latest date or month that can be selected | `"2026-01-01"` through `"2027-12-31"` |
|
|
444
|
+
| `max_range_days` | Inclusive duration of each date range | `31` permits January 1 through January 31 |
|
|
445
|
+
| `max_selections` | Number of items in the list | `8` permits eight items, each a single value or a whole range |
|
|
446
|
+
|
|
447
|
+
Use a `datetime.date` object or an ISO string for bounds. `datetime.datetime`
|
|
448
|
+
objects are not accepted. Calendar defaults remain strings, such as
|
|
449
|
+
`"2026-10"` and `"2026-10-01/2026-10-31"`.
|
|
450
|
+
|
|
451
|
+
### Shared Settings
|
|
452
|
+
|
|
453
|
+
Existing ordering, numbering, colors, selection limits, disabled states,
|
|
454
|
+
`selected_position`, `default_revision`, and inline single selection apply to
|
|
455
|
+
calendar items. `options` is optional and can supply metadata for known calendar
|
|
456
|
+
values; it does not restrict which valid values the picker accepts. API
|
|
457
|
+
suggestions are available only in options mode. Search placeholders and dropdown
|
|
458
|
+
height do not affect calendar inputs; `max_selections_placeholder` appears as a
|
|
459
|
+
status message when the limit is reached.
|
|
460
|
+
|
|
461
|
+
### Browser Support
|
|
462
|
+
|
|
463
|
+
Date and month inputs use the browser's native picker, whose presentation and
|
|
464
|
+
language depend on the browser and operating system. Browsers without a native
|
|
465
|
+
month picker can accept `YYYY-MM` as text; the same validation applies. Calendar
|
|
466
|
+
values are strings without timezone conversion. See
|
|
467
|
+
[`examples/calendar_input.py`](examples/calendar_input.py) for mixed, date-only,
|
|
468
|
+
month-only, and form examples, including Japanese messages.
|
|
469
|
+
|
|
282
470
|
## API Suggestions
|
|
283
471
|
|
|
284
472
|
Set `suggestions_api_url` to request suggestions as the user types. Static `options` that match the query are shown first, followed by API results. Duplicate `value` entries prefer the static option.
|
|
@@ -327,6 +515,9 @@ Changing the input cancels the previous in-flight request. Set `options=[]` to
|
|
|
327
515
|
use only API results. Selected API values remain selected when a later query
|
|
328
516
|
returns different suggestions.
|
|
329
517
|
|
|
518
|
+
## Examples
|
|
519
|
+
|
|
520
|
+
See [`examples/README.md`](examples/README.md) for a description of each example.
|
|
330
521
|
Build the frontend before packaging or using release mode:
|
|
331
522
|
|
|
332
523
|
```bash
|
|
@@ -338,6 +529,7 @@ Run the example app:
|
|
|
338
529
|
|
|
339
530
|
```bash
|
|
340
531
|
streamlit run examples/basic.py
|
|
532
|
+
streamlit run examples/calendar_input.py
|
|
341
533
|
streamlit run examples/color_by_id.py
|
|
342
534
|
streamlit run examples/tooltip_labels.py
|
|
343
535
|
streamlit run examples/api_suggestions.py
|
|
@@ -364,6 +556,28 @@ browser, it works only when the browser and Streamlit run on the same machine.
|
|
|
364
556
|
For Docker, another computer, or a hosted Streamlit app, configure
|
|
365
557
|
`suggestions_api_url` with a browser-accessible HTTPS endpoint instead.
|
|
366
558
|
|
|
559
|
+
## Troubleshooting
|
|
560
|
+
|
|
561
|
+
If a new argument such as `calendar_labels` or `max_range_days` raises
|
|
562
|
+
`TypeError: sortable_multiselect() got an unexpected keyword argument ...`,
|
|
563
|
+
check the package path and function signature in the Python environment used
|
|
564
|
+
to run Streamlit:
|
|
565
|
+
|
|
566
|
+
```bash
|
|
567
|
+
python -c 'import inspect; import streamlit_sortable_multiselect as sms; print(sms.__file__); print(inspect.signature(sms.sortable_multiselect))'
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
For repository development, install the local package in that environment with
|
|
571
|
+
`python -m pip install -e ".[dev]"`. If the signature includes the argument but
|
|
572
|
+
an existing Streamlit process still reports it as unexpected, stop that process
|
|
573
|
+
and restart it to load the updated Python module:
|
|
574
|
+
|
|
575
|
+
```bash
|
|
576
|
+
python -m streamlit run examples/calendar_input.py
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
After rebuilding frontend assets, reload the app page to pick up the updated UI.
|
|
580
|
+
|
|
367
581
|
## Release
|
|
368
582
|
|
|
369
583
|
Build and check the distribution files:
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# streamlit-sortable-multiselect
|
|
2
2
|
|
|
3
|
-
A Streamlit custom component for searching, selecting, and reordering
|
|
3
|
+
A Streamlit custom component for searching, selecting, and reordering options,
|
|
4
|
+
dates, months, and date/month ranges. Selected items can be reordered by dragging
|
|
5
|
+
or using move buttons, and are returned as an ordered `list[str]`.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
@@ -30,6 +32,10 @@ npm run dev
|
|
|
30
32
|
|
|
31
33
|
## Usage
|
|
32
34
|
|
|
35
|
+
The default `input_mode="options"` provides searchable options. For calendar
|
|
36
|
+
inputs, see [Calendar Input](#calendar-input), including date ranges, single
|
|
37
|
+
months, selection bounds, and Japanese labels and messages.
|
|
38
|
+
|
|
33
39
|
```python
|
|
34
40
|
import streamlit as st
|
|
35
41
|
from streamlit_sortable_multiselect import sortable_multiselect
|
|
@@ -62,16 +68,22 @@ st.write(selected)
|
|
|
62
68
|
|
|
63
69
|
## Settings
|
|
64
70
|
|
|
65
|
-
`sortable_multiselect` returns
|
|
71
|
+
`sortable_multiselect` returns selected values as a `list[str]` in the current
|
|
72
|
+
display order. Calendar values use the formats in [Returned Values](#returned-values).
|
|
66
73
|
|
|
67
74
|
| Argument | Type | Default | Description |
|
|
68
75
|
| --- | --- | --- | --- |
|
|
69
76
|
| `label` | `str` | required | Label displayed above the component. |
|
|
70
|
-
| `options` | `Sequence[str \| Mapping[str, Any]]` |
|
|
71
|
-
| `default` | `Sequence[str] \| None` | `None` | Initially selected values, in the initial order. Changing the values or their order replaces the current selection.
|
|
77
|
+
| `options` | `Sequence[str \| Mapping[str, Any]]` | `()` | Available options. Each option can be a plain string, or a dictionary with `label`, `value`, and optional `icon_url` and `color`. Option values must be unique. In calendar modes, optional entries supply labels, icons, and colors for matching calendar values. |
|
|
78
|
+
| `default` | `Sequence[str] \| None` | `None` | Initially selected values, in the initial order. Changing the values or their order replaces the current selection. In options mode, values must exist in `options`. Calendar defaults must match the mode and bounds. Duplicates are not allowed. |
|
|
72
79
|
| `default_revision` | `str \| int \| None` | `None` | Change this value to reapply `default` when its values and order are unchanged. |
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
80
|
+
| `input_mode` | `str` | `"options"` | `"options"`, `"date"`, `"month"`, or `"date_month"`. Mixed mode offers one switch between date ranges and single months. Date-only and month-only modes offer Single/Range controls. |
|
|
81
|
+
| `min_value` | `str \| datetime.date \| None` | `None` | Inclusive lower bound in calendar modes. Accepts `YYYY-MM-DD`, `YYYY-MM`, or a date object. |
|
|
82
|
+
| `max_value` | `str \| datetime.date \| None` | `None` | Inclusive upper bound in calendar modes. Accepts `YYYY-MM-DD`, `YYYY-MM`, or a date object. |
|
|
83
|
+
| `max_range_days` | `int \| None` | `None` | Maximum number of days in each date range, including start and end. Must be positive. `None` means unlimited. Does not limit single values or month ranges. Requires a calendar mode. |
|
|
84
|
+
| `calendar_labels` | `Mapping[str, str] \| None` | `None` | Overrides calendar switches, the Add button, field labels, accessibility group names, and validation messages. See [Calendar Input](#calendar-input) for all keys. Unspecified entries retain their English defaults. |
|
|
85
|
+
| `placeholder` | `str` | `"Select..."` | Placeholder shown in the search/add input when options are available. Used in options mode. |
|
|
86
|
+
| `disabled` | `bool` | `False` | Disables searching, calendar inputs and switches, adding, removing, dragging, and move buttons. |
|
|
75
87
|
| `show_move_buttons` | `bool` | `True` | Shows up/down buttons on selected items. Drag sorting remains available unless `disabled=True`. |
|
|
76
88
|
| `show_numbers` | `bool` | `False` | Shows 1-based position numbers before selected item labels. |
|
|
77
89
|
| `base_color` | `str \| Mapping[str, str] \| None` | `None` | Fallback color for every selected item. See [Colors](#colors). |
|
|
@@ -82,13 +94,13 @@ st.write(selected)
|
|
|
82
94
|
| `tooltip_color` | `str \| Mapping[str, str] \| None` | `None` | Color of the tooltip shown for labels that do not fit. `None` uses the built-in dark tooltip. See [Labels](#labels). |
|
|
83
95
|
| `max_selections` | `int \| None` | `None` | Maximum number of selected items. `None` means no limit. Use `0` to prevent any selections. |
|
|
84
96
|
| `single_select_display` | `bool` | `False` | With `max_selections=1`, displays the selected item inside the search control and replaces it when another option is selected. |
|
|
85
|
-
| `max_selections_placeholder` | `str` | `"Selection limit reached"` | Placeholder shown when `max_selections` has been reached.
|
|
97
|
+
| `max_selections_placeholder` | `str` | `"Selection limit reached"` | Placeholder shown when `max_selections` has been reached in options mode; a status message in calendar modes. Takes precedence over other placeholders. Not shown in inline single-selection mode, which permits replacement. |
|
|
86
98
|
| `empty_message` | `str` | `"No items selected"` | Message shown where the selected list appears when no items are selected. |
|
|
87
|
-
| `no_options_placeholder` | `str` | `"No more options"` | Placeholder shown when every option is already selected and there are no more options to add. |
|
|
99
|
+
| `no_options_placeholder` | `str` | `"No more options"` | Placeholder shown when every option is already selected and there are no more options to add. Used in options mode. |
|
|
88
100
|
| `selected_position` | `str` | `"bottom"` | Position of the selected item list relative to the search/add input. Use `"bottom"` or `"top"`. |
|
|
89
101
|
| `icon_size` | `int` | `20` | Icon display size in pixels for `icon_url` images. Images are displayed inside a square area while preserving their aspect ratio. |
|
|
90
|
-
| `options_max_height` | `int` | `190` | Maximum height in pixels for the available options dropdown. |
|
|
91
|
-
| `suggestions_api_url` | `str \| None` | `None` | Absolute HTTP(S) endpoint used to fetch suggestions in the browser. `None` disables API suggestions. |
|
|
102
|
+
| `options_max_height` | `int` | `190` | Maximum height in pixels for the available options dropdown. Used in options mode. |
|
|
103
|
+
| `suggestions_api_url` | `str \| None` | `None` | Absolute HTTP(S) endpoint used to fetch suggestions in the browser. `None` disables API suggestions. Only supported in options mode. |
|
|
92
104
|
| `suggestions_query_param` | `str` | `"q"` | Query parameter name used to send the current search text. |
|
|
93
105
|
| `suggestions_response_path` | `str` | `""` | Dot-separated path to the suggestions array in the JSON response. Empty means the response root. |
|
|
94
106
|
| `suggestions_label_path` | `str` | `"label"` | Dot-separated path to each suggestion's display label. |
|
|
@@ -251,6 +263,182 @@ option replaces the current value instead of adding another one. Use the remove
|
|
|
251
263
|
inside the selected item to clear it. `single_select_display=True` without
|
|
252
264
|
`max_selections=1` raises `ValueError`.
|
|
253
265
|
|
|
266
|
+
In calendar modes, the selected item is displayed inside the calendar control.
|
|
267
|
+
Adding another calendar value replaces it. A date range counts as one selected item.
|
|
268
|
+
|
|
269
|
+
## Calendar Input
|
|
270
|
+
|
|
271
|
+
### Input Modes
|
|
272
|
+
|
|
273
|
+
`input_mode` selects the input method for the whole component:
|
|
274
|
+
|
|
275
|
+
| Mode | Picker controls | Items added |
|
|
276
|
+
| --- | --- | --- |
|
|
277
|
+
| `"options"` (default) | Searchable dropdown and optional API suggestions | Values from options or API results |
|
|
278
|
+
| `"date"` | Date input with a Single/Range switch | One date or one date range |
|
|
279
|
+
| `"month"` | Month input with a Single/Range switch | One month or one month range |
|
|
280
|
+
| `"date_month"` | One Date (range)/Month (single) switch | One date range or one month |
|
|
281
|
+
|
|
282
|
+
Use `input_mode="date_month"` to add date ranges and single months to one sortable
|
|
283
|
+
list. One switch selects Date (range) or Month (single). Date (range) shows Start
|
|
284
|
+
and End inputs; Month (single) shows one month input. Press Add to append the
|
|
285
|
+
selection. A range is one item, not an expanded sequence. Use `"date"` or `"month"`
|
|
286
|
+
for a fixed precision with a separate Single/Range switch.
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
import streamlit as st
|
|
290
|
+
from streamlit_sortable_multiselect import sortable_multiselect
|
|
291
|
+
|
|
292
|
+
selected = sortable_multiselect(
|
|
293
|
+
"Reporting periods",
|
|
294
|
+
input_mode="date_month",
|
|
295
|
+
min_value="2026-01-01",
|
|
296
|
+
max_value="2027-12-31",
|
|
297
|
+
max_range_days=31,
|
|
298
|
+
default=["2026-10-01/2026-10-24", "2026-11"],
|
|
299
|
+
show_numbers=True,
|
|
300
|
+
key="reporting_periods",
|
|
301
|
+
)
|
|
302
|
+
st.write("Selected order:", selected)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Mixed mode initially shows the date-range inputs. Switching to Month (single)
|
|
306
|
+
clears unfinished inputs and keeps items already added to the sortable list.
|
|
307
|
+
|
|
308
|
+
### Calendar Labels
|
|
309
|
+
|
|
310
|
+
Override `calendar_labels` to display Japanese or another language. The settings
|
|
311
|
+
apply to switch text, the Add button, field labels, accessibility group names,
|
|
312
|
+
and validation messages. They do not change returned values. Supported keys and
|
|
313
|
+
defaults are:
|
|
314
|
+
|
|
315
|
+
| Key | Default | Used in |
|
|
316
|
+
| --- | --- | --- |
|
|
317
|
+
| `date_range` | `"Date (range)"` | `date_month` |
|
|
318
|
+
| `month_single` | `"Month (single)"` | `date_month` |
|
|
319
|
+
| `single` | `"Single"` | `date`, `month` |
|
|
320
|
+
| `range` | `"Range"` | `date`, `month` |
|
|
321
|
+
| `add` | `"Add"` | Add button |
|
|
322
|
+
| `start` | `"Start"` | Range start field and its accessible name |
|
|
323
|
+
| `end` | `"End"` | Range end field and its accessible name |
|
|
324
|
+
| `date` | `"Date"` | Single-date field and its accessible name |
|
|
325
|
+
| `month` | `"Month"` | Single-month field and its accessible name |
|
|
326
|
+
| `calendar_input` | `"Calendar input"` | Accessible name of the mixed-mode switch group |
|
|
327
|
+
| `selection_kind` | `"Selection kind"` | Accessible name of the Single/Range switch group |
|
|
328
|
+
| `invalid_value` | `"Choose a valid value within the allowed range, with start on or before end."` | Invalid date, bounds, or reversed range |
|
|
329
|
+
| `duplicate_value` | `"This item is already selected."` | Exact duplicate selection |
|
|
330
|
+
| `incomplete_selection` | `"Complete the selection before adding it."` | Add or Enter with missing input |
|
|
331
|
+
| `range_too_long` | `"Choose a date range of at most {max_range_days} days (including both endpoints)."` | Date range longer than `max_range_days` |
|
|
332
|
+
|
|
333
|
+
Only specify the labels you want to override. Unknown keys, non-string values,
|
|
334
|
+
and empty or whitespace-only labels raise an error. In `range_too_long`, every
|
|
335
|
+
`{max_range_days}` placeholder is replaced with the configured limit; a message
|
|
336
|
+
without the placeholder is also allowed. Native calendar localization follows
|
|
337
|
+
the browser and operating system. Set `empty_message` for the empty selected
|
|
338
|
+
list and `max_selections_placeholder` for the selection-count limit message.
|
|
339
|
+
|
|
340
|
+
### Japanese Example
|
|
341
|
+
|
|
342
|
+
```python
|
|
343
|
+
import streamlit as st
|
|
344
|
+
from streamlit_sortable_multiselect import sortable_multiselect
|
|
345
|
+
|
|
346
|
+
selected = sortable_multiselect(
|
|
347
|
+
"Reporting periods",
|
|
348
|
+
input_mode="date_month",
|
|
349
|
+
min_value="2026-01-01",
|
|
350
|
+
max_value="2027-12-31",
|
|
351
|
+
max_range_days=31,
|
|
352
|
+
default=["2026-10-01/2026-10-24", "2026-11", "2027-01"],
|
|
353
|
+
show_numbers=True,
|
|
354
|
+
max_selections=8,
|
|
355
|
+
calendar_labels={
|
|
356
|
+
"date_range": "日付(範囲)",
|
|
357
|
+
"month_single": "年月(単一)",
|
|
358
|
+
"single": "単一",
|
|
359
|
+
"range": "範囲",
|
|
360
|
+
"add": "追加",
|
|
361
|
+
"start": "開始日",
|
|
362
|
+
"end": "終了日",
|
|
363
|
+
"date": "日付",
|
|
364
|
+
"month": "年月",
|
|
365
|
+
"calendar_input": "入力方法",
|
|
366
|
+
"selection_kind": "選択方法",
|
|
367
|
+
"invalid_value": "選択範囲を確認してください。",
|
|
368
|
+
"duplicate_value": "この項目は選択済みです。",
|
|
369
|
+
"incomplete_selection": "追加する値をすべて入力してください。",
|
|
370
|
+
"range_too_long": "{max_range_days}日以内で指定してください。",
|
|
371
|
+
},
|
|
372
|
+
empty_message="期間が選択されていません。",
|
|
373
|
+
max_selections_placeholder="選択数の上限に達しました。",
|
|
374
|
+
key="periods",
|
|
375
|
+
)
|
|
376
|
+
st.write(selected)
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Returned Values
|
|
380
|
+
|
|
381
|
+
Across the calendar modes, the returned `list[str]` retains the selected order
|
|
382
|
+
and identifies precision by format:
|
|
383
|
+
|
|
384
|
+
| Selection | Returned value |
|
|
385
|
+
| --- | --- |
|
|
386
|
+
| Date | `"2026-10-24"` |
|
|
387
|
+
| Month | `"2026-10"` |
|
|
388
|
+
| Date range | `"2026-10-01/2026-10-31"` |
|
|
389
|
+
| Month range | `"2026-10/2026-12"` |
|
|
390
|
+
|
|
391
|
+
Ranges include both endpoints, require the same precision at each end, and must
|
|
392
|
+
start on or before their end. Overlapping ranges are allowed; identical items
|
|
393
|
+
cannot be added twice. Dates and months may coexist in mixed mode. Switching
|
|
394
|
+
precision clears the unfinished input and preserves added items.
|
|
395
|
+
|
|
396
|
+
### Bounds and Range Length
|
|
397
|
+
|
|
398
|
+
Bounds are optional. A `YYYY-MM` lower bound expands to the first day of that
|
|
399
|
+
month and an upper bound to its last day. Month selections compare by month:
|
|
400
|
+
`min_value="2026-01-15"` still permits the month `"2026-01"`, while date selections
|
|
401
|
+
must be on or after January 15. Changing bounds or input mode removes selected
|
|
402
|
+
items that are no longer valid.
|
|
403
|
+
|
|
404
|
+
Set `max_range_days=31` to allow at most 31 days in each date range. Both endpoints
|
|
405
|
+
count: January 1 through January 31 is 31 days; January 1 through February 1 is
|
|
406
|
+
32 days and cannot be added. `max_range_days=1` allows only same-day date ranges.
|
|
407
|
+
The end picker uses the earlier of `max_value` and the start date plus
|
|
408
|
+
`max_range_days - 1` days. Invalid defaults and option metadata values raise an
|
|
409
|
+
error, and reducing the limit removes date ranges that exceed it. This limit
|
|
410
|
+
does not restrict single months or month ranges; `min_value` and `max_value`
|
|
411
|
+
still apply. It is available only in calendar modes.
|
|
412
|
+
|
|
413
|
+
| Setting | What it limits | Example |
|
|
414
|
+
| --- | --- | --- |
|
|
415
|
+
| `min_value` / `max_value` | Earliest/latest date or month that can be selected | `"2026-01-01"` through `"2027-12-31"` |
|
|
416
|
+
| `max_range_days` | Inclusive duration of each date range | `31` permits January 1 through January 31 |
|
|
417
|
+
| `max_selections` | Number of items in the list | `8` permits eight items, each a single value or a whole range |
|
|
418
|
+
|
|
419
|
+
Use a `datetime.date` object or an ISO string for bounds. `datetime.datetime`
|
|
420
|
+
objects are not accepted. Calendar defaults remain strings, such as
|
|
421
|
+
`"2026-10"` and `"2026-10-01/2026-10-31"`.
|
|
422
|
+
|
|
423
|
+
### Shared Settings
|
|
424
|
+
|
|
425
|
+
Existing ordering, numbering, colors, selection limits, disabled states,
|
|
426
|
+
`selected_position`, `default_revision`, and inline single selection apply to
|
|
427
|
+
calendar items. `options` is optional and can supply metadata for known calendar
|
|
428
|
+
values; it does not restrict which valid values the picker accepts. API
|
|
429
|
+
suggestions are available only in options mode. Search placeholders and dropdown
|
|
430
|
+
height do not affect calendar inputs; `max_selections_placeholder` appears as a
|
|
431
|
+
status message when the limit is reached.
|
|
432
|
+
|
|
433
|
+
### Browser Support
|
|
434
|
+
|
|
435
|
+
Date and month inputs use the browser's native picker, whose presentation and
|
|
436
|
+
language depend on the browser and operating system. Browsers without a native
|
|
437
|
+
month picker can accept `YYYY-MM` as text; the same validation applies. Calendar
|
|
438
|
+
values are strings without timezone conversion. See
|
|
439
|
+
[`examples/calendar_input.py`](examples/calendar_input.py) for mixed, date-only,
|
|
440
|
+
month-only, and form examples, including Japanese messages.
|
|
441
|
+
|
|
254
442
|
## API Suggestions
|
|
255
443
|
|
|
256
444
|
Set `suggestions_api_url` to request suggestions as the user types. Static `options` that match the query are shown first, followed by API results. Duplicate `value` entries prefer the static option.
|
|
@@ -299,6 +487,9 @@ Changing the input cancels the previous in-flight request. Set `options=[]` to
|
|
|
299
487
|
use only API results. Selected API values remain selected when a later query
|
|
300
488
|
returns different suggestions.
|
|
301
489
|
|
|
490
|
+
## Examples
|
|
491
|
+
|
|
492
|
+
See [`examples/README.md`](examples/README.md) for a description of each example.
|
|
302
493
|
Build the frontend before packaging or using release mode:
|
|
303
494
|
|
|
304
495
|
```bash
|
|
@@ -310,6 +501,7 @@ Run the example app:
|
|
|
310
501
|
|
|
311
502
|
```bash
|
|
312
503
|
streamlit run examples/basic.py
|
|
504
|
+
streamlit run examples/calendar_input.py
|
|
313
505
|
streamlit run examples/color_by_id.py
|
|
314
506
|
streamlit run examples/tooltip_labels.py
|
|
315
507
|
streamlit run examples/api_suggestions.py
|
|
@@ -336,6 +528,28 @@ browser, it works only when the browser and Streamlit run on the same machine.
|
|
|
336
528
|
For Docker, another computer, or a hosted Streamlit app, configure
|
|
337
529
|
`suggestions_api_url` with a browser-accessible HTTPS endpoint instead.
|
|
338
530
|
|
|
531
|
+
## Troubleshooting
|
|
532
|
+
|
|
533
|
+
If a new argument such as `calendar_labels` or `max_range_days` raises
|
|
534
|
+
`TypeError: sortable_multiselect() got an unexpected keyword argument ...`,
|
|
535
|
+
check the package path and function signature in the Python environment used
|
|
536
|
+
to run Streamlit:
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
python -c 'import inspect; import streamlit_sortable_multiselect as sms; print(sms.__file__); print(inspect.signature(sms.sortable_multiselect))'
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
For repository development, install the local package in that environment with
|
|
543
|
+
`python -m pip install -e ".[dev]"`. If the signature includes the argument but
|
|
544
|
+
an existing Streamlit process still reports it as unexpected, stop that process
|
|
545
|
+
and restart it to load the updated Python module:
|
|
546
|
+
|
|
547
|
+
```bash
|
|
548
|
+
python -m streamlit run examples/calendar_input.py
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
After rebuilding frontend assets, reload the app page to pick up the updated UI.
|
|
552
|
+
|
|
339
553
|
## Release
|
|
340
554
|
|
|
341
555
|
Build and check the distribution files:
|
{streamlit_sortable_multiselect-0.7.9 → streamlit_sortable_multiselect-0.7.10}/pyproject.toml
RENAMED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "streamlit-sortable-multiselect"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.10"
|
|
8
8
|
description = "A Streamlit custom component for selecting and reordering multiple string values."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|