Skip to main content

A Streamlit custom component for creating columns with adjustable widths

Project description

🎯 Streamlit Adjustable Columns

PyPI version

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.

Adjustable Columns Demo

✨ Features

  • 🎯 Drop-in Replacement: Works exactly like st.columns with 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.columns parameters (gap, alignment, border)
  • 🔒 Minimum Width: 6% minimum width constraint prevents unusably narrow columns
  • 📊 Width Tracking: Optional return_widths parameter 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 ratios
    • 3 → 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 columns
  • labels (list): Custom labels shown in resize handles
  • return_widths (bool): Return width information along with columns
  • key (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

  1. Look for resize handles above each set of adjustable columns
  2. Hover over the boundaries between column areas - you'll see resize cursors
  3. Click and drag the handles to adjust column widths
  4. 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

  1. Frontend Dev Server: http://localhost:3001

    • This serves the interactive column resizer component
  2. 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 = False in streamlit_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_modules and run npm install again

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 code
  • tests/test_integration.py - Integration tests
  • tests/test_*.py - E2E tests for specific features
  • tests/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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Install development dependencies (make install-dev)
  4. Make your changes and add tests
  5. Run the test suite (make test)
  6. Format your code (make format)
  7. Commit your changes (git commit -m 'Add amazing feature')
  8. Push to the branch (git push origin feature/amazing-feature)
  9. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

streamlit_adjustable_columns-0.2.0.tar.gz (150.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

streamlit_adjustable_columns-0.2.0-py3-none-any.whl (153.5 kB view details)

Uploaded Python 3

File details

Details for the file streamlit_adjustable_columns-0.2.0.tar.gz.

File metadata

File hashes

Hashes for streamlit_adjustable_columns-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b48bd7cd4942e92e3af4d662dcab431476a2b9593c47c044cfcfda13f4f72972
MD5 843d0942ecb8a3603f2b72c5be989a7e
BLAKE2b-256 cf930073159702d34fae58a55c9e57b26bfe962a2c666dad2e7b26239d61f437

See more details on using hashes here.

File details

Details for the file streamlit_adjustable_columns-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for streamlit_adjustable_columns-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 51987dcace2f6e30e2d22b895331b4941f8a090735d88924e21666f82f767a00
MD5 bc5df44752d0d9272a1fa1005c8dae53
BLAKE2b-256 d36044efe3f9a5cb1d39efb181dfb5cb437a1d015da0c03d9e1d769675eda5d3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page