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

[Lexical] Create initial Gallery View with Emoji Plugin Example #44

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

local-dev-korbit-ai-mentor[bot]
Copy link

@local-dev-korbit-ai-mentor local-dev-korbit-ai-mentor bot commented Aug 15, 2024

WHAT

Create initial Gallery View with Emoji Plugin Example

Description

  • Added initial Gallery View to have list of cards from Intern and Extern

  • TODO Have a details view for a card with description, right now it just kinda opens the example in a separate sandbox

Test plan

https://lexical-agv4wnh6m-fbopensource.vercel.app/gallery

Screenshot 2024-07-04 at 1 38 19 PM

Description by Korbit AI

Note

This feature is in early access. You can enable or disable it in the Korbit Console.

What change is being made?

Create an initial Gallery View with an example of the Emoji Plugin, including new components for displaying gallery cards and updating the Docusaurus configuration.

Why are these changes being made?

This change introduces a new Gallery section to showcase various plugins, starting with the Emoji Plugin, to enhance the documentation and provide users with interactive examples. This approach improves user engagement and provides a visual representation of available plugins.

Summary by CodeRabbit

  • New Features

    • Introduced a Gallery interface with multiple components for displaying a collection of items.
    • Added a Card component for rendering individual items in the gallery.
    • Implemented a responsive grid layout for the gallery to enhance accessibility and user experience.
  • Bug Fixes

    • Simplified the navigation structure by ensuring the Gallery is always available.
  • Documentation

    • Updated the import path for the GalleryPage component in the documentation to ensure accuracy and clarity.

Copy link
Author

Clone of the PR facebook/lexical#6369

Copy link

korbit-ai bot commented Aug 15, 2024

My review is in progress 📖 - I will have feedback for you in a few minutes!

Copy link

coderabbitai bot commented Aug 15, 2024

Walkthrough

The changes introduce a significant restructuring of the Docusaurus project, enhancing the gallery feature by simplifying configuration and ensuring consistent availability of components. The new components, such as Card, GalleryCards, and GalleryPage, streamline the rendering of information while accompanying styles improve the visual experience. Additionally, the removal of conditional logic and the introduction of a new metadata file signify a move toward a more unified and accessible documentation approach.

Changes

Files Change Summary
packages/lexical-website/docusaurus.config.js Removed conditional logic for plugins and settings, ensuring package-docs is always included and all docs are included.
packages/lexical-website/fb/sdoc-cache.json Introduced a metadata file with snippets initialized as an empty object and a description indicating it's auto-generated.
packages/lexical-website/src/components/Gallery/Card.js Added a Card component for rendering individual item cards with optimized rendering using React.memo.
packages/lexical-website/src/components/Gallery/GalleryCards.js Added a GalleryCards component for displaying a list of cards using the CardList sub-component.
packages/lexical-website/src/components/Gallery/GalleryPage.js Introduced a GalleryPage component that acts as a container for the gallery interface.
packages/lexical-website/src/components/Gallery/pluginList.js Added a plugins constant for dynamic plugin configuration for the EmojiPlugin.
packages/lexical-website/src/components/Gallery/styles.module.css Introduced CSS for styling the gallery component with a responsive design using CSS Grid.
packages/lexical-website/src/pages/gallery.md Updated import path for GalleryPage and simplified the section header by removing "WIP".

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GalleryPage
    participant GalleryCards
    participant Card

    User->>GalleryPage: Request gallery
    GalleryPage->>GalleryCards: Render cards
    GalleryCards->>Card: For each card
    Card->>GalleryCards: Return card info
    GalleryCards->>GalleryPage: Return list of cards
    GalleryPage->>User: Display gallery
Loading

🐇 In a world of pixels and light,
The Gallery shines, a beautiful sight.
Cards align, each tale they share,
With styles so sweet, beyond compare.
So hop on in, enjoy the view,
A joyful space, just for you! ✨


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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

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

I have reviewed your code and found 5 potential issues.

const image = getCardImage(item);
return (
<li key={item.title} className="card shadow--md">
<a href={item.uri} target="_blank">
Copy link

Choose a reason for hiding this comment

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

category Functionality

The anchor tag that opens the link in a new tab is missing the 'rel="noopener noreferrer"' attribute. When using 'target="_blank"', it's important to include this attribute to prevent potential security vulnerabilities. Please update the anchor tag to include this attribute.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +16 to +26
function CardList({cards}) {
return (
<div className="container">
<ul className={clsx('clean-list', styles.cardList)}>
{cards.map((item) => (
<Card key={item.title} item={item} />
))}
</ul>
</div>
);
}
Copy link

Choose a reason for hiding this comment

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

category Functionality

In the CardList component, it's important to add error handling for the 'cards' prop. Currently, if 'cards' is undefined or not an array, the component will throw an error when trying to map over it. Consider adding a check to ensure 'cards' is defined and is an array before rendering. For example:

function CardList({cards}) {
  if (!Array.isArray(cards)) {
    return <div>No cards to display</div>;
  }
  return (
    <div className="container">
      <ul className={clsx('clean-list', styles.cardList)}>
        {cards.map((item) => (
          <Card key={item.title} item={item} />
        ))}
      </ul>
    </div>
  );
}

This change will improve the robustness of the component and prevent potential runtime errors.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +25 to +46
function Card({item}) {
const image = getCardImage(item);
return (
<li key={item.title} className="card shadow--md">
<a href={item.uri} target="_blank">
<div className={clsx('card__image', styles.showcaseCardImage)}>
<img src={image} alt={item.title} />
</div>
</a>
<div className="card__body">
<div className={clsx(styles.showcaseCardHeader)}>
<Heading as="h4" className={styles.showcaseCardTitle}>
<Link href={item.website} className={styles.showcaseCardLink}>
{item.title}
</Link>
</Heading>
</div>
<p className={styles.showcaseCardBody}>{item.description}</p>
</div>
</li>
);
}
Copy link

Choose a reason for hiding this comment

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

category Functionality

I noticed that the Card component doesn't handle potential missing data in the 'item' prop. This could lead to runtime errors if any of the expected properties (title, uri, website, description) are undefined or null. Consider adding null checks or default values to ensure the component renders gracefully even with incomplete data. For example, you could use the optional chaining operator (?.) or provide fallback values using the nullish coalescing operator (??).

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +9 to +14
export const plugins = (customFields) => [
{
title: 'EmojiPlugin',
uri: `${customFields.STACKBLITZ_PREFIX}examples/vanilla-js-plugin?embed=1&file=src%2Femoji-plugin%2FEmojiPlugin.ts&terminalHeight=0&ctl=1`,
},
];
Copy link

Choose a reason for hiding this comment

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

category Functionality

The plugins function relies on customFields.STACKBLITZ_PREFIX, but there's no check to ensure customFields or STACKBLITZ_PREFIX are defined. This could lead to runtime errors if the function is called without the expected parameter or if STACKBLITZ_PREFIX is missing. Consider adding a default value or a check to handle cases where these might be undefined. For example:

export const plugins = (customFields = {}) => [
  {
    title: 'EmojiPlugin',
    uri: `${customFields.STACKBLITZ_PREFIX || ''}examples/vanilla-js-plugin?embed=1&file=src%2Femoji-plugin%2FEmojiPlugin.ts&terminalHeight=0&ctl=1`,
  },
];

This change would prevent potential runtime errors and make the function more robust.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

Comment on lines +20 to +22
{cards.map((item) => (
<Card key={item.title} item={item} />
))}
Copy link

Choose a reason for hiding this comment

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

category Functionality

In the CardList component, you're currently using the 'title' property as the key for each Card component. While this might work if all titles are unique, it's generally safer to use a dedicated unique identifier. Consider modifying the data structure in 'pluginList.js' to include a unique 'id' for each item, and then use this 'id' as the key. For example:

{cards.map((item) => (
  <Card key={item.id} item={item} />
))}

This change will ensure that React can efficiently update the list of cards, even if titles are not unique or if they change.

Chat with Korbit by mentioning @korbit-ai, and give a 👍 or 👎 to help Korbit improve your reviews.

@furwellness
Copy link
Owner

/review

@furwellness
Copy link
Owner

@coderabbitai review

Copy link

codiumai-pr-agent-free bot commented Aug 16, 2024

PR Reviewer Guide 🔍

(Review updated until commit 8707e68)

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Key issues to review

Accessibility Concern
The Card component uses an <a> tag with target="_blank" but does not include rel="noopener noreferrer". This can be a security risk and should be addressed to prevent potential window.opener API abuse.

Code Quality
The plugins function is called directly in the GalleryCards component without any error handling or checks if customFields is properly structured to avoid runtime errors.

Copy link

coderabbitai bot commented Aug 16, 2024

Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

Persistent review updated to latest commit 8707e68

@furwellness furwellness changed the base branch from cloned_main_a7a6a to main August 21, 2024 18:13
@furwellness
Copy link
Owner

@coderabbitai full review

Copy link

coderabbitai bot commented Aug 21, 2024

Actions performed

Full review triggered.

Copy link

@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: 5

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4cbb85f and 8707e68.

Files selected for processing (8)
  • packages/lexical-website/docusaurus.config.js (3 hunks)
  • packages/lexical-website/fb/sdoc-cache.json (1 hunks)
  • packages/lexical-website/src/components/Gallery/Card.js (1 hunks)
  • packages/lexical-website/src/components/Gallery/GalleryCards.js (1 hunks)
  • packages/lexical-website/src/components/Gallery/GalleryPage.js (1 hunks)
  • packages/lexical-website/src/components/Gallery/pluginList.js (1 hunks)
  • packages/lexical-website/src/components/Gallery/styles.module.css (1 hunks)
  • packages/lexical-website/src/pages/gallery.md (1 hunks)
Additional comments not posted (13)
packages/lexical-website/fb/sdoc-cache.json (1)

1-4: LGTM!

The file appears to be a generated cache file, and the content is appropriate for its purpose.

packages/lexical-website/src/pages/gallery.md (1)

6-8: LGTM!

The import path change enhances modularity, and the header update reflects the gallery's readiness.

packages/lexical-website/src/components/Gallery/GalleryPage.js (1)

1-17: LGTM!

The GalleryPage component is well-structured and ready for use.

packages/lexical-website/src/components/Gallery/styles.module.css (9)

8-12: LGTM!

The .cardList class effectively uses CSS Grid for responsive layout.


14-18: LGTM!

The .showcaseFavorite class is well-defined with appropriate padding and background color.


20-22: LGTM!

The dark mode styling for .showcaseFavorite is correctly implemented.


24-27: LGTM!

The .headingFavorites class effectively uses flexbox for alignment.


29-33: LGTM!

The .showcaseCardImage class is well-defined with appropriate styling.


35-39: LGTM!

The .showcaseCardHeader class effectively uses flexbox for layout.


41-44: LGTM!

The .showcaseCardTitle class is well-defined with appropriate styling.


46-54: LGTM!

The .showcaseCardTitle a class is well-defined with a smooth hover effect.


65-68: LGTM!

The .showcaseCardBody class is well-defined with appropriate styling for readability.

packages/lexical-website/docusaurus.config.js (1)

389-392: LGTM!

The addition of the "Gallery" link in the navbar aligns with the PR objectives and enhances user engagement.

Comment on lines +9 to +14
export const plugins = (customFields) => [
{
title: 'EmojiPlugin',
uri: `${customFields.STACKBLITZ_PREFIX}examples/vanilla-js-plugin?embed=1&file=src%2Femoji-plugin%2FEmojiPlugin.ts&terminalHeight=0&ctl=1`,
},
];
Copy link

Choose a reason for hiding this comment

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

Add error handling for customFields.

The plugins function relies on customFields.STACKBLITZ_PREFIX, which could lead to runtime errors if customFields or STACKBLITZ_PREFIX are undefined. Consider adding a default value or a check to handle these cases.

export const plugins = (customFields = {}) => [
  {
    title: 'EmojiPlugin',
    uri: `${customFields.STACKBLITZ_PREFIX || ''}examples/vanilla-js-plugin?embed=1&file=src%2Femoji-plugin%2FEmojiPlugin.ts&terminalHeight=0&ctl=1`,
  },
];

Comment on lines +16 to +26
function CardList({cards}) {
return (
<div className="container">
<ul className={clsx('clean-list', styles.cardList)}>
{cards.map((item) => (
<Card key={item.title} item={item} />
))}
</ul>
</div>
);
}
Copy link

Choose a reason for hiding this comment

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

Add error handling for the cards prop.

The CardList component should check if cards is defined and is an array before rendering to prevent potential runtime errors.

function CardList({cards}) {
  if (!Array.isArray(cards)) {
    return <div>No cards to display</div>;
  }
  return (
    <div className="container">
      <ul className={clsx('clean-list', styles.cardList)}>
        {cards.map((item) => (
          <Card key={item.title} item={item} />
        ))}
      </ul>
    </div>
  );
}

Comment on lines +20 to +22
{cards.map((item) => (
<Card key={item.title} item={item} />
))}
Copy link

Choose a reason for hiding this comment

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

Use a unique identifier for the Card key.

Using title as a key may not be unique. Consider modifying the data structure in pluginList.js to include a unique id for each item and use this id as the key.

{cards.map((item) => (
  <Card key={item.id} item={item} />
))}

const image = getCardImage(item);
return (
<li key={item.title} className="card shadow--md">
<a href={item.uri} target="_blank">
Copy link

Choose a reason for hiding this comment

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

Add rel="noopener noreferrer" to the anchor tag.

When using target="_blank", include rel="noopener noreferrer" to prevent potential security vulnerabilities.

<a href={item.uri} target="_blank" rel="noopener noreferrer">

Comment on lines +25 to +46
function Card({item}) {
const image = getCardImage(item);
return (
<li key={item.title} className="card shadow--md">
<a href={item.uri} target="_blank">
<div className={clsx('card__image', styles.showcaseCardImage)}>
<img src={image} alt={item.title} />
</div>
</a>
<div className="card__body">
<div className={clsx(styles.showcaseCardHeader)}>
<Heading as="h4" className={styles.showcaseCardTitle}>
<Link href={item.website} className={styles.showcaseCardLink}>
{item.title}
</Link>
</Heading>
</div>
<p className={styles.showcaseCardBody}>{item.description}</p>
</div>
</li>
);
}
Copy link

Choose a reason for hiding this comment

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

Handle potential missing data in the item prop.

The Card component should handle cases where properties like title, uri, website, or description might be undefined or null. Consider using optional chaining or default values.

function Card({item}) {
  const image = getCardImage(item);
  return (
    <li key={item.title ?? 'default-title'} className="card shadow--md">
      <a href={item.uri ?? '#'} target="_blank" rel="noopener noreferrer">
        <div className={clsx('card__image', styles.showcaseCardImage)}>
          <img src={image} alt={item.title ?? 'No title'} />
        </div>
      </a>
      <div className="card__body">
        <div className={clsx(styles.showcaseCardHeader)}>
          <Heading as="h4" className={styles.showcaseCardTitle}>
            <Link href={item.website ?? '#'} className={styles.showcaseCardLink}>
              {item.title ?? 'No title'}
            </Link>
          </Heading>
        </div>
        <p className={styles.showcaseCardBody}>{item.description ?? 'No description available.'}</p>
      </div>
    </li>
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants