Skip to content

Conversation

@KristinLBradley
Copy link
Contributor

@KristinLBradley KristinLBradley commented Dec 13, 2025

WIP: In the process of confirming desired layout behavior and testing edge cases.


📌 Summary

If merged, this PR adds responsive column width options to the existing @columnWidth arg of the LayoutGrid component.

Preview: https://hds-showcase-git-kristin-hds-5692-grid-responsive-hashicorp.vercel.app/layouts/grid#responsive-column-width

🛠️ Detailed description

  • Updates the existing @columnWidth option to allow responsive column widths to optionally be passed in as an object.

Views supported:

  • "sm" view (mobile devices)
  • "md" view, 768px and above (tablets and small laptops)
  • "lg" view, 1088px and above (large laptops and desktops)
  • "xl" view, 1440px and above (extra large desktops)
  • "xxl" view, 1920px and above (extra, extra large desktops)

Column layout behavior

Fluid layout:
Column widths are fluid by default. This means there will be as many column tracks as there are child items passed in, and their widths will adjust so that they always fill out a row.

Semi-fluid layout:
If a columnMinWidth is defined, items will wrap if necessary to avoid overflowing a row. If the passed-in items fit within a single row, the layout will be semi-fluid, with items being stretched to fill out the row. However, if there are more items than fit within a single row, the wrapping items will follow a more fixed layout, maintaining the same column structure as the first row of the layout.

Fixed layout:
If a columnWidth is passed in, the layout will behave as more fixed. So, if fewer items are passed in that the number of columns tracks dictated by the defined columnWidth, their widths will not stretch to fill out a row.

Usage examples:

  • Non-responsive columnWidth (3 columns in all views):
    <Hds::Layout::Grid @columnWidth="33.33%" />
  • "md" & above columnWidth overridden in "small view" only:
    <Hds::Layout::Grid @columnWidth={{hash sm="100%" md="33.33%"}} />
  • Different columnWidth for each supported view:
    <Hds::Layout::Grid @columnWidth={{hash sm="100%" md="50%" lg="33.33%" xl="25%" xxl="20%"}} />
  • All views have 2 columns, except "xxl" which has 4 columns
    <Hds::Layout::Grid @columnWidth={{hash sm="50%" xxl="25%"}} />

📸 Screenshots

Extra, extra large (xxl) view:
image

Extra large (xl) view:
image

Large (lg) view:
image

Medium (md) view:
image

Small (sm) view:
image

🔗 External links


👀 Component checklist

💬 Please consider using conventional comments when reviewing this PR.

📋 PCI review checklist
  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
  • If applicable, I've worked with GRC to document the impact of any changes to security controls.
    Examples of changes to controls include access controls, encryption, logging, etc.
  • If applicable, I've worked with GRC to ensure compliance due to a significant change to the in-scope PCI environment.
    Examples include changes to operating systems, ports, protocols, services, cryptography-related components, PII processing code, etc.

@vercel
Copy link

vercel bot commented Dec 13, 2025

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

Project Deployment Review Updated (UTC)
hds-showcase Ready Ready Preview Dec 22, 2025 10:36pm
hds-website Ready Ready Preview Dec 22, 2025 10:36pm

didoo

This comment was marked as outdated.

Co-authored-by: Jory Tindall <[email protected]>
Co-authored-by: Cristiano Rastelli <[email protected]>
…exity, update Showcase with additional examples
Copy link
Contributor

@didoo didoo left a comment

Choose a reason for hiding this comment

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

Left a few comments, but I think we're in the right direction.

export const GAPS: HdsLayoutGridGaps[] = Object.values(HdsLayoutGridGapValues);

type ResponsiveColumnWidths = {
sm?: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

[issue?] should this be required, with the current mobile-first approach? otherwise, with this code

<CodeFragmentWithPlaceholderItems
  @columnCount={{5}}
  @columnWidth={{hash lg="33.33%" xl="25%" xxl="20%"}}
/>

this happens:
Image

alternatively we could use somehow the width/min-width arguments, but I suspect it will make the API more complex

see what you find out, what works better

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, I think I've finally accounted for different use cases like this and fixed the issues.

So now, the column layout will be fluid by default so if you don't define any columnWidth or columnMinWidth, there will be as many columns as there are items within a row.

If you set a columnMinWidth, the layout will still be fluid, and items will stretch if necessary to fill a row.

If you set a columnWidth value, then fixed width columns will be created for the specific views you have passed in values for. Also, it uses a mobile-first approach so larger views will inherit the sm view styles if not overridden.

If the columnWidth for smaller views is left undefined and only larger view columnWidths are defined, then the smaller views will use a fluid layout.

So I think the behavior I've tried to describe makes the most sense, although it's tricky to describe clearly. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just discovered another bug caused by recent changes when fewer items than columns are passed in... (Working to fix)

Copy link
Contributor Author

@KristinLBradley KristinLBradley Dec 19, 2025

Choose a reason for hiding this comment

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

Alright, should be fixed now. I forgot to account for the layout behavior when a non-responsive columnWidth is passed in.


<ShwDivider @level={{2}} />

<ShwTextH4>With responsive column widths</ShwTextH4>
Copy link
Contributor

Choose a reason for hiding this comment

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

do you think we should have these in a "frameless" page so we can test them? the downside would be that we can't take Percy snapshots of them so they would not be covered for visual regression testing

alternatively, we could create a shared code snippet, to be used here but also in a frameless page, and we could put a link to it like I'm doing here: https://hds-showcase-git-project-solar-phase-1-main-fe-1ffc6c-hashicorp.vercel.app/foundations/theming#demo (see the link under the "demo" section)

Copy link
Contributor Author

@KristinLBradley KristinLBradley Dec 19, 2025

Choose a reason for hiding this comment

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

I can look at something like this once we agree upon the behavior & API details, as well as what types of examples are most useful.

Copy link
Contributor

Choose a reason for hiding this comment

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

On a second thought, maybe better to have a proper Demo section at the bottom of the page, after the Examples, with a standard frameless page that can be visible in the showcase page but also opened separately

didoo
didoo previously approved these changes Dec 22, 2025
Copy link
Contributor

@didoo didoo left a comment

Choose a reason for hiding this comment

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

I think it works. Now what I would do, before merging, is to stress test the implementation in the showcase (with a dedicated frameless page) and then start to think how to document the added APIs/features (it will not be simple)

grid-template-columns: repeat(
var(--hds-layout-grid-column-fill-type, auto-fit),
var(--hds-layout-grid-column-fill-type),
minmax(calc(var(--hds-layout-grid-column-min-width) - var(--hds-layout-grid-column-gap)), 1fr)
Copy link
Contributor

Choose a reason for hiding this comment

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

[question] with this formula, are there conditions where the min value is negative? is it something that may lead to strange layouts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If either the columnWidth or columnMinWidth are less than the gap width (gap = 48px wide max), then they will collapse until they are as narrow as possible, which looks to be about 1px wide. This doesn't seem like a likely scenario and if someone were setting column widths that narrow then they should expect weird behavior.


<ShwDivider @level={{2}} />

<ShwTextH4>With responsive column widths</ShwTextH4>
Copy link
Contributor

Choose a reason for hiding this comment

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

On a second thought, maybe better to have a proper Demo section at the bottom of the page, after the Examples, with a standard frameless page that can be visible in the showcase page but also opened separately

Co-authored-by: Cristiano Rastelli <[email protected]>
…howcase page organization for AppHeader and AppSideNav
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.

5 participants