streamlit-sortable-multiselect 0.5.0__tar.gz → 0.6.0__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.
Files changed (16) hide show
  1. {streamlit_sortable_multiselect-0.5.0/streamlit_sortable_multiselect.egg-info → streamlit_sortable_multiselect-0.6.0}/PKG-INFO +3 -1
  2. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/README.md +2 -0
  3. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/pyproject.toml +1 -1
  4. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/streamlit_sortable_multiselect/__init__.py +25 -1
  5. streamlit_sortable_multiselect-0.5.0/streamlit_sortable_multiselect/frontend/build/assets/index-T2Sw6Vor.js → streamlit_sortable_multiselect-0.6.0/streamlit_sortable_multiselect/frontend/build/assets/index-Dg3JH2iL.js +14 -14
  6. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/streamlit_sortable_multiselect/frontend/build/index.html +1 -1
  7. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0/streamlit_sortable_multiselect.egg-info}/PKG-INFO +3 -1
  8. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/streamlit_sortable_multiselect.egg-info/SOURCES.txt +1 -1
  9. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/tests/test_wrapper.py +24 -0
  10. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/LICENSE +0 -0
  11. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/MANIFEST.in +0 -0
  12. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/setup.cfg +0 -0
  13. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/streamlit_sortable_multiselect/frontend/build/assets/index-DU2qFdlq.css +0 -0
  14. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/streamlit_sortable_multiselect.egg-info/dependency_links.txt +0 -0
  15. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/streamlit_sortable_multiselect.egg-info/requires.txt +0 -0
  16. {streamlit_sortable_multiselect-0.5.0 → streamlit_sortable_multiselect-0.6.0}/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.5.0
3
+ Version: 0.6.0
4
4
  Summary: A Streamlit custom component for selecting and reordering multiple string values.
5
5
  Author: Developer
6
6
  License-Expression: MIT
@@ -70,6 +70,8 @@ selected = sortable_multiselect(
70
70
  show_numbers=True,
71
71
  base_color="#eef2ff",
72
72
  order_colors={1: "#fee2e2", 2: "#dcfce7"},
73
+ max_selections=3,
74
+ max_selections_placeholder="Choose up to 3 frameworks",
73
75
  )
74
76
 
75
77
  st.write(selected)
@@ -42,6 +42,8 @@ selected = sortable_multiselect(
42
42
  show_numbers=True,
43
43
  base_color="#eef2ff",
44
44
  order_colors={1: "#fee2e2", 2: "#dcfce7"},
45
+ max_selections=3,
46
+ max_selections_placeholder="Choose up to 3 frameworks",
45
47
  )
46
48
 
47
49
  st.write(selected)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "streamlit-sortable-multiselect"
7
- version = "0.5.0"
7
+ version = "0.6.0"
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"
@@ -8,7 +8,7 @@ from typing import Any, Iterable, Mapping, Sequence, cast
8
8
 
9
9
  import streamlit.components.v1 as components
10
10
 
11
- __version__ = "0.5.0"
11
+ __version__ = "0.6.0"
12
12
  __all__ = ["sortable_multiselect"]
13
13
 
14
14
  _COMPONENT_NAME = "streamlit_sortable_multiselect"
@@ -85,6 +85,16 @@ def _validate_order_colors(order_colors: Mapping[int, str] | None) -> dict[int,
85
85
  return result
86
86
 
87
87
 
88
+ def _validate_max_selections(max_selections: int | None) -> int | None:
89
+ if max_selections is None:
90
+ return None
91
+ if isinstance(max_selections, bool) or not isinstance(max_selections, int):
92
+ raise TypeError("max_selections must be an integer or None.")
93
+ if max_selections < 0:
94
+ raise ValueError("max_selections must be 0 or greater.")
95
+ return max_selections
96
+
97
+
88
98
  def sortable_multiselect(
89
99
  label: str,
90
100
  options: Sequence[str | Mapping[str, Any]],
@@ -95,6 +105,8 @@ def sortable_multiselect(
95
105
  show_numbers: bool = False,
96
106
  base_color: str | None = None,
97
107
  order_colors: Mapping[int, str] | None = None,
108
+ max_selections: int | None = None,
109
+ max_selections_placeholder: str = "Selection limit reached",
98
110
  key: str | None = None,
99
111
  ) -> list[str]:
100
112
  """Select multiple string values and return them in user-defined order.
@@ -119,6 +131,10 @@ def sortable_multiselect(
119
131
  Background color applied to selected items.
120
132
  order_colors:
121
133
  Per-position background colors keyed by 1-based selected item position.
134
+ max_selections:
135
+ Maximum number of selected items. None means no limit.
136
+ max_selections_placeholder:
137
+ Placeholder text shown when the maximum selection count is reached.
122
138
  key:
123
139
  Optional Streamlit component key.
124
140
  """
@@ -126,6 +142,8 @@ def sortable_multiselect(
126
142
  raise TypeError("label must be a string.")
127
143
  if not isinstance(placeholder, str):
128
144
  raise TypeError("placeholder must be a string.")
145
+ if not isinstance(max_selections_placeholder, str):
146
+ raise TypeError("max_selections_placeholder must be a string.")
129
147
  if not isinstance(disabled, bool):
130
148
  raise TypeError("disabled must be a bool.")
131
149
  if not isinstance(show_move_buttons, bool):
@@ -139,6 +157,7 @@ def sortable_multiselect(
139
157
  option_values = [option["value"] for option in option_items]
140
158
  default_values = _validate_string_sequence("default", default)
141
159
  order_color_values = _validate_order_colors(order_colors)
160
+ max_selection_count = _validate_max_selections(max_selections)
142
161
 
143
162
  duplicate_options = sorted({value for value in option_values if option_values.count(value) > 1})
144
163
  if duplicate_options:
@@ -153,6 +172,9 @@ def sortable_multiselect(
153
172
  if duplicate_defaults:
154
173
  raise ValueError("default must not contain duplicate values.")
155
174
 
175
+ if max_selection_count is not None and len(default_values) > max_selection_count:
176
+ raise ValueError("default must not contain more values than max_selections.")
177
+
156
178
  component_value = _component_func(
157
179
  label=label,
158
180
  options=option_items,
@@ -163,6 +185,8 @@ def sortable_multiselect(
163
185
  show_numbers=show_numbers,
164
186
  base_color=base_color,
165
187
  order_colors=order_color_values,
188
+ max_selections=max_selection_count,
189
+ max_selections_placeholder=max_selections_placeholder,
166
190
  key=key,
167
191
  default=default_values,
168
192
  )