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

refactor(docs): revise code block #3922

Open
wants to merge 2 commits into
base: refactor/overall-dx
Choose a base branch
from

Conversation

wingkwong
Copy link
Member

@wingkwong wingkwong commented Oct 20, 2024

Closes #

📝 Description

  • apply fold logic for the upcoming dx change (js will be merged into the main tsx / jsx so by default they should be folded)

⛳️ Current behavior (updates)

🚀 New behavior

💣 Is this a breaking change (Yes/No):

📝 Additional Information

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced Codeblock component with improved code highlighting and rendering for different languages, including support for "diff" languages.
    • Introduced a new helper function for transforming tokens into a structured folder format.
    • Added new CSS classes to improve styling and layout for code components.
  • Bug Fixes

    • Fixed issues with line number rendering and token display for copyable elements.
  • Style

    • Updated global styles for <pre> elements and added new styles for interactive elements to enhance user experience.
    • Improved styles for the .sp-editor and related classes to ensure better layout and responsiveness.

Copy link

changeset-bot bot commented Oct 20, 2024

⚠️ No Changeset found

Latest commit: 86ec1fc

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented Oct 20, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
nextui-docs-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 20, 2024 10:12am
nextui-storybook-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 20, 2024 10:12am

Copy link
Contributor

coderabbitai bot commented Oct 20, 2024

Walkthrough

The pull request introduces significant updates to the Codeblock component, enhancing type safety and internal logic. It includes the addition of a new helper file for transforming tokens into a structured format, modifications to the MDXComponents for styling, and updates to global and Sandpack CSS files for improved presentation and interaction. Key changes involve refining the rendering logic and token handling, as well as adding new CSS classes for better layout and user experience.

Changes

File Path Change Summary
apps/docs/components/docs/components/codeblock.tsx - Added type imports for Language, PrismTheme, TransformTokensTypes.
- Modified BaseHighlight logic and rendering.
- Streamlined calculateLinesToHighlight function.
- Enhanced token rendering with a new renderFolderTokens function.
apps/docs/components/docs/components/helper.ts - Introduced helper.ts with TransformTokens and TransformTokensTypes types.
- Added transformTokens function for token processing.
apps/docs/components/mdx-components.tsx - Updated Code component to include a className prop for Codeblock.
apps/docs/styles/globals.css - Enhanced styling for <pre> elements and summary elements within details tags.
- Added transformations and visibility rules for various tokens.
apps/docs/styles/sandpack.css - Added new CSS classes .sp-editor, .sp-editor-viewer, and .sp-code-viewer.
- Modified existing styles for better layout and interaction.

Possibly related PRs

  • fix(docs): avoid translating the code block #3878: This PR modifies the Codeblock component by adding a translate attribute to the <pre> element, which directly relates to the changes made in the main PR that also focuses on the Codeblock component.

Suggested labels

📋 Scope : Docs

Suggested reviewers

  • winchesHe
  • ryo-manba

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.

@wingkwong wingkwong added this to the v2.5.0 milestone Oct 20, 2024
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: 4

🧹 Outside diff range and nitpick comments (5)
apps/docs/styles/sandpack.css (1)

30-33: LGTM, but consider adding a comment explaining the use of !important.

The addition of these classes with height: auto !important; is appropriate for allowing the editor to adjust its size based on content. However, the use of !important can sometimes lead to specificity issues.

Consider adding a comment explaining why !important is necessary here, such as:

.sp-editor,
.sp-editor-viewer {
  /* Use !important to override conflicting styles from the Sandpack library */
  height: auto !important;
}
apps/docs/styles/globals.css (1)

146-158: LGTM: Well-implemented expandable indicator. Consider accessibility enhancement.

The CSS rule for the summary arrow is well-implemented:

  1. Use of a pseudo-element for the arrow is appropriate.
  2. Absolute positioning and specific styling create a consistent look.
  3. The transition on transform allows for smooth rotation animation.

Suggestion for improvement:
Consider adding aria-hidden="true" to this decorative element in the HTML to enhance accessibility, ensuring screen readers don't announce the arrow character.

apps/docs/components/mdx-components.tsx (1)

155-160: LGTM! Consider using a constant for the className.

The addition of the "sp-editor" class to the Codeblock component aligns well with the PR objectives. This change will likely improve the presentation and functionality of code blocks in the documentation.

For better maintainability and consistency, consider defining the className as a constant at the top of the file or in a separate constants file. This would make it easier to update the class name across the codebase if needed in the future. For example:

const EDITOR_CLASS_NAME = "sp-editor";

// Then use it in the component
<Codeblock
  className={EDITOR_CLASS_NAME}
  codeString={codeString}
  language={language}
  metastring={meta}
/>
apps/docs/components/docs/components/helper.ts (2)

37-37: Prefer explicit type annotations over using any for better type safety.

Using null as any for startToken bypasses TypeScript's type checking and reduces type safety.

Consider updating the type of startToken to include null explicitly:

- let startToken: TransformTokens[0][0] = null as any;
+ let startToken: TransformTokens[0][0] | null = null;

This way, you maintain type safety and avoid using any.


101-101: Typo in comment: 'sure' should be 'ensure'.

In the comment on line 101, there's a typo where 'sure' should be 'ensure'.

Update the comment:

- // Add length check to sure it's added to } token
+ // Add length check to ensure it's added to } token
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 765dac5 and ab1aab9.

📒 Files selected for processing (5)
  • apps/docs/components/docs/components/codeblock.tsx (4 hunks)
  • apps/docs/components/docs/components/helper.ts (1 hunks)
  • apps/docs/components/mdx-components.tsx (1 hunks)
  • apps/docs/styles/globals.css (1 hunks)
  • apps/docs/styles/sandpack.css (1 hunks)
🧰 Additional context used
🪛 Biome
apps/docs/components/docs/components/codeblock.tsx

[error] 216-216: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)


[error] 260-260: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

apps/docs/components/docs/components/helper.ts

[error] 116-116: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🔇 Additional comments (9)
apps/docs/styles/sandpack.css (3)

35-39: LGTM: Consistent padding for code lines.

The addition of padding to .token-line within .sp-editor provides consistent spacing for code lines, improving the overall layout and readability of the code blocks.


41-43: LGTM: Appropriate padding for code viewer.

The addition of the .sp-code-viewer class with padding: 6px; enhances the visual presentation of the code blocks by providing some space around the content.


Line range hint 1-28: Verify integration with existing styles.

The new changes appear to integrate well with the existing styles. However, it's important to ensure that these changes don't introduce any unintended side effects, especially considering the use of !important in the new classes.

Please run the following script to check for any potential conflicts or overrides:

Also applies to: 45-89

✅ Verification successful

Style Integration Verified Successfully

No conflicting !important declarations found within .sp-editor and .sp-editor-viewer classes. The new changes integrate well with existing styles without introducing unintended side effects.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential style conflicts or overrides

# Test: Search for classes that might conflict with the new .sp-editor and .sp-editor-viewer
rg -i '\.sp-(editor|editor-viewer)' --type css

# Test: Look for other uses of !important that might conflict
rg '!important' --type css

# Test: Check for other styles affecting height of .sp-editor or .sp-editor-viewer
rg '\.sp-(editor|editor-viewer).*height' --type css

Length of output: 1621


Script:

#!/bin/bash
# Description: List all '!important' declarations in sandpack.css
rg '!important' --type css apps/docs/styles/sandpack.css

# Description: Check for '!important' declarations within .sp-editor and .sp-editor-viewer
rg '\.sp-(editor|editor-viewer)[^{]*\{[^}]*!important' --type css apps/docs/styles/sandpack.css

Length of output: 442

apps/docs/styles/globals.css (6)

100-102: LGTM: Effective visual feedback for expanded code blocks.

The CSS rule correctly applies a 90-degree rotation to the arrow indicator when the details are open, providing clear visual feedback to users.


104-106: Approved, but clarification needed on "custom-folder" class.

The CSS rule correctly hides the "custom-folder" span when details are open. However, it would be helpful to have more context on the purpose of this class and its relation to the expanded code block view.

Could you provide more information about the "custom-folder" class and its usage in the code blocks?


108-110: LGTM: Effective use of ellipsis for collapsed content.

The CSS rule appropriately adds an ellipsis after the "ellipsis-token" span when the details are not open, providing a clear visual cue that there's more content to be expanded.


112-126: LGTM: Excellent handling of copy token visibility with accessibility in mind.

The CSS rules effectively manage the visibility of the "copy-token" span:

  1. When collapsed, it's visually hidden but still accessible to screen readers.
  2. When expanded, it's completely hidden.

This approach maintains good accessibility while providing a clean user interface.


128-138: LGTM: Effective collapsed view management. Verify intended behavior.

The CSS rules effectively manage the display of collapsed code blocks:

  1. Closed details are displayed inline.
  2. Empty tokens and subsequent token lines are hidden when collapsed.

This creates a compact view, which seems appropriate. However, it's worth verifying if this behavior aligns perfectly with the intended user experience across all use cases.

Could you confirm that this collapsed view behavior is consistent with the design specifications and works well for all types of code blocks in the documentation?


140-144: LGTM: Clean and appropriate summary styling.

The CSS rules for the summary element are well-structured:

  1. Inline display ensures it flows with the text.
  2. Relative positioning allows for absolute positioning of child elements if needed.
  3. Removing the list-style creates a clean appearance.

These styles contribute to a polished look for the code block summaries.

apps/docs/components/docs/components/helper.ts Outdated Show resolved Hide resolved
apps/docs/components/docs/components/helper.ts Outdated Show resolved Hide resolved
apps/docs/components/docs/components/codeblock.tsx Outdated Show resolved Hide resolved
apps/docs/components/docs/components/codeblock.tsx Outdated Show resolved Hide resolved
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: 4

🧹 Outside diff range and nitpick comments (7)
apps/docs/components/docs/components/helper.ts (2)

142-159: Add more detailed comments to explain the algorithm

The checkIsFolder function uses an efficient stack-based approach to determine if a token represents a folder. However, it could benefit from more detailed comments explaining how the algorithm works. This would make it easier for other developers to understand and maintain the code.

Consider adding comments like this:

function checkIsFolder(
  token: TransformTokens[0],
  {specialStartFlag, specialEndFlag}: SpecialOptions = {},
) {
  // Use a stack to keep track of opening brackets
  const stack: string[] = [];
  const mergedStartFlagList = specialStartFlag ? [...startFlag, ...specialStartFlag] : startFlag;
  const mergedEndFlagList = specialEndFlag ? [...endFlag, ...specialEndFlag] : endFlag;

  // Iterate through each token
  for (const t of token) {
    // If we encounter an opening bracket, push it onto the stack
    if (mergedStartFlagList.includes(t.content)) {
      stack.push(t.content);
    // If we encounter a closing bracket, pop from the stack
    } else if (mergedEndFlagList.includes(t.content)) {
      stack.pop();
    }
  }

  // If the stack is not empty, we have unmatched opening brackets, indicating a folder
  return stack.length !== 0;
}

174-174: Add a comment explaining the purpose of $ character replacement

The purpose of replacing $ characters in the line content is not immediately clear. Consider adding a comment to explain why this is necessary.

Add a comment like this:

// Remove $ characters to handle special cases (e.g., template literals)
const transformLine = line.content.replace(/\$/g, "");
apps/docs/components/docs/components/codeblock.tsx (5)

Line range hint 28-38: LGTM: New constants for syntax highlighting look good.

The new constants nextuiCliCommand and highlightStyleToken enhance the syntax highlighting capabilities for NextUI CLI commands. This is a valuable addition to the component.

Consider adding a brief comment explaining the purpose of these constants for better code readability.


Line range hint 166-269: LGTM with suggestions: Enhanced rendering logic for complex code structures.

The new implementation using transformTokens and the added logic for handling folder-like structures significantly improve the component's capabilities. The conditional rendering for different token types enhances the overall functionality.

Consider the following optimizations for better performance:

  1. Memoize the result of transformTokens(tokens) to avoid unnecessary re-computations on re-renders.
  2. Use React.useMemo for complex computations within the render method, such as the highlightStyleToken.some(...) check.
  3. Consider extracting the inner rendering logic (e.g., renderLine, renderFolderTokens) to separate components to leverage React's memoization capabilities.

Example of memoizing transformTokens:

const memoizedTransformedTokens = React.useMemo(() => transformTokens(tokens), [tokens]);

These optimizations can help reduce unnecessary re-renders and improve the overall performance of the component, especially for large code blocks.


151-165: LGTM with suggestion: Improved pre element rendering and styling.

The updates to the pre element, including new class names and data attributes, enhance the styling and flexibility of the code block. The conditional classes for multi-line code and scroll behavior are particularly useful.

Consider adding an aria-label attribute to the pre element to improve accessibility. For example:

aria-label={`Code block in ${language} language`}

This will provide more context for screen reader users about the content of the code block.


Line range hint 210-247: LGTM with issue: Enhanced token rendering with copy and folder support.

The new logic for handling 'copy' tokens and folder content significantly improves the component's ability to represent complex code structures. This enhancement allows for more interactive and hierarchical code presentations.

There's a potential issue with missing key props in mapped elements. Specifically:

  1. In the mapping of token.folderContent (line 217), each mapped element should have a unique key prop.
  2. In the rendering of empty content (line 221), consider using a more meaningful key than just the index.

To fix these issues, apply the following changes:

- {token.folderContent?.map((folderTokens) => {
+ {token.folderContent?.map((folderTokens, folderIndex) => {
-   return folderTokens.map((token, index) => {
+   return folderTokens.map((token, tokenIndex) => {
      // Hack for wrap line
      return token.content === "" ? (
-       <div key={`${index}-${getUniqueID("line")}`} />
+       <div key={`empty-${folderIndex}-${tokenIndex}-${getUniqueID("line")}`} />
      ) : (
-       <span key={`${index}-${getUniqueID("line")}`}>{token.content}</span>
+       <span key={`content-${folderIndex}-${tokenIndex}-${getUniqueID("line")}`}>{token.content}</span>
      );
    });
  })}

These changes will ensure that each rendered element has a unique key, improving React's ability to efficiently update the DOM.


259-265: LGTM with suggestion: New folder rendering logic.

The addition of folder-like structure rendering using details and summary elements is a great enhancement. This allows for collapsible code sections, improving the overall user experience when dealing with large or complex code structures.

To improve accessibility, consider adding an aria-label to the summary element that describes the content of the folder. For example:

- <summary className="cursor-pointer">
+ <summary className="cursor-pointer" aria-label={`Folder: ${folderLine.summaryContent[0].content}`}>

This will provide more context for screen reader users about the content of each collapsible section.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between ab1aab9 and 86ec1fc.

📒 Files selected for processing (2)
  • apps/docs/components/docs/components/codeblock.tsx (4 hunks)
  • apps/docs/components/docs/components/helper.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
apps/docs/components/docs/components/helper.ts (2)

1-11: Well-structured type declarations

The type declarations are well-defined and make good use of TypeScript features. The TransformTokens type utilizes the Parameters utility type for accurate type inference, and TransformTokensTypes extends the base token type appropriately for the transformation logic.


116-118: Good job on addressing the previous issue

The previously flagged issue of assignment within an expression has been correctly addressed. The current implementation is cleaner and more readable.

apps/docs/components/docs/components/codeblock.tsx (2)

1-10: LGTM: Import statements and type definitions look good.

The new imports and type definitions enhance type safety and introduce new functionality. These changes align well with the refactoring being done to the Codeblock component.


199-208: LGTM: Improved line number rendering.

The updated logic for rendering line numbers with conditional classes based on digit count is a great improvement. This ensures proper alignment and enhances the visual presentation of the code block, especially for files with a large number of lines.

@wingkwong wingkwong changed the base branch from canary to refactor/overall-dx October 25, 2024 04:29
Copy link
Member

@ryo-manba ryo-manba left a comment

Choose a reason for hiding this comment

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

Could you please provide a more detailed explanation in the PR about why this change is necessary and what it accomplishes? If there are any related issues or PRs, please link to them as well.

@wingkwong
Copy link
Member Author

Some examples may import other code such as data.js, logo.tsx and etc. Currently it displays in different tabs. For example, data.js in https://nextui.org/docs/components/autocomplete#label-placements. With the new raw approach, you cannot import that in raw (from users perspective, the code should be ready to use by copying and pasting). Hence I put all the code together in the one single file App.jsx. In this case, users can just copy one file instead of setting up one by one. This is also a future plan for NextUI Pro as well. Since putting all the code together would make the code block longer, hence this PR introduces a collapsible code block, similar to nextui pro one, so that users can only focus on the main logic and expand other code if necessary.

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