Skip to content

Commit

Permalink
feat(ListItemExandIcon): added new list component for expanded icon v…
Browse files Browse the repository at this point in the history
…iew (#1762)
  • Loading branch information
IsaevAlexandr authored Oct 23, 2024
1 parent 2d9c88e commit b6516f4
Show file tree
Hide file tree
Showing 19 changed files with 288 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import {Button} from '../../../Button';
import {Text} from '../../../Text';
import {TextInput} from '../../../controls';
import {Flex, spacing} from '../../../layout';
import {useList, useListFilter} from '../../../useList';
import {ListContainer, useList, useListFilter} from '../../../useList';
import {createRandomizedData} from '../../../useList/__stories__/utils/makeData';
import {TreeList} from '../../TreeList';
import type {TreeListContainerProps, TreeListProps} from '../../types';
import {RenderVirtualizedContainer} from '../components/RenderVirtualizedContainer';

interface Entity {
title: string;
Expand Down Expand Up @@ -37,7 +36,7 @@ export const WithFiltrationAndControlsStory = ({
);
}

return <RenderVirtualizedContainer {...props} />;
return <ListContainer {...props} />;
};

return {items: baseItems, renderContainer: containerRenderer};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';

import {ChevronDown, ChevronUp, Database, PlugConnection} from '@gravity-ui/icons';
import {Database, PlugConnection} from '@gravity-ui/icons';

import {Button} from '../../../Button';
import {Icon} from '../../../Icon';
import {Flex, spacing} from '../../../layout';
import {ListItemView, useList} from '../../../useList';
import {Flex} from '../../../layout';
import {ListItemExpandIcon, ListItemView, useList} from '../../../useList';
import type {ListItemId, ListItemViewContentType} from '../../../useList';
import {createRandomizedData} from '../../../useList/__stories__/utils/makeData';
import {TreeList} from '../../TreeList';
Expand Down Expand Up @@ -84,8 +84,6 @@ export const WithGroupSelectionAndCustomIconStory = ({

endSlot: childrenIds ? (
<Button
size="m"
className={spacing({mr: 1})}
onClick={(e) => {
e.stopPropagation();
list.state.setExpanded?.((prevExpandedState) => ({
Expand All @@ -99,12 +97,12 @@ export const WithGroupSelectionAndCustomIconStory = ({
: expandButtonLabel,
}}
>
<Icon
data={
itemProps.content.expanded ? ChevronDown : ChevronUp
}
size={16}
/>
<Button.Icon>
<ListItemExpandIcon
expanded={itemProps.content.expanded}
behavior="action"
/>
</Button.Icon>
</Button>
) : undefined,
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';

import {ChevronDown, ChevronUp, FolderOpen} from '@gravity-ui/icons';
import {FolderOpen} from '@gravity-ui/icons';

import {Button} from '../../../Button';
import {DropdownMenu} from '../../../DropdownMenu';
import {Icon} from '../../../Icon';
import {Flex} from '../../../layout';
import {ListItemView, useList} from '../../../useList';
import {ListItemExpandIcon, ListItemView, useList} from '../../../useList';
import type {ListItemId} from '../../../useList';
import {createRandomizedData} from '../../../useList/__stories__/utils/makeData';
import {TreeList} from '../../TreeList';
Expand Down Expand Up @@ -96,12 +96,12 @@ export const WithItemLinksAndActionsStory = (props: WithItemLinksAndActionsStory
: expandButtonLabel,
}}
>
<Icon
data={
itemProps.content.expanded ? ChevronDown : ChevronUp
}
size={16}
/>
<Button.Icon>
<ListItemExpandIcon
expanded={itemProps.content.expanded}
behavior="action"
/>
</Button.Icon>
</Button>
) : (
<Flex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import React from 'react';

import {Button} from '../../../Button';
import {Text} from '../../../Text';
import {RenderVirtualizedContainer} from '../../../TreeList/__stories__/components/RenderVirtualizedContainer';
import {TextInput} from '../../../controls';
import {Flex, spacing} from '../../../layout';
import {ListItemView, useListFilter} from '../../../useList';
import {ListContainer, ListItemView, useListFilter} from '../../../useList';
import {createRandomizedData} from '../../../useList/__stories__/utils/makeData';
import {TreeSelect} from '../../TreeSelect';
import type {TreeSelectProps, TreeSelectRenderContainer} from '../../types';
Expand Down Expand Up @@ -37,7 +36,7 @@ export const WithFiltrationAndControlsExample = ({
);
}

return <RenderVirtualizedContainer {...props} />;
return <ListContainer {...props} />;
};

return {items: baseItems, renderContainer: containerRenderer};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';

import {ChevronDown, ChevronUp, Database, PlugConnection} from '@gravity-ui/icons';
import {Database, PlugConnection} from '@gravity-ui/icons';

import {Button} from '../../../Button';
import {Icon} from '../../../Icon';
import {Flex, spacing} from '../../../layout';
import {ListItemView} from '../../../useList';
import {ListItemExpandIcon, ListItemView} from '../../../useList';
import type {ListItemId, ListItemViewContentType, UseListResult} from '../../../useList';
import {createRandomizedData} from '../../../useList/__stories__/utils/makeData';
import {TreeSelect} from '../../TreeSelect';
Expand Down Expand Up @@ -92,10 +92,12 @@ export const WithGroupSelectionControlledStateAndCustomIconExample = ({
}));
}}
>
<Icon
data={props.content.expanded ? ChevronDown : ChevronUp}
size={16}
/>
<Button.Icon>
<ListItemExpandIcon
expanded={props.content.expanded}
behavior="action"
/>
</Button.Icon>
</Button>
) : undefined,
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';

import {ChevronDown, ChevronUp, FolderOpen} from '@gravity-ui/icons';
import {FolderOpen} from '@gravity-ui/icons';

import {Button} from '../../../Button';
import {DropdownMenu} from '../../../DropdownMenu';
import {Icon} from '../../../Icon';
import {Flex} from '../../../layout';
import {ListItemView} from '../../../useList';
import {ListItemExpandIcon, ListItemView} from '../../../useList';
import type {ListItemId, UseListResult} from '../../../useList';
import {createRandomizedData} from '../../../useList/__stories__/utils/makeData';
import {TreeSelect} from '../../TreeSelect';
Expand Down Expand Up @@ -97,12 +97,12 @@ export const WithItemLinksAndActionsExample = (storyProps: WithItemLinksAndActio
}));
}}
>
<Icon
data={
props.content.expanded ? ChevronDown : ChevronUp
}
size={16}
/>
<Button.Icon>
<ListItemExpandIcon
expanded={props.content.expanded}
behavior="state"
/>
</Button.Icon>
</Button>
) : (
<Flex
Expand Down
31 changes: 30 additions & 1 deletion src/components/useList/__stories__/Docs.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import {Meta, Markdown} from '@storybook/addon-docs';
import {
Meta,
Markdown,
Canvas,
AnchorMdx,
CodeOrSourceMdx,
HeadersMdx,
} from '@storybook/addon-docs';

import UseListHook from './docs/use-list.md?raw';
import UseListKeydownHook from './docs/use-list-keydown.md?raw';
Expand All @@ -13,6 +20,9 @@ import getItemRenderState from './docs/get-item-render-state.md?raw';
import getListParsedState from './docs/get-list-parsed-state.md?raw';
import getListItemQa from './docs/get-list-item-qa.md?raw';

import ListItemExpandIcon from '../components/ListItemExpandIcon/__stories__/list-item-expand-icon.md?raw';
import * as ListItemExpandIconStories from '../components/ListItemExpandIcon/__stories__/ListItemExpandIcon.stories';

<Meta title="Lab/useList" />

# UseList hooks and components
Expand All @@ -32,6 +42,7 @@ The basic idea is that hooks take all the complex logic on themselves, and all y
### Components (View only):

- [ListItemView](#listitemview);
- [ListItemExpandIcon](#listitemexpandicon);
- [ListContainerView](#listcontainerview);
- [ListRecursiveRenderer](#listrecursiverenderer);

Expand Down Expand Up @@ -144,6 +155,24 @@ function List() {

<Markdown>{ListRecursiveRenderer}</Markdown>

<Markdown
options={{
overrides: {
code: CodeOrSourceMdx,
a: AnchorMdx,
...HeadersMdx,
ListItemExpandIconDefault: () => (
<Canvas of={ListItemExpandIconStories.Default} sourceState="none" />
),
ListItemExpandIconInsideButton: () => (
<Canvas of={ListItemExpandIconStories.InsideButton} sourceState="none" />
),
},
}}
>
{ListItemExpandIcon}
</Markdown>

## Utilities

<Markdown>{GetListItemClickHandler}</Markdown>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@use '../../../variables';

$block: '.#{variables.$ns}list-item-expand-icon';

#{$block} {
flex-shrink: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';

import type {ArrowToggleProps} from '../../../ArrowToggle';
import {ArrowToggle} from '../../../ArrowToggle';
import {colorText} from '../../../Text';
import {block} from '../../../utils/cn';
import type {ListItemExpandIconRenderProps} from '../../types';

import './ListItemExpandIcon.scss';

const b = block('list-item-expand-icon');

export interface ListItemExpandIconProps extends ListItemExpandIconRenderProps {}

export const ListItemExpandIcon = ({
expanded,
behavior = 'action',
disabled,
}: ListItemExpandIconProps) => {
return (
<ArrowToggle
direction={getIconDirection({behavior, expanded})}
className={b(null, colorText({color: disabled ? 'hint' : undefined}))}
size={16}
/>
);
};

function getIconDirection({
behavior,
expanded,
}: Pick<ListItemExpandIconRenderProps, 'expanded' | 'behavior'>): ArrowToggleProps['direction'] {
if (expanded && behavior === 'action') {
return 'top';
} else if (expanded && behavior === 'state') {
return 'bottom';
} else if (expanded && behavior === 'state-inverse') {
return 'bottom';
} else if (behavior === 'action') {
return 'bottom';
} else if (behavior === 'state') {
return 'right';
} else if (behavior === 'state-inverse') {
return 'left';
}

return 'bottom';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';

import type {Meta, StoryObj} from '@storybook/react';

import {Button} from '../../../../Button';
import type {ListItemExpandIconProps} from '../ListItemExpandIcon';
import {ListItemExpandIcon} from '../ListItemExpandIcon';

const meta: Meta<typeof ListItemExpandIcon> = {
title: 'Lab/useList/ListItemExpandIcon',
component: ListItemExpandIcon,
};

export default meta;

type Story = StoryObj<typeof ListItemExpandIcon>;

const DefaultExample = (props: ListItemExpandIconProps) => {
return <ListItemExpandIcon {...props} />;
};

export const Default = {
render: DefaultExample,
} satisfies Story;

const InsideButtonExample = (props: ListItemExpandIconProps) => {
const [expanded, setExpanded] = React.useState(false);

return (
<Button extraProps={{'aria-label': 'toggle-button'}} onClick={() => setExpanded((x) => !x)}>
<Button.Icon>
<ListItemExpandIcon {...props} expanded={expanded} />
</Button.Icon>
</Button>
);
};

export const InsideButton = {
render: InsideButtonExample,
} satisfies Story;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
### ListItemExpandIcon

Base group expand icon view

#### Import

```tsx
import {
type unstable_ListItemExpandIconProps as ListItemExpandIconProps,
unstable_ListItemExpandIcon as ListItemExpandIcon,
} from '@gravity-ui/uikit/unstable';
```

#### Base example:

```jsx
const DefaultExample = (props: ListItemExpandIconProps) => {
return <ListItemExpandIcon {...props} />;
};
```

<ListItemExpandIconDefault />

#### Render icon inside Button component:

```jsx
const InsideButtonExample = (props: ListItemExpandIconProps) => {
const [expanded, setExpanded] = React.useState(false);

return (
<Button onClick={() => setExpanded((x) => !x)}>
<Button.Icon>
<ListItemExpandIcon {...props} expanded={expanded} />
</Button.Icon>
</Button>
);
};
```

<ListItemExpandIconInsideButton />

#### Props

| Name | Description | Type | Default |
| :------- | :---------------------------- | :-------------------------------: | :-----: |
| expanded | icon state | `boolean` | |
| disabled | disabled view type | `boolean` | |
| behavior | The behavior of the component | `state`, `state-inverse`,`action` | |
2 changes: 2 additions & 0 deletions src/components/useList/components/ListItemExpandIcon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {ListItemExpandIcon} from './ListItemExpandIcon';
export type {ListItemExpandIconProps} from './ListItemExpandIcon';
Loading

0 comments on commit b6516f4

Please sign in to comment.