-
Notifications
You must be signed in to change notification settings - Fork 30
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
Conversation
Could not publish Pre-release for 6945243. View Logs Previous build information:
|
Deploying atlantis with Cloudflare Pages
|
@@ -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 }, |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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> | |||
<> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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"> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
…om/GetJobber/atlantis into poc-moving-datalist-actions-around
@@ -1,6 +1,5 @@ | |||
.fadeContainer { | |||
--overflow-fade--offset: var(--space-smaller); | |||
--overflow-fade--negative-offset: calc(var(--overflow-fade--offset) * -1); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…om/GetJobber/atlantis into poc-moving-datalist-actions-around
@chris-at-jobber for the failed
These two have to be fixed: |
There was a problem hiding this 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
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
Testing
Hover over a row
Changes can be
tested via Pre-release
In Atlantis we use Github's built in pull request reviews.