Skip to content

Commit

Permalink
LG-4795: fix cell clipping hover and focus styles (#2681)
Browse files Browse the repository at this point in the history
* add overrideTruncation

* use clip

* basic example

* remove comments

* revert changes and adds css

* update comment

* remove unused packages

* fix comment
  • Loading branch information
shaneeza authored Feb 5, 2025
1 parent 0ba51a4 commit 5b30db9
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/olive-hats-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@leafygreen-ui/table': patch
---

Adds `css` to ensure interactive styles (e.g., hover and focus) are not clipped within cells.
3 changes: 2 additions & 1 deletion packages/table/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"@leafygreen-ui/code": "workspace:^",
"@leafygreen-ui/button": "workspace:^",
"@leafygreen-ui/badge": "workspace:^",
"@leafygreen-ui/pagination": "workspace:^"
"@leafygreen-ui/pagination": "workspace:^",
"@leafygreen-ui/tooltip": "workspace:^"
},
"peerDependencies": {
"@leafygreen-ui/leafygreen-provider": "workspace:^"
Expand Down
5 changes: 3 additions & 2 deletions packages/table/src/Cell/Cell.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ export const getCellContainerStyles = (align: Align = 'left') => css`
display: flex;
align-items: center;
min-height: ${standardCellHeight}px;
overflow: hidden;
justify-content: ${align};
text-align: ${align};
Expand All @@ -77,7 +76,6 @@ export const getBaseCellStyles = (
verticalAlignment: VerticalAlignment = VerticalAlignment.Top,
) => css`
padding: 0 ${spacing[200]}px;
overflow: hidden;
vertical-align: ${verticalAlignment};
&:focus-visible {
Expand All @@ -103,5 +101,8 @@ export const getCellEllipsisStyles = (shouldTruncate: boolean) =>
white-space: nowrap;
text-overflow: ellipsis;
contain: inline-size; // 🤯
// This is a workaround to ensure interactive styles (e.g., hover and focus) are not clipped within cells because of overflow: hidden
margin: -${spacing[100]}px;
padding: ${spacing[100]}px;
`]: shouldTruncate,
});
1 change: 1 addition & 0 deletions packages/table/src/Table.Interactions.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ const Template: StoryFn<StoryTableProps> = args => {
);
};

// TODO: fix this test https://jira.mongodb.org/browse/LG-4867
export const StickyHeader = {
render: (args: StoryTableProps) => <Template {...args} />,
play: async ({ canvasElement }) => {
Expand Down
144 changes: 143 additions & 1 deletion packages/table/src/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { css, cx } from '@leafygreen-ui/emotion';
import Icon from '@leafygreen-ui/icon';
import IconButton from '@leafygreen-ui/icon-button';
import Pagination, { PaginationProps } from '@leafygreen-ui/pagination';
import Tooltip from '@leafygreen-ui/tooltip';

import { VerticalAlignment } from './Table/Table.types';
import {
Expand Down Expand Up @@ -95,7 +96,23 @@ const Template: StoryFn<StoryTableProps> = args => {
{data.map((row: AnyDict) => (
<Row key={row.id}>
{Object.keys(row).map((cellKey: string, index: number) => {
return <Cell key={`${cellKey}-${index}`}>{row[cellKey]}</Cell>;
return (
<Cell key={`${cellKey}-${index}`}>
{index === 6 ? (
<Tooltip
trigger={
<Button type="button" size="small">
{row[cellKey]}
</Button>
}
>
{"I'm leafy, you're leafy"}
</Tooltip>
) : (
row[cellKey]
)}
</Cell>
);
})}
</Row>
))}
Expand Down Expand Up @@ -367,6 +384,131 @@ HundredsOfRows.parameters = {
},
};

export const WithButtons: StoryFn<StoryTableProps> = args => {
const tableContainerRef = React.useRef<HTMLDivElement>(null);
const [data] = useState(() => makeKitchenSinkData(300));

const columns = React.useMemo<Array<LGColumnDef<Person>>>(
() => [
{
accessorKey: 'dateCreated',
header: 'Date Created',
enableSorting: true,
cell: info =>
(info.getValue() as Date).toLocaleDateString('en-us', {
year: 'numeric',
month: 'short',
day: 'numeric',
}),
},
{
accessorKey: 'frequency',
header: 'Frequency',
},
{
accessorKey: 'clusterType',
header: 'Cluster Type',
},
{
accessorKey: 'encryptorEnabled',
header: 'Encryptor',

cell: info => (
<Badge variant={info.getValue() ? 'green' : 'red'}>
{info.getValue() ? 'Enabled' : 'Not enabled'}
</Badge>
),
},
{
accessorKey: 'mdbVersion',
header: 'MongoDB Version',
enableSorting: true,
size: 90,
},
{
id: 'actions',
header: '',
size: 120,
cell: _ => {
return (
<Tooltip trigger={<Button size="small">Button</Button>}>
{"I'm leafy, you're leafy"}
</Tooltip>
);
},
},
],
[],
);

const table = useLeafyGreenTable<any>({
data,
columns,
});

const { rows } = table.getRowModel();

return (
<Table {...args} table={table} ref={tableContainerRef}>
<TableHead isSticky>
{table.getHeaderGroups().map((headerGroup: HeaderGroup<Person>) => (
<HeaderRow key={headerGroup.id}>
{headerGroup.headers.map((header, index) => {
return (
<HeaderCell
key={header.id}
header={header}
className={cx({
[css`
// since the table is not fixed, the width is not respected. This prevents the width from getting any smaller.
min-width: 120px;
`]: index === 5,
})}
>
{flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</HeaderCell>
);
})}
</HeaderRow>
))}
</TableHead>
<TableBody>
{rows.map((row: LeafyGreenTableRow<Person>) => {
const isExpandedContent = row.isExpandedContent ?? false;

return (
<Fragment key={row.id}>
{!isExpandedContent && (
<Row row={row}>
{row.getVisibleCells().map(cell => {
return (
<Cell key={cell.id} id={cell.id} cell={cell}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</Cell>
);
})}
</Row>
)}
{isExpandedContent && <ExpandedContent row={row} />}
</Fragment>
);
})}
</TableBody>
</Table>
);
};
WithButtons.parameters = {
chromatic: {
disableSnapshot: true,
},
};

export const NoTruncation = LiveExample.bind({});
NoTruncation.args = {
shouldTruncate: false,
Expand Down
18 changes: 6 additions & 12 deletions packages/table/src/Table/TableWithVS.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
import { StoryFn } from '@storybook/react';

import Badge from '@leafygreen-ui/badge';
import Button from '@leafygreen-ui/button';
import { css } from '@leafygreen-ui/emotion';
import Icon from '@leafygreen-ui/icon';
import IconButton from '@leafygreen-ui/icon-button';
import Tooltip from '@leafygreen-ui/tooltip';

import {
KitchenSink,
Expand Down Expand Up @@ -727,20 +727,14 @@ export const WithLeafyGreenComponents: StoryFn<StoryTableProps> = args => {
{
id: 'actions',
header: '',
size: 120,
size: 150,

cell: _ => {
return (
<div>
<IconButton aria-label="Download">
<Icon glyph="Download" />
</IconButton>
<IconButton aria-label="Export">
<Icon glyph="Export" />
</IconButton>
<IconButton aria-label="More Options">
<Icon glyph="Ellipsis" />
</IconButton>
<Tooltip trigger={<Button size="small">Button</Button>}>
{"I'm leafy, you're leafy"}
</Tooltip>
</div>
);
},
Expand Down
17 changes: 12 additions & 5 deletions packages/table/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
{
"extends": "@lg-tools/build/config/package.tsconfig.json",
"compilerOptions": {
"compilerOptions": {
"declarationDir": "dist",
"outDir": "dist",
"rootDir": "src",
"baseUrl": ".",
"paths": {
"@leafygreen-ui/icon/dist/*": ["../icon/src/generated/*"],
"@leafygreen-ui/*": ["../*/src"]
"@leafygreen-ui/icon/dist/*": [
"../icon/src/generated/*"
],
"@leafygreen-ui/*": [
"../*/src"
]
}
},
"include": [
"src/**/*"
],
"exclude": ["**/*.spec.*", "**/*.stories.*"],
"exclude": [
"**/*.spec.*",
"**/*.stories.*"
],
"references": [
{
"path": "../checkbox"
Expand Down Expand Up @@ -52,4 +59,4 @@
"path": "../leafygreen-provider"
}
]
}
}
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5b30db9

Please sign in to comment.