streamlit-react-components 0.1.0__py3-none-any.whl → 1.0.4__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.
@@ -0,0 +1,877 @@
1
+ Metadata-Version: 2.4
2
+ Name: streamlit-react-components
3
+ Version: 1.0.4
4
+ Summary: Reusable React-based Streamlit components with Tailwind CSS styling
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/your-org/streamlit-react-components
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: streamlit>=1.24.0
19
+
20
+ # Streamlit React Components
21
+
22
+ A collection of 12 reusable React-based Streamlit components with Tailwind CSS styling. All components support custom inline styles and Tailwind class names.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install streamlit-react-components
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ ```python
33
+ import streamlit as st
34
+ from streamlit_react_components import (
35
+ panel, section_header, stat_card, metric_row,
36
+ data_table, step_indicator, button_group, chart_legend,
37
+ plotly_chart, form_select, form_slider, checkbox_group
38
+ )
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Styling
44
+
45
+ All components accept two styling parameters:
46
+
47
+ | Parameter | Type | Description |
48
+ |-----------|------|-------------|
49
+ | `style` | `dict` | Inline CSS as Python dict (e.g., `{"background": "#1e293b", "padding": "16px"}`) |
50
+ | `class_name` | `str` | Tailwind CSS classes (e.g., `"bg-slate-900 p-4 rounded-lg"`) |
51
+
52
+ ### Example
53
+
54
+ ```python
55
+ stat_card(
56
+ label="Revenue",
57
+ value="$50K",
58
+ color="blue",
59
+ style={"minWidth": "200px", "boxShadow": "0 4px 6px rgba(0,0,0,0.3)"},
60
+ class_name="border border-blue-500"
61
+ )
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Components
67
+
68
+ ### 1. Panel
69
+
70
+ A styled container/card wrapper.
71
+
72
+ ```python
73
+ panel(
74
+ children: str = "", # HTML content
75
+ style: dict = None,
76
+ class_name: str = "",
77
+ key: str = None
78
+ ) -> None
79
+ ```
80
+
81
+ #### Example
82
+
83
+ ```python
84
+ panel(
85
+ children="<h3 style='color: white;'>Title</h3><p style='color: #94a3b8;'>Content here</p>",
86
+ class_name="border border-blue-500"
87
+ )
88
+ ```
89
+
90
+ #### Default Styling
91
+ - Background: `bg-slate-900`
92
+ - Border radius: `rounded-lg`
93
+ - Padding: `p-4`
94
+
95
+ ---
96
+
97
+ ### 2. Section Header
98
+
99
+ A section title with optional action buttons.
100
+
101
+ ```python
102
+ section_header(
103
+ title: str, # Header text
104
+ icon: str = "", # Emoji or icon prefix
105
+ actions: list = None, # List of action buttons
106
+ style: dict = None,
107
+ class_name: str = "",
108
+ key: str = None
109
+ ) -> str | None # Returns clicked action ID
110
+ ```
111
+
112
+ #### Actions Format
113
+
114
+ ```python
115
+ actions = [
116
+ {"id": "refresh", "label": "Refresh", "color": "blue"},
117
+ {"id": "export", "icon": "📥", "label": "Export", "color": "green"}
118
+ ]
119
+ ```
120
+
121
+ | Action Key | Type | Description |
122
+ |------------|------|-------------|
123
+ | `id` | `str` | Unique identifier (returned on click) |
124
+ | `label` | `str` | Button text (optional) |
125
+ | `icon` | `str` | Emoji/icon (optional) |
126
+ | `color` | `str` | Preset (`"blue"`, `"green"`, `"red"`, `"yellow"`, `"purple"`, `"slate"`) or hex (e.g., `"#94a3b8"`) |
127
+ | `style` | `dict` | Inline CSS styles for this button (optional) |
128
+ | `className` | `str` | Tailwind classes for this button (optional) |
129
+ | `href` | `str` | URL for link actions. External URLs (http/https) open in new tab (optional) |
130
+
131
+ #### Example
132
+
133
+ ```python
134
+ # Using preset colors
135
+ clicked = section_header(
136
+ title="Executive Summary",
137
+ icon="📊",
138
+ actions=[
139
+ {"id": "refresh", "label": "Refresh", "color": "blue"},
140
+ {"id": "settings", "icon": "⚙️", "color": "slate"}
141
+ ]
142
+ )
143
+
144
+ # Using hex colors and custom styling
145
+ clicked = section_header(
146
+ title="Custom Actions",
147
+ actions=[
148
+ {"id": "custom", "label": "Custom", "color": "#ff5733"},
149
+ {"id": "styled", "label": "Styled", "style": {"padding": "12px", "borderRadius": "20px"}}
150
+ ]
151
+ )
152
+
153
+ # External link (opens in new tab)
154
+ section_header(
155
+ title="Resources",
156
+ actions=[
157
+ {"id": "docs", "label": "Documentation", "href": "https://docs.example.com", "icon": "📚"},
158
+ {"id": "github", "label": "GitHub", "href": "https://github.com", "color": "slate"}
159
+ ]
160
+ )
161
+
162
+ # Internal page navigation
163
+ clicked = section_header(
164
+ title="Settings",
165
+ actions=[{"id": "home", "label": "Home", "icon": "🏠"}]
166
+ )
167
+ if clicked == "home":
168
+ st.switch_page("pages/home.py")
169
+ ```
170
+
171
+ ---
172
+
173
+ ### 3. Stat Card
174
+
175
+ A statistics display card with colored accent.
176
+
177
+ ```python
178
+ stat_card(
179
+ label: str, # Description text
180
+ value: str | int | float, # The statistic value
181
+ color: str = "blue", # Accent color
182
+ icon: str = "", # Optional icon
183
+ style: dict = None,
184
+ class_name: str = "",
185
+ key: str = None
186
+ ) -> None
187
+ ```
188
+
189
+ #### Colors
190
+
191
+ Supports preset color names or hex values:
192
+
193
+ | Preset | Border | Text |
194
+ |--------|--------|------|
195
+ | `"blue"` | `border-blue-500` | `text-blue-400` |
196
+ | `"green"` | `border-green-500` | `text-green-400` |
197
+ | `"red"` | `border-red-500` | `text-red-400` |
198
+ | `"yellow"` | `border-yellow-500` | `text-yellow-400` |
199
+ | `"purple"` | `border-purple-500` | `text-purple-400` |
200
+ | `"slate"` | `border-slate-500` | `text-slate-400` |
201
+ | `"#xxxxxx"` | Custom hex color | Custom hex color |
202
+
203
+ #### Example
204
+
205
+ ```python
206
+ col1, col2, col3, col4 = st.columns(4)
207
+
208
+ with col1:
209
+ stat_card(label="Within Threshold", value="4", color="green")
210
+ with col2:
211
+ stat_card(label="Above (Risk)", value="2", color="red")
212
+ with col3:
213
+ stat_card(label="Below (Underutil)", value="1", color="yellow")
214
+ with col4:
215
+ stat_card(label="Avg OEE", value="78.4%", color="blue")
216
+
217
+ # Using hex color
218
+ stat_card(label="Custom Color", value="42", color="#ff5733")
219
+ ```
220
+
221
+ ---
222
+
223
+ ### 4. Metric Row
224
+
225
+ A key-value display row.
226
+
227
+ ```python
228
+ metric_row(
229
+ label: str, # Left-side label
230
+ value: str, # Right-side value
231
+ value_color: str = "", # Tailwind text color class
232
+ style: dict = None,
233
+ class_name: str = "",
234
+ key: str = None
235
+ ) -> None
236
+ ```
237
+
238
+ #### Example
239
+
240
+ ```python
241
+ metric_row(label="Mean", value="78.4%")
242
+ metric_row(label="Median", value="79.0%")
243
+ metric_row(label="Outliers", value="3", value_color="text-red-400")
244
+ metric_row(label="Trend", value="↑ +0.4%/mo", value_color="text-green-400")
245
+ ```
246
+
247
+ #### Common Value Colors
248
+
249
+ | Color | Class |
250
+ |-------|-------|
251
+ | Green | `text-green-400` |
252
+ | Red | `text-red-400` |
253
+ | Yellow | `text-yellow-400` |
254
+ | Blue | `text-blue-400` |
255
+ | Gray | `text-slate-400` |
256
+
257
+ ---
258
+
259
+ ### 5. Data Table
260
+
261
+ A styled data table with row click support.
262
+
263
+ ```python
264
+ data_table(
265
+ columns: list, # Column definitions
266
+ rows: list, # Row data
267
+ show_header: bool = True,
268
+ style: dict = None,
269
+ class_name: str = "",
270
+ key: str = None
271
+ ) -> dict | None # Returns {rowIndex, rowData} on click
272
+ ```
273
+
274
+ #### Column Definition
275
+
276
+ ```python
277
+ columns = [
278
+ {"key": "name", "label": "Name"},
279
+ {"key": "value", "label": "Value", "align": "right", "format": "number"},
280
+ {"key": "percent", "label": "%", "align": "center", "format": "percent"},
281
+ {"key": "status", "label": "Status", "colorByValue": True}
282
+ ]
283
+ ```
284
+
285
+ | Column Key | Type | Description |
286
+ |------------|------|-------------|
287
+ | `key` | `str` | Data key in row dict |
288
+ | `label` | `str` | Column header text |
289
+ | `align` | `str` | `"left"`, `"center"`, `"right"` |
290
+ | `format` | `str` | `"number"` (adds commas), `"percent"` (adds %) |
291
+ | `colorByValue` | `bool` | Color based on status values |
292
+
293
+ #### Auto-Colored Values
294
+
295
+ When `colorByValue: True`, these values get automatic colors:
296
+
297
+ | Value | Color |
298
+ |-------|-------|
299
+ | `"above"` | Red |
300
+ | `"below"` | Yellow |
301
+ | `"within"` | Green |
302
+ | `"approved"` | Green |
303
+ | `"rejected"` | Red |
304
+ | `"submitted"` | Yellow |
305
+ | `"draft"` | Gray |
306
+
307
+ #### Example
308
+
309
+ ```python
310
+ columns = [
311
+ {"key": "site", "label": "Site"},
312
+ {"key": "line", "label": "Line"},
313
+ {"key": "util", "label": "Utilization", "align": "right", "format": "percent"},
314
+ {"key": "volume", "label": "Volume", "align": "right", "format": "number"},
315
+ {"key": "status", "label": "Status", "align": "center", "colorByValue": True}
316
+ ]
317
+
318
+ rows = [
319
+ {"site": "AML_14", "line": "L1", "util": 94, "volume": 125000, "status": "above"},
320
+ {"site": "ADL", "line": "L2", "util": 72, "volume": 98000, "status": "within"},
321
+ {"site": "Devens", "line": "L3", "util": 58, "volume": 45000, "status": "below"}
322
+ ]
323
+
324
+ clicked = data_table(columns=columns, rows=rows)
325
+
326
+ if clicked:
327
+ st.write(f"Selected row {clicked['rowIndex']}: {clicked['rowData']}")
328
+ ```
329
+
330
+ ---
331
+
332
+ ### 6. Step Indicator
333
+
334
+ A multi-step wizard progress indicator.
335
+
336
+ ```python
337
+ step_indicator(
338
+ steps: list, # List of step labels
339
+ current_step: int, # Current step (1-indexed)
340
+ style: dict = None,
341
+ class_name: str = "",
342
+ key: str = None
343
+ ) -> int | None # Returns clicked step number
344
+ ```
345
+
346
+ #### Example
347
+
348
+ ```python
349
+ if "step" not in st.session_state:
350
+ st.session_state.step = 1
351
+
352
+ clicked = step_indicator(
353
+ steps=["Supply Plan", "Configure Levers", "Review & Submit"],
354
+ current_step=st.session_state.step
355
+ )
356
+
357
+ if clicked:
358
+ st.session_state.step = clicked
359
+ st.rerun()
360
+ ```
361
+
362
+ #### Visual States
363
+
364
+ | State | Appearance |
365
+ |-------|------------|
366
+ | Completed (< current) | Green circle with ✓ |
367
+ | Current | Blue circle with number |
368
+ | Future (> current) | Gray circle with number |
369
+
370
+ ---
371
+
372
+ ### 7. Button Group
373
+
374
+ A group of action buttons.
375
+
376
+ ```python
377
+ button_group(
378
+ buttons: list, # List of button configs
379
+ style: dict = None,
380
+ class_name: str = "",
381
+ key: str = None
382
+ ) -> str | None # Returns clicked button ID
383
+ ```
384
+
385
+ #### Button Definition
386
+
387
+ ```python
388
+ buttons = [
389
+ {"id": "view", "icon": "👁️"},
390
+ {"id": "edit", "icon": "✏️", "label": "Edit"},
391
+ {"id": "approve", "icon": "✓", "color": "green"},
392
+ {"id": "reject", "icon": "✕", "color": "red", "disabled": True}
393
+ ]
394
+ ```
395
+
396
+ | Button Key | Type | Description |
397
+ |------------|------|-------------|
398
+ | `id` | `str` | Unique identifier (returned on click) |
399
+ | `label` | `str` | Button text (optional) |
400
+ | `icon` | `str` | Emoji/icon (optional) |
401
+ | `color` | `str` | Preset (`"blue"`, `"green"`, `"red"`, `"yellow"`, `"purple"`, `"slate"`) or hex (e.g., `"#94a3b8"`) |
402
+ | `disabled` | `bool` | Disable the button |
403
+ | `style` | `dict` | Inline CSS styles for this button (optional) |
404
+ | `className` | `str` | Tailwind classes for this button (optional) |
405
+
406
+ #### Example
407
+
408
+ ```python
409
+ # Using preset colors
410
+ clicked = button_group(
411
+ buttons=[
412
+ {"id": "view", "icon": "👁️", "label": "View"},
413
+ {"id": "edit", "icon": "✏️", "label": "Edit"},
414
+ {"id": "delete", "icon": "🗑️", "color": "red"}
415
+ ]
416
+ )
417
+
418
+ # Using hex colors and custom styling
419
+ clicked = button_group(
420
+ buttons=[
421
+ {"id": "custom", "icon": "🎨", "color": "#ff5733"},
422
+ {"id": "styled", "label": "Styled", "style": {"padding": "12px"}}
423
+ ]
424
+ )
425
+
426
+ if clicked == "delete":
427
+ st.warning("Delete clicked!")
428
+ ```
429
+
430
+ ---
431
+
432
+ ### 8. Chart Legend
433
+
434
+ A legend for charts with colored indicators.
435
+
436
+ ```python
437
+ chart_legend(
438
+ items: list, # List of legend items
439
+ style: dict = None,
440
+ class_name: str = "",
441
+ key: str = None
442
+ ) -> None
443
+ ```
444
+
445
+ #### Items Format
446
+
447
+ ```python
448
+ items = [
449
+ {"color": "#94a3b8", "label": "Historical"},
450
+ {"color": "#ef4444", "label": "Outlier"},
451
+ {"color": "#8b5cf6", "label": "Prophet"},
452
+ {"color": "#10b981", "label": "ARIMA"}
453
+ ]
454
+ ```
455
+
456
+ #### Example
457
+
458
+ ```python
459
+ # Display a chart (using st.line_chart, plotly, etc.)
460
+ st.line_chart(data)
461
+
462
+ # Add legend below
463
+ chart_legend(
464
+ items=[
465
+ {"color": "#3b82f6", "label": "Actual"},
466
+ {"color": "#ef4444", "label": "Upper Threshold"},
467
+ {"color": "#eab308", "label": "Lower Threshold"},
468
+ {"color": "#8b5cf6", "label": "Forecast"}
469
+ ]
470
+ )
471
+ ```
472
+
473
+ ---
474
+
475
+ ### 9. Plotly Chart
476
+
477
+ Render Plotly charts with full interactivity and event callbacks.
478
+
479
+ ```python
480
+ plotly_chart(
481
+ # Data source (one required)
482
+ figure: Any = None, # Plotly figure or dict
483
+ data: DataFrame = None, # pandas DataFrame
484
+
485
+ # DataFrame options (when using data=)
486
+ x: str = None, # Column name for x-axis
487
+ y: str | list = None, # Column name(s) for y-axis
488
+ color: str = None, # Column name for color grouping
489
+ chart_type: str = "line", # "line", "bar", "scatter", "area", "pie", "histogram"
490
+ title: str = None, # Chart title
491
+
492
+ # Plotly config
493
+ config: dict = None, # Plotly config options
494
+
495
+ # Event callbacks
496
+ on_click: bool = False, # Enable click events
497
+ on_select: bool = False, # Enable selection events
498
+ on_hover: bool = False, # Enable hover events
499
+ on_relayout: bool = False, # Enable zoom/pan events
500
+
501
+ # Expandable dialog
502
+ expandable: bool = False, # Show expand button
503
+ modal_title: str = "", # Dialog header title
504
+
505
+ # Styling
506
+ style: dict = None,
507
+ class_name: str = "",
508
+ key: str = None
509
+ ) -> dict | None # Returns event dict or None
510
+ ```
511
+
512
+ #### Using Plotly Figure
513
+
514
+ ```python
515
+ import plotly.graph_objects as go
516
+
517
+ fig = go.Figure(
518
+ data=[
519
+ go.Scatter(x=[1,2,3,4,5], y=[10,15,13,17,20], mode='lines+markers', name='Sales'),
520
+ go.Bar(x=[1,2,3,4,5], y=[5,8,6,9,12], name='Orders')
521
+ ],
522
+ layout=go.Layout(title='Sales Dashboard')
523
+ )
524
+
525
+ event = plotly_chart(
526
+ figure=fig,
527
+ on_click=True,
528
+ on_select=True,
529
+ style={"height": "400px"}
530
+ )
531
+
532
+ if event and event['type'] == 'click':
533
+ st.write(f"Clicked: {event['points']}")
534
+ ```
535
+
536
+ #### Using DataFrame
537
+
538
+ ```python
539
+ import pandas as pd
540
+
541
+ df = pd.DataFrame({
542
+ 'month': ['Jan', 'Feb', 'Mar', 'Apr'],
543
+ 'sales': [100, 150, 120, 180],
544
+ 'orders': [50, 75, 60, 90]
545
+ })
546
+
547
+ # Simple line chart
548
+ event = plotly_chart(
549
+ data=df,
550
+ x='month',
551
+ y='sales',
552
+ chart_type='line',
553
+ title='Monthly Sales'
554
+ )
555
+
556
+ # Multiple y columns as bar chart
557
+ event = plotly_chart(
558
+ data=df,
559
+ x='month',
560
+ y=['sales', 'orders'],
561
+ chart_type='bar',
562
+ title='Sales vs Orders'
563
+ )
564
+
565
+ # Scatter with color grouping
566
+ event = plotly_chart(
567
+ data=df,
568
+ x='sales',
569
+ y='orders',
570
+ color='month',
571
+ chart_type='scatter'
572
+ )
573
+ ```
574
+
575
+ #### Chart Types (DataFrame mode)
576
+
577
+ | Type | Description |
578
+ |------|-------------|
579
+ | `"line"` | Line chart with connected points |
580
+ | `"scatter"` | Scatter plot with markers only |
581
+ | `"bar"` | Vertical bar chart |
582
+ | `"area"` | Area chart (filled line) |
583
+ | `"pie"` | Pie chart (x=labels, y=values) |
584
+ | `"histogram"` | Histogram of x values |
585
+
586
+ #### Event Types
587
+
588
+ | Event | When Triggered | Data Returned |
589
+ |-------|----------------|---------------|
590
+ | `click` | User clicks a data point | `{type: 'click', points: [...]}` |
591
+ | `select` | User box/lasso selects points | `{type: 'select', points: [...]}` |
592
+ | `hover` | User hovers over a point | `{type: 'hover', points: [...]}` |
593
+ | `relayout` | User zooms/pans the chart | `{type: 'relayout', relayout: {...}}` |
594
+
595
+ #### Point Data Structure
596
+
597
+ Each point in the `points` array contains:
598
+
599
+ ```python
600
+ {
601
+ "curveNumber": 0, # Index of the trace
602
+ "pointNumber": 2, # Index of the point in the trace
603
+ "pointIndex": 2, # Same as pointNumber
604
+ "x": "Mar", # X value
605
+ "y": 120, # Y value
606
+ "customdata": None # Custom data if provided
607
+ }
608
+ ```
609
+
610
+ #### Expandable Dialog
611
+
612
+ Charts can be expanded into a full-page dialog using Streamlit's native `st.dialog()`:
613
+
614
+ ```python
615
+ event = plotly_chart(
616
+ figure=fig,
617
+ expandable=True, # Show expand button in corner
618
+ modal_title="Sales Dashboard", # Title in dialog header
619
+ style={"height": "300px"}
620
+ )
621
+ ```
622
+
623
+ **Dialog Features:**
624
+ - Click the expand icon (⛶) in the top-right corner to open
625
+ - Dialog uses Streamlit's native full-width dialog overlay
626
+ - Click outside the dialog or press Escape to close
627
+ - Chart renders at full dialog width for better visibility
628
+
629
+ ---
630
+
631
+ ### 10. Form Select
632
+
633
+ A styled dropdown select input.
634
+
635
+ ```python
636
+ form_select(
637
+ label: str, # Label text
638
+ options: list, # Options list
639
+ value: str = "", # Selected value
640
+ groups: list = None, # Option groups (for optgroup)
641
+ style: dict = None,
642
+ class_name: str = "",
643
+ key: str = None
644
+ ) -> str # Returns selected value
645
+ ```
646
+
647
+ #### Simple Options
648
+
649
+ ```python
650
+ options = ["Option A", "Option B", "Option C"]
651
+ ```
652
+
653
+ #### Options with Labels
654
+
655
+ ```python
656
+ options = [
657
+ {"value": "a", "label": "Option A"},
658
+ {"value": "b", "label": "Option B"}
659
+ ]
660
+ ```
661
+
662
+ #### Grouped Options
663
+
664
+ ```python
665
+ groups = [
666
+ {"label": "Baselines", "options": ["Baseline v7", "Baseline v6"]},
667
+ {"label": "Scenarios", "options": ["Q2 Demand Surge", "OEE Initiative"]}
668
+ ]
669
+ ```
670
+
671
+ #### Example
672
+
673
+ ```python
674
+ # Simple
675
+ site = form_select(
676
+ label="Site",
677
+ options=["AML_14", "ADL", "Devens"],
678
+ value="AML_14"
679
+ )
680
+
681
+ # With groups
682
+ scenario = form_select(
683
+ label="Base On",
684
+ groups=[
685
+ {"label": "Baselines", "options": ["Baseline v7 (Current)", "Baseline v6"]},
686
+ {"label": "Scenarios", "options": ["Q2 Demand Surge", "OEE Initiative"]}
687
+ ],
688
+ class_name="max-w-xs"
689
+ )
690
+ ```
691
+
692
+ ---
693
+
694
+ ### 11. Form Slider
695
+
696
+ A styled range slider input.
697
+
698
+ ```python
699
+ form_slider(
700
+ label: str, # Label text
701
+ value: float, # Current value
702
+ min_val: float, # Minimum value
703
+ max_val: float, # Maximum value
704
+ step: float = 1, # Step increment
705
+ unit: str = "", # Unit suffix (e.g., "%", "hrs")
706
+ color: str = "blue", # Preset or hex color (e.g., "#94a3b8")
707
+ style: dict = None,
708
+ class_name: str = "",
709
+ key: str = None
710
+ ) -> float # Returns current value
711
+ ```
712
+
713
+ #### Example
714
+
715
+ ```python
716
+ # Percentage slider with preset color
717
+ threshold = form_slider(
718
+ label="Upper Threshold",
719
+ value=90,
720
+ min_val=75,
721
+ max_val=100,
722
+ unit="%",
723
+ color="red"
724
+ )
725
+
726
+ # Time slider
727
+ hold_time = form_slider(
728
+ label="VPHP Hold Time",
729
+ value=5.0,
730
+ min_val=2.0,
731
+ max_val=8.0,
732
+ step=0.5,
733
+ unit=" hrs",
734
+ color="blue"
735
+ )
736
+
737
+ # Slider with hex color
738
+ custom_slider = form_slider(
739
+ label="Custom Color",
740
+ value=50,
741
+ min_val=0,
742
+ max_val=100,
743
+ color="#ff5733"
744
+ )
745
+ ```
746
+
747
+ ---
748
+
749
+ ### 12. Checkbox Group
750
+
751
+ A group of checkboxes.
752
+
753
+ ```python
754
+ checkbox_group(
755
+ items: list, # List of checkbox items
756
+ label: str = "", # Optional group label
757
+ style: dict = None,
758
+ class_name: str = "",
759
+ key: str = None
760
+ ) -> list # Returns list of checked item IDs
761
+ ```
762
+
763
+ #### Items Format
764
+
765
+ ```python
766
+ items = [
767
+ {"id": "opt1", "label": "Option 1", "checked": True},
768
+ {"id": "opt2", "label": "Option 2", "checked": True},
769
+ {"id": "opt3", "label": "Option 3"} # checked defaults to False
770
+ ]
771
+ ```
772
+
773
+ #### Example
774
+
775
+ ```python
776
+ selected = checkbox_group(
777
+ label="Parameters to Optimize",
778
+ items=[
779
+ {"id": "vphp", "label": "VPHP Hold Time", "checked": True},
780
+ {"id": "lot_co", "label": "Lot Changeover", "checked": True},
781
+ {"id": "campaign_co", "label": "Campaign Changeover"},
782
+ {"id": "batch", "label": "Batch Size"}
783
+ ]
784
+ )
785
+
786
+ st.write(f"Selected parameters: {selected}")
787
+ # Output: ['vphp', 'lot_co']
788
+ ```
789
+
790
+ ---
791
+
792
+ ## Complete Example App
793
+
794
+ ```python
795
+ import streamlit as st
796
+ from streamlit_react_components import (
797
+ section_header, stat_card, data_table,
798
+ form_select, form_slider, checkbox_group
799
+ )
800
+
801
+ st.set_page_config(page_title="Dashboard", layout="wide")
802
+
803
+ # Header
804
+ action = section_header(
805
+ title="Production Dashboard",
806
+ icon="🏭",
807
+ actions=[{"id": "refresh", "label": "Refresh", "color": "blue"}]
808
+ )
809
+
810
+ # Stats row
811
+ col1, col2, col3 = st.columns(3)
812
+ with col1:
813
+ stat_card(label="Lines Active", value="12", color="green")
814
+ with col2:
815
+ stat_card(label="At Risk", value="3", color="red")
816
+ with col3:
817
+ stat_card(label="Avg Utilization", value="82%", color="blue")
818
+
819
+ # Filters
820
+ st.markdown("### Filters")
821
+ col1, col2 = st.columns(2)
822
+ with col1:
823
+ site = form_select(label="Site", options=["All", "AML", "ADL", "Devens"])
824
+ with col2:
825
+ threshold = form_slider(label="Risk Threshold", value=90, min_val=80, max_val=100, unit="%")
826
+
827
+ # Data table
828
+ st.markdown("### Lines Overview")
829
+ clicked = data_table(
830
+ columns=[
831
+ {"key": "line", "label": "Line"},
832
+ {"key": "util", "label": "Utilization", "format": "percent", "align": "right"},
833
+ {"key": "status", "label": "Status", "colorByValue": True}
834
+ ],
835
+ rows=[
836
+ {"line": "L1", "util": 94, "status": "above"},
837
+ {"line": "L2", "util": 82, "status": "within"},
838
+ {"line": "L3", "util": 65, "status": "below"}
839
+ ]
840
+ )
841
+
842
+ if clicked:
843
+ st.info(f"Selected: {clicked['rowData']['line']}")
844
+ ```
845
+
846
+ ---
847
+
848
+ ## Tailwind CSS Classes Reference
849
+
850
+ Since components use Tailwind CSS, here are commonly used classes:
851
+
852
+ ### Spacing
853
+ - `p-1` to `p-8`: Padding
854
+ - `m-1` to `m-8`: Margin
855
+ - `mt-4`, `mb-4`, `ml-4`, `mr-4`: Directional margin
856
+
857
+ ### Layout
858
+ - `w-full`: Full width
859
+ - `max-w-xs`, `max-w-sm`, `max-w-md`: Max width
860
+ - `flex`, `grid`: Display types
861
+ - `gap-2`, `gap-4`: Gap between items
862
+
863
+ ### Colors (Dark Theme)
864
+ - `bg-slate-900`, `bg-slate-800`: Backgrounds
865
+ - `text-white`, `text-slate-400`: Text colors
866
+ - `border-slate-700`: Border colors
867
+
868
+ ### Effects
869
+ - `rounded`, `rounded-lg`: Border radius
870
+ - `shadow`, `shadow-lg`: Box shadows
871
+ - `opacity-50`: Transparency
872
+
873
+ ---
874
+
875
+ ## License
876
+
877
+ MIT