Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak dropdownview to allow to display icon only #4881

Merged
merged 3 commits into from
Oct 10, 2024

Conversation

lanzhenw
Copy link
Contributor

@lanzhenw lanzhenw commented Oct 3, 2024

What changes are proposed in this pull request?

allow to pass down icon ("SettingsIcon" and "MoreVertIcon" at the moment) to menu, to make the dropdown view an action icon button menu.

How is this patch tested? If it is not, please explain why.

Screen.Recording.2024-10-07.at.4.22.41.PM.mov

(Details)

Release Notes

Is this a user-facing change that should be mentioned in the release notes?

  • No. You can skip the rest of this section.
  • Yes. Give a description of this change to be included in the release
    notes for FiftyOne users.

(Details in 1-2 sentences. You can just refer to another PR with a description
if this PR is part of a larger change.)

What areas of FiftyOne does this PR affect?

  • App: FiftyOne application changes
  • Build: Build and test infrastructure changes
  • Core: Core fiftyone Python library changes
  • Documentation: FiftyOne documentation changes
  • Other

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Enhanced the DropdownView component to support dynamic icons, allowing users to display icons alongside or instead of text in dropdown menus.
    • Introduced a new icon parameter in the MenuView class, enabling customization of the menu trigger with icons like SettingsIcon and MoreVertIcon.
    • Improved performance of the DropdownView with optimized rendering logic and style management.

@lanzhenw lanzhenw self-assigned this Oct 3, 2024
Copy link
Contributor

coderabbitai bot commented Oct 3, 2024

Walkthrough

The pull request modifies the DropdownView component in DropdownView.tsx by introducing new imports for icons and adding properties to the view object. A state variable for dynamically importing icons is added, along with several new functions for styling and rendering. The computation of choiceLabels is optimized using useMemo, and the rendering logic is encapsulated in a new function that conditionally displays the icon. Changes are also made to the MenuView class in types.py, allowing an icon to be specified for the menu trigger.

Changes

File Path Change Summary
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx Introduced new imports for icons, added icon and useIconOnly properties to view, added state variable IconComponent, and implemented new functions for styling and rendering.
fiftyone/operators/types.py Enhanced MenuView class by adding icon parameter to its constructor and updated documentation accordingly.

Possibly related PRs

  • visual tweaks for menu and views in menu #4562: The changes in DropdownView.tsx within this PR involve adding new props and modifying rendering logic, which directly relates to the updates made in the main PR regarding the DropdownView component.

Suggested reviewers

  • ritch
  • sashankaryal

Poem

In the dropdown where choices play,
An icon now leads the way.
With useIconOnly, bright and clear,
Settings shine, bringing cheer!
A hop, a skip, a joyful glance,
In our code, we dance a chance! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (2)

28-28: Add type annotation for useIconOnly

The addition of useIconOnly with a default value of false is good. However, consider adding a type annotation for consistency and improved type safety.

-    useIconOnly = false,
+    useIconOnly: boolean = false,

87-89: Consider accessibility for icon-only display

The conditional rendering of SettingsIcon based on useIconOnly is implemented correctly. However, displaying only an icon without any text might impact accessibility and user experience.

Consider adding an aria-label or title attribute to the icon to provide context for screen readers and on hover. For example:

return <SettingsIcon aria-label="Settings" />;

Also, it might be beneficial to add documentation or comments explaining the purpose and usage of the useIconOnly option.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between babdb74 and 3666f36.

📒 Files selected for processing (1)
  • app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (2)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (2)

1-1: LGTM: Import of SettingsIcon

The import of SettingsIcon from @mui/icons-material is correctly placed and necessary for the new functionality.


Line range hint 1-134: Summary of changes and request for additional information

The changes successfully implement the ability to display only an icon in the dropdown view. The code is well-structured and consistent with the existing style. However, there are a few points to address:

  1. Consider adding type annotations for improved type safety.
  2. Enhance accessibility for the icon-only display.
  3. The PR description is incomplete. Please provide more details about:
    • The specific use case for this change
    • How it has been tested
    • Whether this is a user-facing change
    • Which areas of the FiftyOne application it affects

To help identify the impact areas, please run the following script:

This will help determine where the component is used and potentially affected by this change.

✅ Verification successful

Impact Areas Confirmed

The DropdownView component is utilized in the following locations:

  • app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx
  • app/packages/core/src/plugins/SchemaIO/components/index.ts
  • app/packages/core/src/plugins/OperatorIO/utils/index.ts

The implementation successfully allows for icon-only display in the dropdown view. The code adheres to the existing style and structure, and the impact areas have been clearly identified. No further issues were found regarding type safety or accessibility based on the current changes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of DropdownView component
rg --type typescript 'DropdownView'

Length of output: 70


Script:

#!/bin/bash
# Search for usages of DropdownView component
rg --type typescriptreact 'DropdownView'

Length of output: 80


Script:

#!/bin/bash
# Search for usages of DropdownView component in .ts and .tsx files
rg 'DropdownView' --glob '*.ts' --glob '*.tsx'

Length of output: 541

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (3)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

180-246: LGTM: New rendering functions with a minor suggestion

The introduction of renderIcon and renderMenuDropdown functions significantly improves code organization and readability. The logic for handling icon-only and regular dropdown views is well-implemented.

The renderIcon function correctly handles the case when IconComponent is null, and the renderMenuDropdown function successfully integrates the new icon rendering logic while maintaining existing dropdown functionality.

Consider adding a comment explaining the purpose of the setSelected(!unselected) call in the renderValue function, as its purpose might not be immediately clear to other developers.

renderValue={(value) => {
  // ...
  const unselected = value?.length === 0;
  setSelected(!unselected); // Update selected state for styling purposes
  // ...
}}

This minor addition would improve code clarity and maintainability.

fiftyone/operators/types.py (2)

Line range hint 2359-2388: Approved: New 'icon' parameter enhances UI flexibility.

The addition of the 'icon' parameter to the MenuView class is a good improvement, allowing for more versatile UI designs by enabling the use of an icon button as the menu trigger.

Consider updating the docstring to include examples of how to use the new 'icon' parameter, which would help developers understand and implement this feature more easily.


2367-2368: Minor formatting and clarity improvements needed.

The description of the new 'icon' parameter is clear and concise. However, there are two minor issues to address:

  1. The indentation of these lines is slightly off compared to the surrounding text. Ensure consistent indentation throughout the docstring.
  2. The description could be more specific about the type of icons accepted.

Consider adjusting the lines as follows:

-        icon (None): when set, the icon button will be displayed as the menu trigger,
-        instead of the selected value. Can be "SettingsIcon" or "MoreVertIcon"
+        icon (None): when set, the icon button will be displayed as the menu trigger
+            instead of the selected value. Can be a string like "SettingsIcon" or "MoreVertIcon"

This change improves readability and clarifies that the icon parameter expects a string value.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 73549ad and f80aaef.

📒 Files selected for processing (2)
  • app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (4 hunks)
  • fiftyone/operators/types.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (4)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (3)

35-38: LGTM: New icon property and state variable

The addition of the icon property to the view object and the new IconComponent state variable are well-implemented. These changes provide the necessary foundation for the new icon-only display functionality, enhancing the component's flexibility.


171-178: LGTM: Dynamic icon loading implementation

The implementation of dynamic icon loading using the useEffect hook is well done. This approach ensures that icons are only loaded when needed, which is beneficial for performance. The dependency array correctly includes the icon prop, ensuring that the effect runs when the icon changes.

This is a good example of code splitting and lazy loading, which can significantly improve the application's performance, especially when dealing with multiple icons.


248-254: LGTM: Flexible rendering based on icon presence

The changes to the component's return statement are well-implemented. The use of a ternary operator for conditional rendering based on the presence of an icon is concise and readable.

This approach effectively handles both icon-only and regular dropdown views, maintaining backwards compatibility for existing usage without an icon. It's a good example of enhancing component flexibility without breaking existing functionality.

fiftyone/operators/types.py (1)

Line range hint 2359-2388: Summary: Positive enhancement to MenuView with minor improvements needed.

The changes to the MenuView class introduce a valuable new feature by adding the 'icon' parameter. This enhancement allows for more flexible UI designs by enabling the use of icon buttons as menu triggers. The implementation appears sound, although it's not fully visible in this diff.

While the core functionality is well-implemented, there are minor improvements that can be made to the documentation:

  1. Consistent indentation in the docstring.
  2. More specific description of the 'icon' parameter type and usage.
  3. Consider adding usage examples for the new feature.

Overall, these changes represent a positive improvement to the MenuView class, enhancing its versatility for UI development.

Comment on lines +1 to +2
import { IconButton, MenuItem, Select } from "@mui/material";
import React, { useEffect, useMemo, useState } from "react";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider moving iconImports to a separate configuration file

The addition of dynamic icon imports is a good practice for code splitting and performance optimization. However, to improve maintainability, consider moving the iconImports object to a separate configuration file. This would make it easier to add or modify supported icons in the future without changing the component logic.

You could create a new file, e.g., iconConfig.ts:

export const iconImports: {
  [key: string]: () => Promise<{ default: React.ComponentType<any> }>;
} = {
  MoreVertIcon: () => import("@mui/icons-material/MoreVert"),
  SettingsIcon: () => import("@mui/icons-material/Settings"),
};

Then import it in this file:

import { iconImports } from './iconConfig';

This approach would make the component more modular and easier to maintain.

Also applies to: 11-17

Comment on lines +73 to +111
const getIconOnlyStyles = () => ({
"&.MuiInputBase-root.MuiOutlinedInput-root.MuiInputBase-colorPrimary": {
backgroundColor: "transparent !important",
borderRadius: "0 !important",
border: "none !important",
boxShadow: "none !important",
"&:hover, &:focus": {
backgroundColor: "transparent !important",
boxShadow: "none !important",
},
},
"& .MuiSelect-select": {
padding: 0,
background: "transparent",
"&:focus": {
background: "transparent",
},
},
"& .MuiInputBase-root": {
background: "transparent",
},
"& .MuiOutlinedInput-notchedOutline": {
border: "none",
},
"& .MuiSelect-icon": {
display: "none",
},
});

const getDefaultStyles = (selected: boolean) => ({
".MuiSelect-select": {
padding: "0.45rem 2rem 0.45rem 1rem",
opacity: selected ? 1 : 0.5,
},
});

const getDropdownStyles = (icon: string | undefined, selected: boolean) => {
return icon ? getIconOnlyStyles() : getDefaultStyles(selected);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider further abstraction for styling functions

The addition of separate styling functions (getIconOnlyStyles, getDefaultStyles, and getDropdownStyles) improves code organization and maintainability. However, the styling objects are quite large and contain some repetition.

Consider the following improvements:

  1. Extract common styles into a base style object.
  2. Use a CSS-in-JS solution like styled-components or @emotion/styled for better style management.
  3. Create a separate styles file to keep the component logic and styling separate.

Example of extracting common styles:

const baseStyles = {
  backgroundColor: "transparent !important",
  boxShadow: "none !important",
};

const getIconOnlyStyles = () => ({
  "&.MuiInputBase-root.MuiOutlinedInput-root.MuiInputBase-colorPrimary": {
    ...baseStyles,
    borderRadius: "0 !important",
    border: "none !important",
    "&:hover, &:focus": baseStyles,
  },
  // ... rest of the styles
});

This approach would make the styling more maintainable and reduce duplication.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

125-142: LGTM with a minor suggestion: Dynamic icon import and rendering

The implementation of dynamic icon import using useEffect and the conditional rendering of the icon in renderIcon are well done. The use of IconButton for wrapping the icon improves accessibility.

Consider adding error handling for the dynamic import to gracefully handle cases where the icon import fails:

useEffect(() => {
  if (icon && iconImports[icon]) {
    iconImports[icon]()
      .then((module) => {
        setIconComponent(() => module.default);
      })
      .catch((error) => {
        console.error(`Failed to load icon: ${icon}`, error);
        setIconComponent(null);
      });
  }
}, [icon]);

This will ensure that any issues with icon loading are properly logged and don't break the component.

fiftyone/operators/types.py (1)

409-411: LGTM! Consider enhancing the docstring.

The addition of the icon parameter is a good improvement, allowing for more versatile UI options. The docstring update is informative.

Consider adding a brief explanation of when to use icons instead of labels, to guide developers in making appropriate UI decisions. For example:

 Can be "SettingsIcon", "MoreVertIcon".
+Use icons when space is limited or for a more compact visual representation.
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f80aaef and ea0394e.

📒 Files selected for processing (2)
  • app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (6 hunks)
  • fiftyone/operators/types.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (7)
app/packages/core/src/plugins/SchemaIO/components/DropdownView.tsx (7)

1-2: LGTM: New imports added correctly

The new imports for IconButton and useState are correctly added and necessary for the new icon functionality.


11-18: Consider moving iconImports to a separate configuration file

The addition of dynamic icon imports is a good practice for code splitting and performance optimization. However, to improve maintainability, consider moving the iconImports object to a separate configuration file. This would make it easier to add or modify supported icons in the future without changing the component logic.


35-38: LGTM: New state variable for icon component added correctly

The new icon property and IconComponent state variable are correctly implemented for handling the dynamically imported icon component. The naming convention follows React best practices.


66-71: LGTM: Optimized choiceLabels computation

The use of useMemo for computing choiceLabels is a good optimization. It ensures that the labels are only recomputed when the choices prop changes, potentially improving performance for large lists of choices.


73-111: Consider further abstraction for styling functions

The addition of separate styling functions (getIconOnlyStyles, getDefaultStyles, and getDropdownStyles) improves code organization and maintainability. However, the styling objects are quite large and contain some repetition.


113-122: LGTM: Updated getComponentProps call

The getComponentProps call has been correctly updated to use the new styling functions. The use of the spread operator for combining styles is appropriate and maintains good readability.


156-158: LGTM: Updated renderValue function

The renderValue function has been correctly updated to conditionally render the icon when the icon prop is provided. The logic is clear and concise, maintaining good readability.

Copy link
Contributor

@Br2850 Br2850 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽

@Br2850 Br2850 merged commit 6b79c47 into feat/fo-assistant Oct 10, 2024
9 of 13 checks passed
@Br2850 Br2850 deleted the patch/dropdownview branch October 10, 2024 15:29
@lanzhenw lanzhenw restored the patch/dropdownview branch October 14, 2024 19:53
@Br2850 Br2850 deleted the patch/dropdownview branch October 16, 2024 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants