diff --git a/packages/components/src/GridList.tsx b/packages/components/src/GridList.tsx index d75ee2255..339971e9b 100644 --- a/packages/components/src/GridList.tsx +++ b/packages/components/src/GridList.tsx @@ -10,6 +10,8 @@ import { composeRenderProps, } from 'react-aria-components'; +import { Checkbox } from './Checkbox'; +import { IconButton } from './IconButton'; import styles from './styles/GridList.module.css'; const list = cva(styles.list); @@ -48,7 +50,23 @@ const _GridListItem = (props: GridListItemProps, ref: Forwa className={composeRenderProps(props.className, (className, renderProps) => item({ ...renderProps, className }), )} - /> + > + {composeRenderProps( + props.children, + (children, { allowsDragging, selectionMode, selectionBehavior }) => ( + <> + {allowsDragging && ( + /* @ts-expect-error RAC adds label */ + + )} + {selectionMode === 'multiple' && selectionBehavior === 'toggle' && ( + + )} + {children} + + ), + )} + ); }; diff --git a/packages/components/src/Table.tsx b/packages/components/src/Table.tsx index 8996501ba..43964bb81 100644 --- a/packages/components/src/Table.tsx +++ b/packages/components/src/Table.tsx @@ -160,7 +160,7 @@ const _Row = ( > {allowsDragging && ( - {/* @ts-ignore RAC adds label */} + {/* @ts-expect-error RAC adds label */} )} diff --git a/packages/components/src/styles/GridList.module.css b/packages/components/src/styles/GridList.module.css index 131d680c2..c36e0b9b0 100644 --- a/packages/components/src/styles/GridList.module.css +++ b/packages/components/src/styles/GridList.module.css @@ -1,17 +1,43 @@ .list { display: flex; flex-direction: column; + + &[data-empty] { + align-items: center; + justify-content: center; + } } .item { composes: interactive from './base.module.css'; display: flex; + column-gap: var(--lp-spacing-300); align-items: center; - box-shadow: inset 0 -1px 0 0 var(--lp-color-border-ui-secondary); + border-bottom: 1px solid var(--lp-color-border-ui-secondary); outline: none; - padding-block: var(--lp-spacing-300); + padding: var(--lp-spacing-300) var(--lp-spacing-500); + position: relative; + transform: translateZ(0); &[data-hovered] { background-color: var(--lp-color-bg-ui-secondary); } + + &[data-focus-visible] { + outline: 2px solid var(--lp-color-shadow-interactive-focus); + outline-offset: -2px; + z-index: 1; + } + + &[data-dragging] { + opacity: 0.6; + } + + &[data-disabled] { + opacity: 0.6; + } + + & button[data-rac]:not([slot]) { + margin-left: auto; + } } diff --git a/packages/components/src/styles/Table.module.css b/packages/components/src/styles/Table.module.css index 62e8c580b..146a4052a 100644 --- a/packages/components/src/styles/Table.module.css +++ b/packages/components/src/styles/Table.module.css @@ -18,6 +18,10 @@ } .body { + &[data-empty] { + font: var(--lp-text-body-2-semibold); + text-align: center; + } } .row { diff --git a/packages/components/stories/GridList.stories.tsx b/packages/components/stories/GridList.stories.tsx index d39ac9a4e..2f96e45f1 100644 --- a/packages/components/stories/GridList.stories.tsx +++ b/packages/components/stories/GridList.stories.tsx @@ -1,6 +1,19 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { GridList, GridListItem } from '../src'; +import { useDragAndDrop } from 'react-aria-components'; +import { useListData } from 'react-stately'; + +import { + DropIndicator, + GridList, + GridListItem, + IconButton, + Menu, + MenuItem, + MenuTrigger, + Popover, + Text, +} from '../src'; const meta: Meta = { component: GridList, @@ -18,15 +31,92 @@ export default meta; type Story = StoryObj; +const Options = () => ( + + + + + Action one + + Action two + + Action three + + + +); + +const renderGrid = (args: Story['args']) => ( + + + Item one + + + + Item two + + + + Item three + + + +); + export const Example: Story = { + render: (args) => renderGrid(args), args: { - children: ( - <> - Item one - Item two - Item three - - ), selectionMode: 'single', }, }; + +export const Selection: Story = { + render: (args) => renderGrid(args), + args: { + selectionMode: 'multiple', + }, +}; + +export const DragAndDrop: Story = { + render: (args) => { + const list = useListData({ + initialItems: [ + { id: 1, name: 'Item one' }, + { id: 2, name: 'Item two' }, + { id: 3, name: 'Item three' }, + { id: 4, name: 'Item four' }, + { id: 5, name: 'Item five' }, + ], + }); + + const { dragAndDropHooks } = useDragAndDrop({ + getItems: (keys) => [...keys].map((key) => ({ 'text/plain': list.getItem(key).name })), + onReorder(e) { + if (e.target.dropPosition === 'before') { + list.moveBefore(e.target.key, e.keys); + } else if (e.target.dropPosition === 'after') { + list.moveAfter(e.target.key, e.keys); + } + }, + renderDropIndicator: (target) => , + }); + + return ( + + {(item) => ( + + {item.name} + + + )} + + ); + }, +}; + +export const Empty: Story = { + args: { + children: [], + renderEmptyState: () => 'No results found', + }, +}; diff --git a/packages/components/stories/Table.stories.tsx b/packages/components/stories/Table.stories.tsx index 9bb04cd78..2422548aa 100644 --- a/packages/components/stories/Table.stories.tsx +++ b/packages/components/stories/Table.stories.tsx @@ -180,3 +180,18 @@ export const DragAndDrop: Story = { 'aria-label': 'table', }, }; + +export const Empty: Story = { + args: { + children: ( + <> + + Name + Description + ID + + 'No results found'}>{[]} + + ), + }, +};