A Streamlit custom component for creating columns with adjustable widths
Project description
🎯 Streamlit Adjustable Columns
Version: 0.2.0
Create resizable columns in Streamlit! This component provides st.columns functionality with draggable resize handles that allow users to adjust column widths dynamically.
✨ Features
- 🎯 Drop-in Replacement: Works exactly like
st.columnswith the same API - 🖱️ Resizable Boundaries: Drag handles between columns to adjust widths
- 💾 Persistent State: Column widths persist across app reruns
- 🎨 Theme Integration: Automatically matches your Streamlit theme
- 📱 Responsive: Works on desktop and mobile devices
- ⚙️ Full Compatibility: Supports all
st.columnsparameters (gap, alignment, border) - 🔒 Minimum Width: 6% minimum width constraint prevents unusably narrow columns
- 📊 Width Tracking: Optional
return_widthsparameter for dynamic layouts
🚀 Quick Start
Installation
pip install streamlit-adjustable-columns
Note: Packages installed from PyPI already include the compiled frontend so no additional tools are required. If you install from a source checkout (e.g. GitHub), Node.js and npm are needed to build the frontend assets.
Basic Usage
import streamlit as st
from streamlit_adjustable_columns import adjustable_columns
# Use exactly like st.columns - but with resize handles!
col1, col2, col3 = adjustable_columns(3, labels=["📊 Charts", "📋 Data", "⚙️ Settings"])
with col1:
st.metric("Sales", "$1,234", "12%")
col2.write("This column can be resized!")
col3.button("Settings")
✅ Success Indicators
You know it's working when you see:
- ✅ Column headers with drag handles between them
- ✅ Ability to drag column separators to resize
- ✅ Column widths persist when you interact with other elements
- ✅ Responsive behavior on different screen sizes
📖 API Reference
adjustable_columns(spec, *, gap="small", vertical_alignment="top", border=False, labels=None, return_widths=False, key=None)
Creates resizable columns with draggable boundaries.
Parameters
spec(int or list): Number of columns or width ratios3→ Three equal columns[2, 1]→ Two columns with 2:1 ratio
gap(str): Space between columns -"small","medium", or"large"vertical_alignment(str): Content alignment -"top","center", or"bottom"border(bool): Show borders around columnslabels(list): Custom labels shown in resize handlesreturn_widths(bool): Return width information along with columnskey(str): Unique component key (recommended for multiple instances)
Returns
- Default: List of column containers (same as
st.columns) - With
return_widths=True: Dict with{'columns': [...], 'widths': [...]}
🎮 How to Resize
- Look for resize handles above each set of adjustable columns
- Hover over the boundaries between column areas - you'll see resize cursors
- Click and drag the handles to adjust column widths
- Release to apply changes - they persist across app reruns!
📚 Examples
Dashboard Layout
# Create a dashboard with resizable main content and sidebar
main, sidebar = adjustable_columns([4, 1], labels=["📊 Dashboard", "⚙️ Controls"])
with main:
st.subheader("Analytics Overview")
col1, col2 = st.columns(2)
col1.metric("Revenue", "$45,231", "12%")
col2.metric("Users", "1,429", "3%")
st.line_chart(data)
with sidebar:
st.selectbox("Time Period", ["1D", "1W", "1M"])
st.checkbox("Show Trends")
st.button("Refresh Data")
Width Tracking
# Track column widths for dynamic layouts
result = adjustable_columns([2, 1], labels=["Content", "Sidebar"], return_widths=True)
content, sidebar = result['columns']
current_widths = result['widths']
st.info(f"Current ratios: {[f'{w:.1f}' for w in current_widths]}")
with content:
st.write("Main content area")
with sidebar:
st.write("Adjustable sidebar")
Multiple Column Sets
# Each set of columns needs a unique key
cols1 = adjustable_columns(3, labels=["A", "B", "C"], key="top")
cols2 = adjustable_columns([1, 2], labels=["Left", "Right"], key="bottom")
# First row
cols1[0].metric("Metric 1", "100")
cols1[1].metric("Metric 2", "200")
cols1[2].metric("Metric 3", "300")
# Second row
cols2[0].button("Action")
cols2[1].write("Content area")
All Parameters
columns = adjustable_columns(
spec=[3, 2, 1], # Custom width ratios
gap="large", # Large spacing
vertical_alignment="center", # Center-align content
border=True, # Show column borders
labels=["📊 Charts", "📋 Data", "⚙️ Tools"], # Custom labels
return_widths=True, # Get width info
key="advanced_example" # Unique identifier
)
cols = columns['columns']
widths = columns['widths']
🎨 Customization
Column Labels
Customize the labels shown in resize handles:
cols = adjustable_columns(
3,
labels=["📈 Analytics", "🛠️ Tools", "📱 Mobile"]
)
Responsive Layouts
Use width information for responsive behavior:
result = adjustable_columns([2, 1], return_widths=True)
main_col, side_col = result['columns']
widths = result['widths']
# Adapt content based on current column width
if widths[0] > 3: # Main column is wide
main_col.plotly_chart(fig, use_container_width=True)
else: # Main column is narrow
main_col.write("Chart too narrow - expand column to view")
🔧 Development
Prerequisites
- Python 3.9+
- Node.js 18+
- npm or yarn
- Git
Setup
# Clone the repository
git clone https://github.com/danieljannai/streamlit-adjustable-columns
cd streamlit-adjustable-columns
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
make install-dev
# Or manually:
pip install -e ".[dev]"
cd streamlit_adjustable_columns/frontend
npm install
cd ../..
Development Workflow
# Terminal 1: Start frontend development server
make frontend-dev # Or: cd streamlit_adjustable_columns/frontend && npm start
# Terminal 2: Run the demo (make sure venv is activated)
source venv/bin/activate
streamlit run example.py
What You'll See
-
Frontend Dev Server: http://localhost:3001
- This serves the interactive column resizer component
-
Streamlit App: http://localhost:8501
- Your main app with the adjustable columns
Testing
The project includes comprehensive tests using pytest and Playwright:
# Run all tests
make test
# Run only unit tests
make test-unit
# Run only E2E tests
make test-e2e
# Run with coverage
pytest --cov=streamlit_adjustable_columns
Code Quality
# Format code
make format
# Check linting
make lint
# Run full check (format + lint + test)
make format && make lint && make test
Building and Publishing
# Build the package
make build
# Upload to PyPI (requires credentials)
make upload
🐛 Troubleshooting
Component shows "Loading..." forever
- Make sure the frontend dev server is running on port 3001
- Check that
_RELEASE = Falseinstreamlit_adjustable_columns/__init__.py
"Module not found" error
- Make sure your virtual environment is activated:
source venv/bin/activate - Reinstall dependencies:
make install-dev
Frontend won't start
- Make sure Node.js and npm are installed
- Delete
node_modulesand runnpm installagain
Port conflicts
- If port 3001 or 8501 are busy, kill other processes or change ports in the configuration
🧪 Test Coverage
The project includes comprehensive test coverage:
- Unit Tests: Test core functionality, parameter handling, and state management
- Integration Tests: Test component behavior with Streamlit integration
- E2E Tests: Test user interactions, resize functionality, and visual elements
- Cross-browser Testing: Firefox and Chromium support via Playwright
Test files are organized in the tests/ directory:
tests/test_unit.py- Unit tests for Python codetests/test_integration.py- Integration teststests/test_*.py- E2E tests for specific featurestests/streamlit_apps/- Test Streamlit applications
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request. This is a brief overview of how to contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Install development dependencies (
make install-dev) - Make your changes and add tests
- Run the test suite (
make test) - Format your code (
make format) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
For detailed contributing guidelines, development setup, testing procedures, and release processes, please see CONTRIBUTING.md.
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Built with Streamlit
- Inspired by the need for flexible column layouts in Streamlit applications
- Developed with great assistance from Cursor AI coding assistant
👨💻 Author
Daniel Jannai Epstein
- GitHub: @danieljannai
- Created this component to enhance Streamlit's column functionality
Made with ❤️ for the Streamlit community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file streamlit_adjustable_columns-0.2.0.tar.gz.
File metadata
- Download URL: streamlit_adjustable_columns-0.2.0.tar.gz
- Upload date:
- Size: 150.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b48bd7cd4942e92e3af4d662dcab431476a2b9593c47c044cfcfda13f4f72972
|
|
| MD5 |
843d0942ecb8a3603f2b72c5be989a7e
|
|
| BLAKE2b-256 |
cf930073159702d34fae58a55c9e57b26bfe962a2c666dad2e7b26239d61f437
|
File details
Details for the file streamlit_adjustable_columns-0.2.0-py3-none-any.whl.
File metadata
- Download URL: streamlit_adjustable_columns-0.2.0-py3-none-any.whl
- Upload date:
- Size: 153.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51987dcace2f6e30e2d22b895331b4941f8a090735d88924e21666f82f767a00
|
|
| MD5 |
bc5df44752d0d9272a1fa1005c8dae53
|
|
| BLAKE2b-256 |
d36044efe3f9a5cb1d39efb181dfb5cb437a1d015da0c03d9e1d769675eda5d3
|