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

feat(components): improve positioning of DataList actions [JOB-99926] #1915

Merged
merged 20 commits into from
Sep 20, 2024

Conversation

chris-at-jobber
Copy link
Contributor

Motivations

When the content in the last column of a DataList row is full-width or right-aligned, the "hover" actions on the row can be obscured. This violates the "recognition over recall" principle.

Changes

Changed

  • reduced the size of the DataList hover actions and changed their offset to avoid covering contents of the rightmost column

Testing

Hover over a row

Changes can be
tested via Pre-release


In Atlantis we use Github's built in pull request reviews.

Random photo of Atlantis

Copy link

github-actions bot commented Jun 5, 2024

Could not publish Pre-release for 6945243. View Logs
The problem is likely in the NPM Publish or NPM CI step in the Trigger Pre-release Build Job.

Previous build information:

Published Pre-release for 6945243 with versions:

  - @jobber/components@5.7.9-poc-moving-6945243.15+69452437

To install the new version(s) for Web run:

npm install @jobber/components@5.7.9-poc-moving-6945243.15+69452437
```.

Copy link

cloudflare-workers-and-pages bot commented Jul 10, 2024

Deploying atlantis with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7794a79
Status: ✅  Deploy successful!
Preview URL: https://4d291804.atlantis.pages.dev
Branch Preview URL: https://poc-moving-datalist-actions.atlantis.pages.dev

View logs

@chris-at-jobber chris-at-jobber changed the title feat(components): improve positioning of DataList actions feat(components): improve positioning of DataList actions [JOB-99926] Jul 10, 2024
@@ -21,8 +21,8 @@ export function DataListItemActions<T extends DataListObject>(
}

const variants: Variants = {
hidden: { opacity: 0, y: 10 },
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 0 },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adjusts the animation to map better to the new position

@@ -54,7 +54,7 @@ export function DataListActions<T extends DataListObject>({
(props.onClick as () => void)?.();
}
}}
type="secondary"
type="tertiary"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tertiary button in the "individual" actions

@@ -22,7 +22,7 @@ export function DataListItemActionsOverflow<T extends DataListObject>({
<Button
icon="more"
ariaLabel="More actions"
type="secondary"
type="tertiary"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

tertiary button in the "more" actions

unclear to me at this point why this action is different from the DataList actions but here we are

Copy link
Contributor

Choose a reason for hiding this comment

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

It's a good separation of concerns.
DataListActions are rendering the primary actions we see on hover. DataListItemActionsOverflow is that ••• menu button and needs to handle state for opening/closing the menu

I think we could also pretty easily extract & simplify DataListItemActionsOverflow to share with other menus that would have the same behaviour. Obviously not something we'll do now but, hope that helps clear things a little

@@ -25,7 +24,7 @@ export function DataListActions<T extends DataListObject>({
childrenArray.splice(0, exposedActions.length);

return (
<DataListOverflowFade>
<>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This impacts both the "row" actions and the "bulk" actions, but has no negative impact on either instance:

image image image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At one point the design direction was to have the bulk actions be scrollable, which is likely why this was implemented, but you can see that they collapse down to the ••• menu once the viewport is narrowed so the gradient fade support added by DataListOverFlowFade was not giving us anything, and was in turn:

  • coupling the spacing of these actions to the spacing in the filters bar
  • clipping the focus shadow of the actions

So two birds with one stone, as they say

@@ -1,13 +1,14 @@
.menu {
display: flex;
position: absolute;
top: calc(var(--space-small) * -1);
top: -26px;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes this number is relatively magic

Copy link
Contributor

Choose a reason for hiding this comment

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

🪄 I trust in your magic, Chris.

@@ -25,7 +24,7 @@ export function DataListActions<T extends DataListObject>({
childrenArray.splice(0, exposedActions.length);

return (
<DataListOverflowFade>
<span data-testid="ATL-DataListActions">
Copy link
Contributor Author

Choose a reason for hiding this comment

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

DataListOverFlowFade came with a testid that was being referenced in BatchActions test - this preserves the test

Copy link
Contributor

Choose a reason for hiding this comment

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

hmmm, we have a file, packages/components/src/DataList/components/DataListBulkActions/DataListBulkActions.const.ts that holds

export const BULK_ACTIONS_CONTAINER_TEST_ID =
  "ATL-DataListBulkActions-Container";

Which actually isn't being used anywhere. We should use BULK_ACTIONS_CONTAINER_TEST_ID instead, but not in this file.

We should:

  • remove the span in DataListActions.tsx, it just becomes empty fragment
  • DataListBulkActions.tsx would now have the bulk actions test id:
import React from "react";
import styles from "./DataListBulkActions.css";
import { BULK_ACTIONS_CONTAINER_TEST_ID } from "./DataListBulkActions.const";
import { DataListBulkActionsProps } from "../../DataList.types";
import { useDataListContext } from "../../context/DataListContext";
import { DataListActions } from "../DataListActions";
import { useResponsiveSizing } from "../../hooks/useResponsiveSizing";

// This component is meant to capture the props of the DataList.BulkActions
export function DataListBulkActions(
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  _: DataListBulkActionsProps,
) {
  return null;
}

export function InternalDataListBulkActions() {
  const { bulkActionsComponent } = useDataListContext();
  if (!bulkActionsComponent) return null;

  const { children } = bulkActionsComponent.props;

  const { sm } = useResponsiveSizing();

  // Collapse all actions under "More actions" when breakpoint is smaller than sm
  const itemsToExpose = sm ? 3 : 0;

  return (
    <div
      className={styles.bulkActions}
      data-testid={BULK_ACTIONS_CONTAINER_TEST_ID}
    >
      <DataListActions itemsToExpose={itemsToExpose}>
        {children}
      </DataListActions>
    </div>
  );
}
  • then in DataListBulkActions.test.tsx you put that testid in there instead:
import { BULK_ACTIONS_CONTAINER_TEST_ID } from "./DataListBulkActions.const";

describe("DataListBulkActions", () => {
  it("should render the 4 buttons", () => {
    renderComponent();
    const overflowContainer = screen.getByTestId(
      BULK_ACTIONS_CONTAINER_TEST_ID,
    );

    expect(within(overflowContainer).getAllByRole("button")).toHaveLength(4);
  });

This way, we're using an unused testid, which is more correct to what we're testing. Let me know if I'm not communicating this well enough we can hop on a call

right: 0;
z-index: var(--elevation-menu);
box-shadow: var(--shadow-base);
padding: var(--space-smaller);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since padding is now 0, no need to declare it

border: var(--border-base) solid var(--color-border);
border-radius: var(--radius-base);
background-color: var(--color-surface);
gap: var(--space-smaller);
gap: var(--space-smallest);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeps a pinch of space between the actions so the focus states don't encroach too heavily on sibling buttons

@@ -1,6 +1,5 @@
.fadeContainer {
--overflow-fade--offset: var(--space-smaller);
--overflow-fade--negative-offset: calc(var(--overflow-fade--offset) * -1);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These values are now the same and can be applied accordingly with one variable

I considered removing the margin and padding declarations, but since the positions of the gradients are coupled to those values, felt worth keeping them in sync

@chris-at-jobber chris-at-jobber marked this pull request as ready for review September 18, 2024 20:32
@chris-at-jobber chris-at-jobber requested a review from a team as a code owner September 18, 2024 20:32
Copy link
Contributor

@taylorvnoj taylorvnoj left a comment

Choose a reason for hiding this comment

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

Looking really really good - we're no longer blocking any info 👌

Just that one change with the testid and this will be good to go!

Screenshot 2024-09-18 at 5 53 44 PM

@taylorvnoj
Copy link
Contributor

@chris-at-jobber for the failed lint_javascript, to see the errors, run:

npm run lint:js 

These two have to be fixed:

Screenshot 2024-09-18 at 7 11 06 PM

Copy link
Contributor

@taylorvnoj taylorvnoj left a comment

Choose a reason for hiding this comment

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

🎉 thanks for fixing the test! SHIP IT :shipit:

@chris-at-jobber chris-at-jobber merged commit 68d7d77 into master Sep 20, 2024
11 checks passed
@chris-at-jobber chris-at-jobber deleted the poc-moving-datalist-actions-around branch September 20, 2024 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants