streamlit-react-components 1.8.1.2__py3-none-any.whl → 1.8.1.3__py3-none-any.whl

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.
@@ -1,8 +1,9 @@
1
1
  """CheckboxGroup component - A group of checkboxes."""
2
2
 
3
+ import streamlit as st
3
4
  import streamlit.components.v1 as components
4
5
  from pathlib import Path
5
- from typing import Dict, Any, List, Optional
6
+ from typing import Dict, Any, List, Optional, Callable
6
7
 
7
8
  _FRONTEND_DIR = Path(__file__).parent.parent / "_frontend"
8
9
 
@@ -16,6 +17,9 @@ def checkbox_group(
16
17
  items: List[Dict[str, Any]],
17
18
  label: str = "",
18
19
  layout: str = "vertical",
20
+ on_change: Optional[Callable] = None,
21
+ args: Optional[tuple] = None,
22
+ kwargs: Optional[Dict[str, Any]] = None,
19
23
  style: Optional[Dict[str, Any]] = None,
20
24
  class_name: str = "",
21
25
  theme: Optional[Dict[str, Any]] = None,
@@ -33,6 +37,9 @@ def checkbox_group(
33
37
  - disabled: Whether checkbox is disabled (optional, default False)
34
38
  label: Optional group label
35
39
  layout: Layout direction - "vertical" (default) or "horizontal"
40
+ on_change: Optional callback function called when selection changes
41
+ args: Optional tuple of args to pass to on_change callback
42
+ kwargs: Optional dict of kwargs to pass to on_change callback
36
43
  style: Inline CSS styles as a dictionary
37
44
  class_name: Tailwind CSS classes
38
45
  theme: Optional theme dictionary. If None, uses active global theme.
@@ -40,7 +47,7 @@ def checkbox_group(
40
47
  defer_update: If True, don't trigger Streamlit rerun on change.
41
48
  Value is stored locally and sent on next rerun (e.g., Apply button).
42
49
  Requires 'key' to be set.
43
- key: Unique key for the component (required if defer_update=True)
50
+ key: Unique key for the component (required if on_change or defer_update is used)
44
51
 
45
52
  Returns:
46
53
  List of checked item IDs
@@ -97,4 +104,19 @@ def checkbox_group(
97
104
  key=key,
98
105
  default=default_checked,
99
106
  )
100
- return result if result is not None else default_checked
107
+
108
+ final_result = result if result is not None else default_checked
109
+
110
+ # Execute on_change callback if value changed
111
+ if on_change and key:
112
+ prev_key = f"_checkbox_group_prev_{key}"
113
+ prev_value = st.session_state.get(prev_key)
114
+
115
+ # Only fire callback if value actually changed (not on first render)
116
+ if prev_value is not None and set(final_result) != set(prev_value):
117
+ on_change(*(args or ()), **(kwargs or {}))
118
+
119
+ # Always update previous value
120
+ st.session_state[prev_key] = final_result
121
+
122
+ return final_result
@@ -1,9 +1,10 @@
1
1
  """FormDateSlider component - A date slider with optional range selection."""
2
2
 
3
+ import streamlit as st
3
4
  import streamlit.components.v1 as components
4
5
  from pathlib import Path
5
6
  from datetime import date, timedelta
6
- from typing import Dict, Any, Optional, Union, Tuple
7
+ from typing import Dict, Any, Optional, Union, Tuple, Callable
7
8
 
8
9
  _FRONTEND_DIR = Path(__file__).parent.parent / "_frontend"
9
10
 
@@ -22,6 +23,9 @@ def form_date_slider(
22
23
  step: Optional[timedelta] = None,
23
24
  format: str = "YYYY-MM",
24
25
  color: str = "blue",
26
+ on_change: Optional[Callable] = None,
27
+ args: Optional[tuple] = None,
28
+ kwargs: Optional[Dict[str, Any]] = None,
25
29
  style: Optional[Dict[str, Any]] = None,
26
30
  class_name: str = "",
27
31
  theme: Optional[Dict[str, Any]] = None,
@@ -43,11 +47,14 @@ def form_date_slider(
43
47
  Defaults to timedelta(days=1)
44
48
  format: Display format string - "YYYY-MM", "YYYY-MM-DD", "MMM YYYY", etc.
45
49
  color: Accent color - preset name or hex value
50
+ on_change: Optional callback function called when value changes
51
+ args: Optional tuple of args to pass to on_change callback
52
+ kwargs: Optional dict of kwargs to pass to on_change callback
46
53
  style: Inline CSS styles as a dictionary
47
54
  class_name: Tailwind CSS classes
48
55
  theme: Optional theme dictionary. If None, uses active global theme.
49
56
  defer_update: If True, don't trigger Streamlit rerun on change.
50
- key: Unique key for the component
57
+ key: Unique key for the component (required if on_change or defer_update is used)
51
58
 
52
59
  Returns:
53
60
  Single date if value was a date, or tuple (start, end) if value was a tuple
@@ -135,13 +142,28 @@ def form_date_slider(
135
142
 
136
143
  # Parse result back to date objects
137
144
  if result is None:
138
- return value
139
-
140
- if is_range:
145
+ final_result = value
146
+ elif is_range:
141
147
  if isinstance(result, (list, tuple)) and len(result) == 2:
142
- return (date.fromisoformat(result[0]), date.fromisoformat(result[1]))
143
- return value
148
+ final_result = (date.fromisoformat(result[0]), date.fromisoformat(result[1]))
149
+ else:
150
+ final_result = value
144
151
  else:
145
152
  if isinstance(result, str):
146
- return date.fromisoformat(result)
147
- return value
153
+ final_result = date.fromisoformat(result)
154
+ else:
155
+ final_result = value
156
+
157
+ # Execute on_change callback if value changed
158
+ if on_change and key:
159
+ prev_key = f"_form_date_slider_prev_{key}"
160
+ prev_value = st.session_state.get(prev_key)
161
+
162
+ # Only fire callback if value actually changed (not on first render)
163
+ if prev_value is not None and final_result != prev_value:
164
+ on_change(*(args or ()), **(kwargs or {}))
165
+
166
+ # Always update previous value
167
+ st.session_state[prev_key] = final_result
168
+
169
+ return final_result
@@ -1,8 +1,9 @@
1
1
  """FormSelect component - A styled dropdown select input."""
2
2
 
3
+ import streamlit as st
3
4
  import streamlit.components.v1 as components
4
5
  from pathlib import Path
5
- from typing import Dict, Any, List, Optional, Union
6
+ from typing import Dict, Any, List, Optional, Union, Callable
6
7
 
7
8
  _FRONTEND_DIR = Path(__file__).parent.parent / "_frontend"
8
9
 
@@ -17,6 +18,9 @@ def form_select(
17
18
  options: List[Union[str, Dict[str, str]]],
18
19
  value: str = "",
19
20
  groups: Optional[List[Dict[str, Any]]] = None,
21
+ on_change: Optional[Callable] = None,
22
+ args: Optional[tuple] = None,
23
+ kwargs: Optional[Dict[str, Any]] = None,
20
24
  style: Optional[Dict[str, Any]] = None,
21
25
  class_name: str = "",
22
26
  theme: Optional[Dict[str, Any]] = None,
@@ -33,6 +37,9 @@ def form_select(
33
37
  groups: Optional list of option groups, each with:
34
38
  - label: Group header text
35
39
  - options: List of options in this group
40
+ on_change: Optional callback function called when value changes
41
+ args: Optional tuple of args to pass to on_change callback
42
+ kwargs: Optional dict of kwargs to pass to on_change callback
36
43
  style: Inline CSS styles as a dictionary
37
44
  class_name: Tailwind CSS classes
38
45
  theme: Optional theme dictionary. If None, uses active global theme.
@@ -40,7 +47,7 @@ def form_select(
40
47
  defer_update: If True, don't trigger Streamlit rerun on change.
41
48
  Value is stored locally and sent on next rerun (e.g., Apply button).
42
49
  Requires 'key' to be set.
43
- key: Unique key for the component (required if defer_update=True)
50
+ key: Unique key for the component (required if on_change or defer_update is used)
44
51
 
45
52
  Returns:
46
53
  The currently selected value
@@ -53,24 +60,28 @@ def form_select(
53
60
  value="AML_14"
54
61
  )
55
62
 
56
- # With option groups
57
- version = form_select(
58
- label="Base On",
59
- groups=[
60
- {"label": "Baselines", "options": ["Baseline v7"]},
61
- {"label": "Scenarios", "options": ["Q2 Demand Surge"]}
62
- ]
63
+ # With on_change callback
64
+ def handle_change():
65
+ st.write("Selection changed!")
66
+
67
+ site = form_select(
68
+ label="Site",
69
+ options=["AML_14", "ADL", "Devens"],
70
+ on_change=handle_change,
71
+ key="site_select"
63
72
  )
64
73
 
65
- # Deferred update (no rerun until Apply button clicked)
74
+ # With on_change and args
75
+ def handle_change(component_name):
76
+ st.write(f"{component_name} changed!")
77
+
66
78
  site = form_select(
67
79
  label="Site",
68
80
  options=["AML_14", "ADL", "Devens"],
69
- defer_update=True,
81
+ on_change=handle_change,
82
+ args=("site_select",),
70
83
  key="site_select"
71
84
  )
72
- if st.button("Apply"):
73
- st.rerun()
74
85
  """
75
86
  # Resolve theme (None = use global, False = disable)
76
87
  from ..themes import get_active_theme
@@ -92,4 +103,19 @@ def form_select(
92
103
  key=key,
93
104
  default=value,
94
105
  )
95
- return result if result is not None else value
106
+
107
+ final_result = result if result is not None else value
108
+
109
+ # Execute on_change callback if value changed
110
+ if on_change and key:
111
+ prev_key = f"_form_select_prev_{key}"
112
+ prev_value = st.session_state.get(prev_key)
113
+
114
+ # Only fire callback if value actually changed (not on first render)
115
+ if prev_value is not None and final_result != prev_value:
116
+ on_change(*(args or ()), **(kwargs or {}))
117
+
118
+ # Always update previous value
119
+ st.session_state[prev_key] = final_result
120
+
121
+ return final_result
@@ -1,8 +1,9 @@
1
1
  """FormSlider component - A styled range slider input."""
2
2
 
3
+ import streamlit as st
3
4
  import streamlit.components.v1 as components
4
5
  from pathlib import Path
5
- from typing import Dict, Any, Optional
6
+ from typing import Dict, Any, Optional, Callable
6
7
 
7
8
  _FRONTEND_DIR = Path(__file__).parent.parent / "_frontend"
8
9
 
@@ -20,6 +21,9 @@ def form_slider(
20
21
  step: float = 1,
21
22
  unit: str = "",
22
23
  color: str = "blue",
24
+ on_change: Optional[Callable] = None,
25
+ args: Optional[tuple] = None,
26
+ kwargs: Optional[Dict[str, Any]] = None,
23
27
  style: Optional[Dict[str, Any]] = None,
24
28
  class_name: str = "",
25
29
  theme: Optional[Dict[str, Any]] = None,
@@ -38,6 +42,9 @@ def form_slider(
38
42
  unit: Unit suffix to display (e.g., "%", "hrs")
39
43
  color: Accent color - preset name ("blue", "green", "red", "yellow",
40
44
  "purple", "slate") or hex value (e.g., "#94a3b8")
45
+ on_change: Optional callback function called when value changes
46
+ args: Optional tuple of args to pass to on_change callback
47
+ kwargs: Optional dict of kwargs to pass to on_change callback
41
48
  style: Inline CSS styles as a dictionary
42
49
  class_name: Tailwind CSS classes
43
50
  theme: Optional theme dictionary. If None, uses active global theme.
@@ -45,7 +52,7 @@ def form_slider(
45
52
  defer_update: If True, don't trigger Streamlit rerun on change.
46
53
  Value is stored locally and sent on next rerun (e.g., Apply button).
47
54
  Requires 'key' to be set.
48
- key: Unique key for the component (required if defer_update=True)
55
+ key: Unique key for the component (required if on_change or defer_update is used)
49
56
 
50
57
  Returns:
51
58
  The current slider value
@@ -105,4 +112,19 @@ def form_slider(
105
112
  key=key,
106
113
  default=value,
107
114
  )
108
- return float(result) if result is not None else value
115
+
116
+ final_result = float(result) if result is not None else value
117
+
118
+ # Execute on_change callback if value changed
119
+ if on_change and key:
120
+ prev_key = f"_form_slider_prev_{key}"
121
+ prev_value = st.session_state.get(prev_key)
122
+
123
+ # Only fire callback if value actually changed (not on first render)
124
+ if prev_value is not None and final_result != prev_value:
125
+ on_change(*(args or ()), **(kwargs or {}))
126
+
127
+ # Always update previous value
128
+ st.session_state[prev_key] = final_result
129
+
130
+ return final_result
@@ -1,8 +1,9 @@
1
1
  """RadioGroup component - A group of radio buttons for single selection."""
2
2
 
3
+ import streamlit as st
3
4
  import streamlit.components.v1 as components
4
5
  from pathlib import Path
5
- from typing import Dict, Any, List, Optional
6
+ from typing import Dict, Any, List, Optional, Callable
6
7
 
7
8
  _FRONTEND_DIR = Path(__file__).parent.parent / "_frontend"
8
9
 
@@ -16,6 +17,9 @@ def radio_group(
16
17
  items: List[Dict[str, Any]],
17
18
  label: str = "",
18
19
  layout: str = "vertical",
20
+ on_change: Optional[Callable] = None,
21
+ args: Optional[tuple] = None,
22
+ kwargs: Optional[Dict[str, Any]] = None,
19
23
  style: Optional[Dict[str, Any]] = None,
20
24
  class_name: str = "",
21
25
  theme: Optional[Dict[str, Any]] = None,
@@ -33,6 +37,9 @@ def radio_group(
33
37
  - disabled: Whether item is disabled (optional, default False)
34
38
  label: Optional group label
35
39
  layout: Layout direction - "vertical" (default) or "horizontal"
40
+ on_change: Optional callback function called when selection changes
41
+ args: Optional tuple of args to pass to on_change callback
42
+ kwargs: Optional dict of kwargs to pass to on_change callback
36
43
  style: Inline CSS styles as a dictionary
37
44
  class_name: Tailwind CSS classes
38
45
  theme: Optional theme dictionary. If None, uses active global theme.
@@ -40,7 +47,7 @@ def radio_group(
40
47
  defer_update: If True, don't trigger Streamlit rerun on change.
41
48
  Value is stored locally and sent on next rerun (e.g., Apply button).
42
49
  Requires 'key' to be set.
43
- key: Unique key for the component (required if defer_update=True)
50
+ key: Unique key for the component (required if on_change or defer_update is used)
44
51
 
45
52
  Returns:
46
53
  ID of the selected item (string), or None if nothing selected
@@ -92,4 +99,19 @@ def radio_group(
92
99
  key=key,
93
100
  default=default_selected,
94
101
  )
95
- return result if result is not None else default_selected
102
+
103
+ final_result = result if result is not None else default_selected
104
+
105
+ # Execute on_change callback if value changed
106
+ if on_change and key:
107
+ prev_key = f"_radio_group_prev_{key}"
108
+ prev_value = st.session_state.get(prev_key)
109
+
110
+ # Only fire callback if value actually changed (not on first render)
111
+ if prev_value is not None and final_result != prev_value:
112
+ on_change(*(args or ()), **(kwargs or {}))
113
+
114
+ # Always update previous value
115
+ st.session_state[prev_key] = final_result
116
+
117
+ return final_result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: streamlit-react-components
3
- Version: 1.8.1.2
3
+ Version: 1.8.1.3
4
4
  Summary: Reusable React-based Streamlit components with Tailwind CSS styling
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/your-org/streamlit-react-components
@@ -17,12 +17,12 @@ streamlit_react_components/common/smart_chart.py,sha256=kYzdPTpgdJLfX6CUXuT8fUMR
17
17
  streamlit_react_components/common/stat_card.py,sha256=-C-73nglpPFbtliK7JfZLQExc9N1wYsyTjDsTXHVjKQ,4758
18
18
  streamlit_react_components/common/step_indicator.py,sha256=RjoBdgWrhrUc2Rs5lTxs_4ocBuMJDI8ELNIQE_0Y7js,1817
19
19
  streamlit_react_components/form/__init__.py,sha256=urk_QJxnOrlMoHBTbCUGfjwxCbNs5lTFIoexUYB4AsA,349
20
- streamlit_react_components/form/checkbox_group.py,sha256=yF2g991jPwOIk28ugyJ8T7-K2kQnCUXdymmIxzuV74g,3325
21
- streamlit_react_components/form/form_date_slider.py,sha256=YB--bP0M_qgfcCyZ5A7AAYhgMIEXVtntC4vEmoTZh6U,4819
22
- streamlit_react_components/form/form_select.py,sha256=bzrfFtE8gtMszqL77hUa4TBa5LvUI88RxcNhwt1ojx0,3021
23
- streamlit_react_components/form/form_slider.py,sha256=vK8iqlWNnly0UiSdI71fxkjNZK0ZJlUC8DCkjBcULmI,3143
24
- streamlit_react_components/form/radio_group.py,sha256=1mL6FOhBfiPQSV6owUl7rcl0AgR5xIE-RmfiKPb-fVk,3217
25
- streamlit_react_components-1.8.1.2.dist-info/METADATA,sha256=_1ukQctQERr4UBLunENmwTlcwHJ06-qmSwRLCMeCWy4,21679
26
- streamlit_react_components-1.8.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
27
- streamlit_react_components-1.8.1.2.dist-info/top_level.txt,sha256=3JFrl15-Uewx3BFMSzqrBufF9GmTS1LDKfShmg0R9VE,27
28
- streamlit_react_components-1.8.1.2.dist-info/RECORD,,
20
+ streamlit_react_components/form/checkbox_group.py,sha256=P3UJ0JrPpkx_yMDy0bzEt7VyIEmG1iB847a9-TKfPbA,4219
21
+ streamlit_react_components/form/form_date_slider.py,sha256=FpKvY7uV5uTsLcjOQwPX_IQL97I4Jg7t-e-RVf1329Y,5801
22
+ streamlit_react_components/form/form_select.py,sha256=bJFyN9at6nTyDcev_7l7pYDW_KhXHG2D7lSfNxPIPTQ,3964
23
+ streamlit_react_components/form/form_slider.py,sha256=ZL1fCLCfanolmxOzuEQo28D1WYFy17uH0EuwbFwD7f8,4020
24
+ streamlit_react_components/form/radio_group.py,sha256=ktmB37APMLiaUJGmP38hlA6I_diPyexkcNGXCvDXjw8,4098
25
+ streamlit_react_components-1.8.1.3.dist-info/METADATA,sha256=88SfH9dY_2E48T-9gAsJMOFqLcY99NNB_rh5aZfWTdE,21679
26
+ streamlit_react_components-1.8.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
27
+ streamlit_react_components-1.8.1.3.dist-info/top_level.txt,sha256=3JFrl15-Uewx3BFMSzqrBufF9GmTS1LDKfShmg0R9VE,27
28
+ streamlit_react_components-1.8.1.3.dist-info/RECORD,,