{"id":30680477,"url":"https://github.com/danieljannai/streamlit-adjustable-columns","last_synced_at":"2025-09-01T16:04:33.026Z","repository":{"id":300218961,"uuid":"1003847000","full_name":"danieljannai/streamlit-adjustable-columns","owner":"danieljannai","description":"A Streamlit custom component for creating columns with adjustable widths using draggable resize handles.","archived":false,"fork":false,"pushed_at":"2025-06-24T11:31:38.000Z","size":687,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-31T20:31:36.392Z","etag":null,"topics":["drag-and-drop","interactive-component","resizable-columns","streamlit","streamlit-component"],"latest_commit_sha":null,"homepage":"https://github.com/danieljannai/streamlit-adjustable-columns","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danieljannai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-17T18:56:23.000Z","updated_at":"2025-08-11T08:44:46.000Z","dependencies_parsed_at":"2025-06-20T13:45:57.605Z","dependency_job_id":"f2c61e83-cd30-42fb-9478-525bcb9683df","html_url":"https://github.com/danieljannai/streamlit-adjustable-columns","commit_stats":null,"previous_names":["danieljannai/streamlit-adjustable-columns"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/danieljannai/streamlit-adjustable-columns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljannai%2Fstreamlit-adjustable-columns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljannai%2Fstreamlit-adjustable-columns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljannai%2Fstreamlit-adjustable-columns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljannai%2Fstreamlit-adjustable-columns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danieljannai","download_url":"https://codeload.github.com/danieljannai/streamlit-adjustable-columns/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljannai%2Fstreamlit-adjustable-columns/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273151416,"owners_count":25054410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["drag-and-drop","interactive-component","resizable-columns","streamlit","streamlit-component"],"created_at":"2025-09-01T16:04:29.217Z","updated_at":"2025-09-01T16:04:33.019Z","avatar_url":"https://github.com/danieljannai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎯 Streamlit Adjustable Columns\n\n[![PyPI version](https://badge.fury.io/py/streamlit-adjustable-columns.svg)](https://badge.fury.io/py/streamlit-adjustable-columns)\n\n**Version:** 0.2.1\n\nCreate resizable columns in Streamlit! This component provides `st.columns` functionality with **draggable resize handles** that allow users to adjust column widths dynamically.\n\n![Adjustable Columns Demo](https://github.com/danieljannai/streamlit-adjustable-columns/raw/main/adjustable-columns-demo.gif)\n\n## ✨ Features\n\n- **🎯 Drop-in Replacement**: Works exactly like `st.columns` with the same API\n- **🖱️ Resizable Boundaries**: Drag handles between columns to adjust widths  \n- **💾 Persistent State**: Column widths persist across app reruns\n- **🎨 Theme Integration**: Automatically matches your Streamlit theme\n- **📱 Responsive**: Works on desktop and mobile devices\n- **⚙️ Full Compatibility**: Supports all `st.columns` parameters (gap, alignment, border)\n- **🔒 Minimum Width**: 6% minimum width constraint prevents unusably narrow columns\n- **📊 Width Tracking**: Optional `return_widths` parameter for dynamic layouts\n- **👁️ Hide/Show Columns**: Double-click column headers to hide/show columns dynamically\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\npip install streamlit-adjustable-columns\n```\n\n**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.\n\n### Basic Usage\n\n```python\nimport streamlit as st\nfrom streamlit_adjustable_columns import adjustable_columns\n\n# Use exactly like st.columns - but with resize handles!\ncol1, col2, col3 = adjustable_columns(3, labels=[\"📊 Charts\", \"📋 Data\", \"⚙️ Settings\"])\n\nwith col1:\n    st.metric(\"Sales\", \"$1,234\", \"12%\")\n    \ncol2.write(\"This column can be resized!\")\ncol3.button(\"Settings\")\n```\n\n### ✅ Success Indicators\n\nYou know it's working when you see:\n- ✅ Column headers with drag handles between them\n- ✅ Ability to drag column separators to resize\n- ✅ Column widths persist when you interact with other elements\n- ✅ Responsive behavior on different screen sizes\n\n## 📖 API Reference\n\n### `adjustable_columns(spec, *, gap=\"small\", vertical_alignment=\"top\", border=False, labels=None, return_widths=False, initial_hidden=None, key=None)`\n\nCreates resizable columns with draggable boundaries.\n\n#### Parameters\n\n- **`spec`** (int or list): Number of columns or width ratios\n  - `3` → Three equal columns  \n  - `[2, 1]` → Two columns with 2:1 ratio\n- **`gap`** (str): Space between columns - `\"small\"`, `\"medium\"`, or `\"large\"`\n- **`vertical_alignment`** (str): Content alignment - `\"top\"`, `\"center\"`, or `\"bottom\"`\n- **`border`** (bool): Show borders around columns\n- **`labels`** (list): Custom labels shown in resize handles\n- **`return_widths`** (bool): Return width information along with columns\n- **`initial_hidden`** (list of bool, optional): List of booleans indicating which columns should start hidden. Must match the number of columns. Example: `[False, True, False]` will start the second column hidden.\n- **`key`** (str): Unique component key (recommended for multiple instances)\n\n#### Returns\n\n- **Default**: List of column containers (same as `st.columns`)\n- **With `return_widths=True`**: Dict with `{'columns': [...], 'widths': [...], 'hidden': [...]}`\n\n## 🎮 How to Resize \u0026 Hide Columns\n\n1. **Look for resize handles** above each set of adjustable columns\n2. **Hover over the boundaries** between column areas - you'll see resize cursors\n3. **Click and drag** the handles to adjust column widths\n4. **Double-click a column header** to hide/show that column\n5. **Release** to apply changes - they persist across app reruns!\n\n## 📚 Examples\n\n### Dashboard Layout\n\n```python\n# Create a dashboard with resizable main content and sidebar\nmain, sidebar = adjustable_columns([4, 1], labels=[\"📊 Dashboard\", \"⚙️ Controls\"])\n\nwith main:\n    st.subheader(\"Analytics Overview\")\n    col1, col2 = st.columns(2)\n    col1.metric(\"Revenue\", \"$45,231\", \"12%\")\n    col2.metric(\"Users\", \"1,429\", \"3%\")\n    st.line_chart(data)\n\nwith sidebar:\n    st.selectbox(\"Time Period\", [\"1D\", \"1W\", \"1M\"])\n    st.checkbox(\"Show Trends\")\n    st.button(\"Refresh Data\")\n```\n\n### Width Tracking\n\n```python\n# Track column widths for dynamic layouts\nresult = adjustable_columns([2, 1], labels=[\"Content\", \"Sidebar\"], return_widths=True)\ncontent, sidebar = result['columns']\ncurrent_widths = result['widths']\n\nst.info(f\"Current ratios: {[f'{w:.1f}' for w in current_widths]}\")\n\nwith content:\n    st.write(\"Main content area\")\n    \nwith sidebar:\n    st.write(\"Adjustable sidebar\")\n```\n\n### Multiple Column Sets\n\n```python\n# Each set of columns needs a unique key\ncols1 = adjustable_columns(3, labels=[\"A\", \"B\", \"C\"], key=\"top\")\ncols2 = adjustable_columns([1, 2], labels=[\"Left\", \"Right\"], key=\"bottom\")\n\n# First row\ncols1[0].metric(\"Metric 1\", \"100\")\ncols1[1].metric(\"Metric 2\", \"200\") \ncols1[2].metric(\"Metric 3\", \"300\")\n\n# Second row  \ncols2[0].button(\"Action\")\ncols2[1].write(\"Content area\")\n```\n\n### All Parameters\n\n```python\ncolumns = adjustable_columns(\n    spec=[3, 2, 1],                    # Custom width ratios\n    gap=\"large\",                       # Large spacing\n    vertical_alignment=\"center\",       # Center-align content\n    border=True,                       # Show column borders\n    labels=[\"📊 Charts\", \"📋 Data\", \"⚙️ Tools\"],  # Custom labels\n    return_widths=True,               # Get width info\n    key=\"advanced_example\"            # Unique identifier\n)\n\ncols = columns['columns']\nwidths = columns['widths']\n```\n\n### Start with Some Columns Hidden\n\n```python\n# Start with the second column hidden\ncols = adjustable_columns(\n    [1, 1, 1],\n    labels=[\"Main\", \"Side\", \"Tools\"],\n    initial_hidden=[False, True, False],\n    key=\"hidden_example\"\n)\n\nwith cols[0]:\n    st.write(\"Main column is visible!\")\nwith cols[1]:\n    st.write(\"Side column starts hidden!\")\nwith cols[2]:\n    st.write(\"Tools column is visible!\")\n```\n\n## 🎨 Customization\n\n### Column Labels\n\nCustomize the labels shown in resize handles:\n\n```python\ncols = adjustable_columns(\n    3, \n    labels=[\"📈 Analytics\", \"🛠️ Tools\", \"📱 Mobile\"]\n)\n```\n\n### Responsive Layouts\n\nUse width information for responsive behavior:\n\n```python\nresult = adjustable_columns([2, 1], return_widths=True)\nmain_col, side_col = result['columns']\nwidths = result['widths']\n\n# Adapt content based on current column width\nif widths[0] \u003e 3:  # Main column is wide\n    main_col.plotly_chart(fig, use_container_width=True)\nelse:  # Main column is narrow\n    main_col.write(\"Chart too narrow - expand column to view\")\n```\n\n## 🔧 Development\n\n### Prerequisites\n\n- Python 3.9+\n- Node.js 18+\n- npm or yarn\n- Git\n\n### Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/danieljannai/streamlit-adjustable-columns\ncd streamlit-adjustable-columns\n\n# Create virtual environment\npython3 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n\n# Install in development mode\nmake install-dev\n\n# Or manually:\npip install -e \".[dev]\"\ncd streamlit_adjustable_columns/frontend\nnpm install\ncd ../..\n```\n\n### Development Workflow\n\n```bash\n# Terminal 1: Start frontend development server\nmake frontend-dev  # Or: cd streamlit_adjustable_columns/frontend \u0026\u0026 npm start\n\n# Terminal 2: Run the demo (make sure venv is activated)\nsource venv/bin/activate\nstreamlit run example.py\n```\n\n### What You'll See\n\n1. **Frontend Dev Server**: http://localhost:3001\n   - This serves the interactive column resizer component\n\n2. **Streamlit App**: http://localhost:8501\n   - Your main app with the adjustable columns\n\n### Testing\n\nThe project includes comprehensive tests using pytest and Playwright:\n\n```bash\n# Run all tests\nmake test\n\n# Run only unit tests\nmake test-unit\n\n# Run only E2E tests  \nmake test-e2e\n\n# Run with coverage\npytest --cov=streamlit_adjustable_columns\n```\n\n### Code Quality\n\n```bash\n# Format code\nmake format\n\n# Check linting\nmake lint\n\n# Run full check (format + lint + test)\nmake format \u0026\u0026 make lint \u0026\u0026 make test\n```\n\n### Building and Publishing\n\n```bash\n# Build the package\nmake build\n\n# Upload to PyPI (requires credentials)\nmake upload\n```\n\n## 🐛 Troubleshooting\n\n### Component shows \"Loading...\" forever\n- Make sure the frontend dev server is running on port 3001\n- Check that `_RELEASE = False` in `streamlit_adjustable_columns/__init__.py`\n\n### \"Module not found\" error\n- Make sure your virtual environment is activated: `source venv/bin/activate`\n- Reinstall dependencies: `make install-dev`\n\n### Frontend won't start\n- Make sure Node.js and npm are installed\n- Delete `node_modules` and run `npm install` again\n\n### Port conflicts\n- If port 3001 or 8501 are busy, kill other processes or change ports in the configuration\n\n## 🧪 Test Coverage\n\nThe project includes comprehensive test coverage:\n\n- **Unit Tests**: Test core functionality, parameter handling, and state management\n- **Integration Tests**: Test component behavior with Streamlit integration\n- **E2E Tests**: Test user interactions, resize functionality, and visual elements\n- **Cross-browser Testing**: Firefox and Chromium support via Playwright\n\nTest files are organized in the `tests/` directory:\n- `tests/test_unit.py` - Unit tests for Python code\n- `tests/test_integration.py` - Integration tests\n- `tests/test_*.py` - E2E tests for specific features\n- `tests/streamlit_apps/` - Test Streamlit applications\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. This is a brief overview of how to contribute:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Install development dependencies (`make install-dev`)\n4. Make your changes and add tests\n5. Run the test suite (`make test`)\n6. Format your code (`make format`)\n7. Commit your changes (`git commit -m 'Add amazing feature'`)\n8. Push to the branch (`git push origin feature/amazing-feature`)\n9. Open a Pull Request\n\n**For detailed contributing guidelines, development setup, testing procedures, and release processes, please see [CONTRIBUTING.md](CONTRIBUTING.md).**\n\n## 📝 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- Built with [Streamlit](https://streamlit.io/)\n- Inspired by the need for flexible column layouts in Streamlit applications\n- Developed with great assistance from [Cursor](https://cursor.com/) AI coding assistant\n\n## 👨‍💻 Author\n\n**Daniel Jannai Epstein**\n\n- GitHub: [@danieljannai](https://github.com/danieljannai)\n- Created this component to enhance Streamlit's column functionality\n\n---\n\n**Made with ❤️ for the Streamlit community** \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieljannai%2Fstreamlit-adjustable-columns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanieljannai%2Fstreamlit-adjustable-columns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieljannai%2Fstreamlit-adjustable-columns/lists"}