Skip to content

feat: create responsive table #8079

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

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

Conversation

araujogui
Copy link
Member

Description

Creates a responsible table

Validation

image

Related Issues

Fixes #7656

Check List

  • I have read the Contributing Guidelines and made commit messages that follow the guideline.
  • I have run pnpm format to ensure the code follows the style guide.
  • I have run pnpm test to check if all tests are passing.
  • I have run pnpm build to check if the website builds without errors.
  • I've covered new added functionality with unit tests if necessary.

@Copilot Copilot AI review requested due to automatic review settings August 15, 2025 21:32
@araujogui araujogui requested a review from a team as a code owner August 15, 2025 21:32
Copy link

vercel bot commented Aug 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
nodejs-org Ready Ready Preview Aug 17, 2025 0:28am

Copilot

This comment was marked as outdated.

Copy link

codecov bot commented Aug 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.15%. Comparing base (8ab9cea) to head (5bb7a10).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8079      +/-   ##
==========================================
- Coverage   73.20%   73.15%   -0.05%     
==========================================
  Files          97       97              
  Lines        8448     8448              
  Branches      227      228       +1     
==========================================
- Hits         6184     6180       -4     
- Misses       2263     2267       +4     
  Partials        1        1              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@ovflowd ovflowd left a comment

Choose a reason for hiding this comment

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

I really like the designs! But won't that mean we would need to manually change all tables? What about the Markdown-based ones? Would we have a WithResponsibleTable thingy?

avivkeller
avivkeller previously approved these changes Aug 15, 2025
Copy link
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

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

I love that 🤘

@avivkeller avivkeller dismissed their stale review August 16, 2025 15:18

I actually realized a concern I have with this. I'm retracting my approval, but I won't block.

Is there a way to make this match the syntax of a normal table, and use children rather than props? With props, we can't add this to our MDX processor, and such, MDX tables (i.e. https://nodejs-5rit8fohj-openjs.vercel.app/en/learn/getting-started/debugging#command-line-options) will not be responsive.

@avivkeller
Copy link
Member

avivkeller commented Aug 16, 2025

The tables here pail in comparison (size wise) to the ones in the node core, so markdown compatibility is really important to me on this

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR creates a responsive table component system that transforms traditional HTML tables into mobile-friendly layouts. The implementation includes utilities for parsing table structures, responsive desktop/mobile views, and integration with MDX for seamless table rendering.

  • Adds table parsing utilities to extract columns and data from React table elements
  • Creates a responsive table component that shows traditional tables on desktop and card-based layouts on mobile
  • Integrates the responsive table with MDX rendering and refactors an existing table implementation

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/ui-components/src/util/table.ts Utility functions for parsing table structure from React elements
packages/ui-components/src/types.ts Type definitions for table columns and data
packages/ui-components/src/MDX/Table/index.tsx MDX table component wrapper using the responsive table
packages/ui-components/src/Common/ResponsiveTable/index.tsx Main responsive table component with desktop/mobile views
packages/ui-components/src/Common/ResponsiveTable/index.stories.tsx Storybook stories for the responsive table component
packages/ui-components/src/Common/ResponsiveTable/MobileTable/index.tsx Mobile card-based table implementation
packages/ui-components/src/Common/ResponsiveTable/MobileTable/index.module.css Styles for mobile table layout
packages/ui-components/src/Common/ResponsiveTable/DesktopTable/index.tsx Desktop traditional table implementation
packages/ui-components/src/Common/Card/index.tsx Card component used by mobile table
packages/ui-components/src/Common/Card/index.stories.tsx Storybook stories for card component
packages/ui-components/src/Common/Card/index.module.css Card component styles
apps/site/next.mdx.use.client.mjs Integration of table component with MDX rendering
apps/site/components/Releases/PreviousReleasesTable.tsx Refactored existing table to use responsive table component

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Member

Choose a reason for hiding this comment

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

need unit test here

Copy link
Member

Choose a reason for hiding this comment

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

I also believe this file could benefit from some cleanup, inline documentation+jsdocs and please use brackets on if statements.

const thead = nodes.find(node => isTableElement(node, 'thead'));
const tbody = nodes.find(node => isTableElement(node, 'tbody'));

if (!thead) throw new Error('Thead element not found');
Copy link
Member

Choose a reason for hiding this comment

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

I don't think Markdown tables require headers, or do they?

@@ -0,0 +1,98 @@
import {
Copy link
Member

Choose a reason for hiding this comment

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

Separate type imports from actual imports.


import type { TableColumn, TableData } from '#ui/types';

const hasChildren = (props: unknown): props is { children: ReactNode } =>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const hasChildren = (props: unknown): props is { children: ReactNode } =>
const hasChildren = (props: {}): props is PropsWithChildren<typeof props> =>

<td data-label="Date">
<FormattedTime date={release.currentStart} />
</td>
const columns = [
Copy link
Member

Choose a reason for hiding this comment

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

Here's my spicy take on this:

  • I don't like this design of passing header/data as props
  • This responsive table component should work as the regular HTML table
  • Pretty much should just be import Table from #ui/common/Table
  • That common table could already come with a mapper to map the children into the proper props
  • Then you won't need a MDX version of this component. I believe you can also handle the type of the component as the same type of an actual HTML table.

What is really confusing here is the separate DOM structure for Mobile and Desktop tables and that you are pretty much rendering a much larger and complex DOM structure https://github.com/nodejs/nodejs.org/pull/8079/files#diff-e77faf52f4e475e7e36e8b4f5c935b9a8c2fb506f89b70ec130a6ed602007c0cR13-R25 for every table.

I know this might sound harder, but I do really believe you can achieve all you want with pure CSS.

I don't even think we need a custom component, it's like we're reinventing the wheel here. I do believe you can achieve all you want purely based on CSS. Might be harder? Hell yes, even more that heading separation. Below is an example query I gave to ChatGPT:

Check the example styles below:

/* Base table styles (desktop) */
table {
  width: 100%;
  border-collapse: collapse;
}
thead th {
  text-align: left;
  padding: 8px;
}
tbody td {
  padding: 8px;
  border-bottom: 1px solid #ddd;
}

/* Mobile layout: stack each row */
@media (max-width: 600px) {
  thead {
    /* Hide the table header visually but keep it for accessibility */
    position: absolute;
    clip: rect(0 0 0 0);
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  table, tbody, tr, td {
    display: block;
    width: 100%;
  }

  tr {
    margin-bottom: 1em;
    border: 1px solid #ccc;
    padding: 8px;
  }

  td {
    /* Indent data and make space for label */
    position: relative;
    padding-left: 50%;
    text-align: left;
  }

  td::before {
    content: attr(data-title);
    position: absolute;
    top: 50%;
    left: 8px;
    transform: translateY(-50%);
    font-weight: bold;
    white-space: nowrap;
  }
}

How It Works

  • Desktop View: The table appears normally with headers on top.
  • Mobile View (max-width: 600px):
    • The <thead> is visually hidden for space-saving, but remains accessible.
    • Each <tr> becomes a block, spaced out like its own mini-card.
    • Each <td> displays a label from its data-title attribute using ::before, mimicking column headers.

Copy link
Member

Choose a reason for hiding this comment

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

Note the above is just an example, but you can absolutely 100% achieve this with pure CSS.

Copy link
Member

Choose a reason for hiding this comment

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

I actually don't think you can achieve the card-based layout with CSS (since, it requires addition text to be displayed) but you definitely can with a custom component matching the syntax of a table.

Copy link
Member

Choose a reason for hiding this comment

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

You posted this twice. But yes, it is possible to do it with pure CSS.

Copy link
Member

@avivkeller avivkeller Aug 17, 2025

Choose a reason for hiding this comment

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

You posted this twice.

Oh, GitHub Mobile 😭

attr(data-title)

This would still require a custom component / modifying the markdown to add this field.

Copy link
Member

@ovflowd ovflowd Aug 17, 2025

Choose a reason for hiding this comment

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

Not really... You can do that directly on Remark.

Copy link
Member

@ovflowd ovflowd Aug 17, 2025

Choose a reason for hiding this comment

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

But if not on Remark, yes, you can make a wrapper, like a WithResponseTable that just introspects the thead and tbody and adds the title tag to the tr's. But I do prefer the remark path, as it can be easily done as a plugin for specifcially table elements, and visits the Nodes and then just updates the attributes :)

Which adds a bit more of processing (CPU) but at least less JSX/interpretation for the client-side.

Copy link
Member

@ovflowd ovflowd left a comment

Choose a reason for hiding this comment

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

Reverting my approval to a request of changes based on my previous comments 👀

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.

Poor Table UX on Mobile
4 participants