Site-kit-wp: Allow widgets to register a fallback width

Created on 23 Oct 2020  ·  6Comments  ·  Source: google/site-kit-wp

When registering a widget, a width argument has to be provided (either quarter, half or full, indicating the width on desktop, which from there is inferred for smaller viewport widths). While this works for the majority of cases, there is at least one existing widget (see #2023) that requires two different widths in order to replicate the current UI behavior.

Widgets should be able to optionally include a fallbackWidth argument, supporting the same possible values. The widget renderering mechanism will try to use the regular width, but if this causes gaps in the UI, it will check for fallbackWidth and whether that would make the grid behave more nicely.


_Do not alter or remove anything below. The following sections will be managed by moderators only._

Acceptance criteria

  • registerWidget should support a new optional argument fallbackWidth. If provided, it must be one of the available WIDGET_WIDTHS.
  • The logic to layout the widget grid in WidgetAreaRenderer should be updated:

    • If the current widget's width is too much so that it will go into the next row (counter > 12):



      • First, test whether the widget has a fallbackWidth set and if so whether with that fallbackWidth it would still fit into the current row. If yes, rely on the counter value and CSS classes based on the fallbackWidth instead.


      • If not, check if the previous widget has a fallbackWidth set and if so whether that fallbackWidth would fill the remaining space in the current row that would otherwise get empty. If yes, replace the counter value and CSS classes of the previous widget based on the fallbackWidth values instead.



    • After iterating through all the widgets, but _before the final resizing logic (counter === 9), check if the last entire row is not full (counter < 12). If so, run the same logic described in the second bullet point above, checking the last widget's fallbackWidth and if possible to fill the remaining space alter its counter value and CSS classes.

  • The two following widgets should both be updated to specify half as primary width and full as secondary width:

    • urlSearch

    • searchConsolePopularKeywords

Implementation Brief

  • Add array support for the width argument in the registerWidget API. width can either be a single value (must be one of the available WIDGET_WIDTHS), or an array of values (must all be one of the available WIDGET_WIDTHS), with the preferred widths in order. See comment below for an example of usage.
  • The registerWidget calls for urlSearch and searchConsolePopularKeywords should be updated to use: width: [ WIDGET_WIDTHS.HALF, WIDGET_WIDTHS.FULL ] instead of width: WIDGET_WIDTHS.HALF.
  • All code that uses the Widget width should check to see if the width is a value or an array of values, then use the first value in the array if it's an array.
  • Update WidgetAreaRenderer's render logic to match the AC above, but to check for fallbackWidth, check to see if the width value is an array with more than one item. If it is, use the next available size in the array as the "fallbackWidth", then use the logic above to try it. Continue with each "fallback width" until the best sizing is achieved.
  • Add a new Storybook section for widget areas (eg. for the WidgetAreaRenderer component). In every story, one dummy widget area is rendered, and then various dummy widgets with different width arguments are registered for that area. For example stories like (not an exhaustive list):

    • 2 quarter widgets, one half widgets

    • 4 quarter widgets

    • 3 quarter widgets

    • 2 half widgets, 1 half widget that has full as secondary width

    • 1 half widget, 1 quarter widget that has half as secondary width, 1 full widget

Test Coverage

  • Add test coverage to ensure width arguments are supported in both raw value and array forms, including an array of one value.
  • Add coverage to ensure the fallback widths are used when appropriate.

Visual Regression Changes

  • This may result in the changing of widget areas if the fallbacks are used in any of the stories, but I don't think that will be the case.

QA Brief

  • Ensure all Jest tests pass—this will cover the logic above.
  • The urlSearch widget can be inspected in both of its widths by comparing what it looks like with the Analytics module active/inactive.
  • The searchConsolePopularKeywords widget can be inspected in both of its widths by comparing what it looks like on the Site Kit dashboard vs on the single URL page dashboard.

Changelog entry

  • Add support for widgets to have multiple (fallback) widths via googlesitekit.widgets.registerWidget, laying out widget grid with as few gaps as possible.
P0 Enhancement

All 6 comments

This is a good idea but I think we can be a bit more flexible with our approach here to allow for multiple fallback widths and a more descriptive param name.

Call these "fallback widths" is a bit confusing to me because they are fallbacks for the widget area layout—I just don't find it a very descriptive name. And I think the "fallback width" should support more than one width, because it could be that a widget will work at any size, but has an _ideal_ size (eg: the default).

What might be better is a supportedWidths: [sizeA, sizeB] type of argument that allows for multiple "fallbacks" to be supplied. Each one can be tried by the widget area renderer and the best will be used if the default doesn't fill the space in the optimal way.

But I think the best approach would be to accept either a single size or an array of sizes for each width. So you could do:

// How registration works today and would continue to work:
Widgets.registerWidget( 'pagespeedInsightsWebVitals', {
    component: DashboardPageSpeedWidget,
    width: Widgets.WIDGET_WIDTHS.HALF,
    wrapWidget: false,
}, [ AREA_DASHBOARD_SPEED, AREA_PAGE_DASHBOARD_SPEED ] );

// Nwe, multiple widths registration, where `fallbackWidth` is the second, and then
/// continued arguments after the first "ideal width":
Widgets.registerWidget( 'pagespeedInsightsWebVitals', {
    component: DashboardPageSpeedWidget,
    width: [ Widgets.WIDGET_WIDTHS.HALF, Widgets.WIDGET_WIDTHS.FULL ],
    wrapWidget: false,
}, [ AREA_DASHBOARD_SPEED, AREA_PAGE_DASHBOARD_SPEED ] );

That way supported widths are defined in a single param, and there's room for widgets to specify their order even if they support all widths.

@tofumatt IB mostly LGTM. I realized we also need to adjust the Search Console Popular Keywords widget in the same way (it should display half width on the dashboard, but full width on the page dashboard), so I've added that to the ACs and modified your IB with that.

I think another thing that would be great to add here is a general Storybook section for widget areas - basically stories for WidgetAreaRenderer. There could be multiple stories with different registry setups. In every story, one dummy widget area is rendered, and then various dummy widgets with different width arguments are registered for that area. For example stories like:

  • 2 quarter widgets, one half widgets
  • 4 quarter widgets
  • 3 quarter widgets
  • 2 half widgets, 1 half widget that has full as secondary width
  • 1 half widget, 1 quarter widget that has half as secondary width, 1 full widget

Just to point out some examples that would cover various different details of the expected grid behavior.

I would also advise to change the estimate to 19 - the logic to add here is fairly complex IMO and may require some finetuning once we're testing this. Together with the suggested Storybook coverage above, I think it warrants a 19.

@tofumatt Regarding the QA Brief (which btw is only required before the code review):

  • The urlSearch widget can be inspected in both of its widths by comparing what it looks like with the Analytics module active/inactive.
  • The searchConsolePopularKeywords widget can be inspected in both of its widths by comparing what it looks like on the Site Kit dashboard vs on the single URL page dashboard.

I like the idea of adding stories for those a lot! 👍🏻 They should probably be added to the VRT in general, but we can leave that as a separate issue if you'd like to move this one along.

Agreed on the 19, especially with the storybook additions. They're super-valuable though. 👍🏻

Your AC/IB updates look good and I've updated the IB/QA Brief here with your suggestions. I figured it was handy to at least start on the QA Brief before Code Review, but it of course can be edited if required. I just figured I'd give whoever has to write it a head-start 🙂

IB ✅

QA Update: Pass ✅

Verified:

The searchConsolePopularKeywords displays the same on the Site Kit dashboard vs on the single URL page dashboard. - Screenshot 1 Screenshot 2

The urlSearch widget displays like with the Analytics module active/inactive. - Screenshot

The Jest tests were completed as part of the PR/Code review.

Was this page helpful?
0 / 5 - 0 ratings