Allow selecting text of pills in the MultiselectColumn and ListColumn#13663
Allow selecting text of pills in the MultiselectColumn and ListColumn#13663lukasmasuch merged 13 commits intodevelopfrom
MultiselectColumn and ListColumn#13663Conversation
Implement a custom multi-select cell based on react-select to replace the glide-data-grid-cells MultiSelectCell. This provides better control over styling, behavior, and features. - Add MultiSelectCell.tsx with custom renderer and editor - Support for options with labels and colors - Configurable duplicate and creation permissions - Enhanced text selection in pill labels - Comprehensive test coverage - Register custom cell in useCustomRenderer hook Co-Authored-By: Claude <[email protected]>
✅ PR preview is ready!
|
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Co-Authored-By: Claude <[email protected]>
Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR introduces a custom MultiSelectCell implementation for DataFrame using react-select to replace the existing glide-data-grid-cells MultiSelectCell. The implementation provides enhanced control over styling, behavior, and features including text selection in pill labels, configurable duplication and creation permissions, and comprehensive paste support.
Changes:
- Added
react-selectdependency to enable multi-select functionality with better customization - Implemented custom MultiSelectCell renderer with canvas drawing, editor component, and paste handler
- Added comprehensive test coverage with 13+ test cases covering core functionality
- Removed dependency on
glide-data-grid-cellsMultiSelectCell while maintaining backward compatibility
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Lockfile appears to be reset/incomplete - requires regeneration with full dependency tree |
| frontend/lib/package.json | Added react-select@^5.10.1 dependency for multi-select functionality |
| frontend/lib/src/components/widgets/DataFrame/hooks/useCustomRenderer.ts | Removed MultiSelectCell from glide-data-grid-cells imports and customRenderers array |
| frontend/lib/src/components/widgets/DataFrame/columns/index.ts | Exported MultiSelectCellRenderer and added to CustomCells array |
| frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx | Implemented complete custom MultiSelectCell with editor, renderer, and paste support (643 lines) |
| frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.test.tsx | Added comprehensive test coverage including unit tests for utility functions and editor behavior (706 lines) |
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.test.tsx
Outdated
Show resolved
Hide resolved
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
Co-Authored-By: Claude <[email protected]>
- Wrap colorStyles in useMemo to prevent unnecessary re-renders - Memoize components object with useMemo for referential stability - Remove export from test helper functions (selectOption, hasOption) - Fix prepareOptions type safety: null/undefined now return empty string - Change border-radius from 4px to 0.25rem for relative units - Remove unnecessary async from onChange and wrap with useCallback - Wrap onMenuOpen/onMenuClose with useCallback - Wrap noOptionsMessage with useCallback Co-Authored-By: Claude <[email protected]>
Co-Authored-By: Claude <[email protected]>
|
@cursor review |
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Show resolved
Hide resolved
MultiselectColumn and ListColumn
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
frontend/lib/src/components/widgets/DataFrame/columns/cells/MultiSelectCell.tsx
Outdated
Show resolved
Hide resolved
📉 Frontend coverage change detectedThe frontend unit test (vitest) coverage has decreased by 0.1800%
💡 Consider adding more unit tests to maintain or improve coverage. |
There was a problem hiding this comment.
This is a temporary migration into our codebase (see comment above). its planned to remove this again soon.
SummaryThis PR introduces a custom Key Changes:
Code QualityStrengths:
Minor observations:
Test CoverageUnit Tests (MultiSelectCell.test.tsx): The test coverage is comprehensive and follows Streamlit's TypeScript testing best practices:
E2E Test (st_data_editor_config_test.py): The new test
Suggestion (non-blocking): The E2E test uses Backwards CompatibilityNo breaking changes identified. The implementation is a drop-in replacement:
The removal of Security & RiskNo security concerns identified:
Low regression risk:
Recommendations
VerdictAPPROVED: This PR is well-implemented with comprehensive test coverage. The custom MultiSelectCell implementation maintains backwards compatibility while adding the valuable text selection enhancement. The code follows Streamlit's established patterns and best practices. The minor suggestions above are non-blocking and can be addressed in follow-up work if desired. This is an automated AI review using |
kmcgrady
left a comment
There was a problem hiding this comment.
Just a few questions and requests. I guess it's weird because we are expecting this to be removed because this should be included in the Glide Data Grid?
I guess I can say it's not as important to get this perfect, but I am not sure what is specifically Glide vs what is our code?
| > div { | ||
| border-radius: 0.25rem; | ||
| border: 1px solid var(--gdg-border-color); | ||
| } |
There was a problem hiding this comment.
Any reason we are not doing the object styled that we usually have recommended? I would recommend breaking this into the styled-components.ts like we've done in the past.
There was a problem hiding this comment.
Ah @lukasmasuch I see that we use emotion's styled vs Glide using linaria? Are there any other differences?
There was a problem hiding this comment.
The initial thought here was not to spread out this "temporary" code into potentially shared files. Also, changing this to object notation requires some eslint ignores. But no string opinion either way, I can also move it to styled-components if preferred.
emotion's styled vs Glide using linaria?
Only minor differences afaik, not impacting this component. So migration here to emotion is unproblematic.
There was a problem hiding this comment.
Ah okay. I am at least valid to know that this code is slightly modified from Glide at the very least. That being said, if the plan is to delete the code in favor of a Glide update, I am open to it.
There was a problem hiding this comment.
Yeah, I wrote down a note and will tweak this if it turns out that this will stay long-term in our codebase
| return { | ||
| value: option.value, | ||
| label: option.label ?? option.value ?? "", | ||
| color: option.color ?? undefined, |
There was a problem hiding this comment.
The ?? undefined is probably not necessary since that is what it could possibly be unless we want to handle the empty string "" in which case it could be option.color || undefined. Happy for more explicit, but wanted to check.
There was a problem hiding this comment.
removed the redundant ?? undefined`
| options: readonly SelectOption[], | ||
| allowDuplicates?: boolean | ||
| ): { value: string; label?: string; color?: string }[] => { | ||
| if (values === undefined || values === null) { |
There was a problem hiding this comment.
isNullOrUndefined(values)? I am not sure if we have a standard to use the convenience function or not, but it's used above so I figured we should stay consistent?
| const { ctx, theme, rect, highlighted } = args | ||
| const { values, options: optionsIn } = cell.data | ||
|
|
||
| if (values === undefined || values === null) { |
There was a problem hiding this comment.
Same here for isNullOrUndefined
The |
…umn` (#13663) ## Describe your changes Allows selecting text of pills in the MultiselectColumn and ListColumn. To do this, I have moved a fixed version of the multi-select cell implementation from glide-data-grid to Streamlit since the release process is currently broken on glide-data-grid. This will be a bit more of a temporary solution, and it's planned to switch back soon. - Closes #13646 ## Testing Plan - Added unit tests. --- **Contribution License Agreement** By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license. --------- Co-authored-by: Claude <[email protected]>
Describe your changes
Allows selecting text of pills in the MultiselectColumn and ListColumn. To do this, I have moved a fixed version of the multi-select cell implementation from glide-data-grid to Streamlit since the release process is currently broken on glide-data-grid. This will be a bit more of a temporary solution, and it's planned to switch back soon.
Testing Plan
Contribution License Agreement
By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.