Skip to content

Commit

Permalink
feat: add stories
Browse files Browse the repository at this point in the history
  • Loading branch information
Niznikr committed Nov 8, 2024
1 parent 13e93d5 commit f336012
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 12 deletions.
20 changes: 19 additions & 1 deletion packages/components/src/GridList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -48,7 +50,23 @@ const _GridListItem = <T extends object>(props: GridListItemProps<T>, 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 */
<IconButton slot="drag" icon="grip-horiz" size="small" variant="minimal" />
)}
{selectionMode === 'multiple' && selectionBehavior === 'toggle' && (
<Checkbox slot="selection" />
)}
{children}
</>
),
)}
</AriaGridListItem>
);
};

Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const _Row = <T extends object>(
>
{allowsDragging && (
<Cell>
{/* @ts-ignore RAC adds label */}
{/* @ts-expect-error RAC adds label */}
<IconButton slot="drag" icon="grip-horiz" variant="minimal" size="small" />
</Cell>
)}
Expand Down
30 changes: 28 additions & 2 deletions packages/components/src/styles/GridList.module.css
Original file line number Diff line number Diff line change
@@ -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;
}
}
4 changes: 4 additions & 0 deletions packages/components/src/styles/Table.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
}

.body {
&[data-empty] {
font: var(--lp-text-body-2-semibold);
text-align: center;
}
}

.row {
Expand Down
106 changes: 98 additions & 8 deletions packages/components/stories/GridList.stories.tsx
Original file line number Diff line number Diff line change
@@ -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<typeof GridList> = {
component: GridList,
Expand All @@ -18,15 +31,92 @@ export default meta;

type Story = StoryObj<typeof GridList>;

const Options = () => (
<MenuTrigger>
<IconButton icon="more-vert" size="small" variant="minimal" aria-label="options" />
<Popover>
<Menu>
<MenuItem>Action one</MenuItem>
<MenuItem>
<Text slot="label">Action two</Text>
</MenuItem>
<MenuItem>Action three</MenuItem>
</Menu>
</Popover>
</MenuTrigger>
);

const renderGrid = (args: Story['args']) => (
<GridList {...args}>
<GridListItem>
Item one
<Options />
</GridListItem>
<GridListItem>
Item two
<Options />
</GridListItem>
<GridListItem>
Item three
<Options />
</GridListItem>
</GridList>
);

export const Example: Story = {
render: (args) => renderGrid(args),
args: {
children: (
<>
<GridListItem>Item one</GridListItem>
<GridListItem>Item two</GridListItem>
<GridListItem>Item three</GridListItem>
</>
),
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) => <DropIndicator target={target} />,
});

return (
<GridList dragAndDropHooks={dragAndDropHooks} {...args} items={list.items}>
{(item) => (
<GridListItem>
{item.name}
<Options />
</GridListItem>
)}
</GridList>
);
},
};

export const Empty: Story = {
args: {
children: [],
renderEmptyState: () => 'No results found',
},
};
15 changes: 15 additions & 0 deletions packages/components/stories/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,18 @@ export const DragAndDrop: Story = {
'aria-label': 'table',
},
};

export const Empty: Story = {
args: {
children: (
<>
<TableHeader>
<Column isRowHeader>Name</Column>
<Column>Description</Column>
<Column>ID</Column>
</TableHeader>
<TableBody renderEmptyState={() => 'No results found'}>{[]}</TableBody>
</>
),
},
};

0 comments on commit f336012

Please sign in to comment.