Skip to content

Commit

Permalink
feat(ListItemExandIcon): added new list component for expanded icon view
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaevAlexandr committed Aug 22, 2024
1 parent 1c95f75 commit 61b8335
Show file tree
Hide file tree
Showing 19 changed files with 329 additions and 53 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,11 +97,9 @@ export const WithGroupSelectionAndCustomIconStory = ({
: expandButtonLabel,
}}
>
<Icon
data={
itemProps.content.expanded ? ChevronDown : ChevronUp
}
size={16}
<ListItemExpandIcon
expanded={itemProps.content.expanded}
position="end"
/>
</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,7 @@ export const WithItemLinksAndActionsStory = (props: WithItemLinksAndActionsStory
: expandButtonLabel,
}}
>
<Icon
data={
itemProps.content.expanded ? ChevronDown : ChevronUp
}
size={16}
/>
<ListItemExpandIcon expanded={itemProps.content.expanded} />
</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,9 +92,9 @@ export const WithGroupSelectionControlledStateAndCustomIconExample = ({
}));
}}
>
<Icon
data={props.content.expanded ? ChevronDown : ChevronUp}
size={16}
<ListItemExpandIcon
expanded={props.content.expanded}
position="end"
/>
</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,7 @@ export const WithItemLinksAndActionsExample = (storyProps: WithItemLinksAndActio
}));
}}
>
<Icon
data={
props.content.expanded ? ChevronDown : ChevronUp
}
size={16}
/>
<ListItemExpandIcon expanded={props.content.expanded} />
</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,26 @@
@use '../../../variables';

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

#{$block} {
flex-shrink: 0;

transition: transform 0.1s ease;

&_disableTransition {
transition: none;
}

&_position_start {
transform: rotate(-90deg);
}

&_position_end {
transform: rotate(180deg);
transition: transform 0.2s ease;
}

&_expanded {
transform: rotate(0deg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';

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

import {Icon} from '../../../Icon';
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 Partial<ListItemExpandIconRenderProps> {}

export const ListItemExpandIcon = ({
expanded,
disableTransition,
position = 'start',
disabled,
}: ListItemExpandIconProps) => {
return (
<Icon
className={b(
{expanded, disableTransition, position},
colorText({color: disabled ? 'hint' : undefined}),
)}
data={ChevronDown}
size={16}
/>
);
};

// For correct rendering inside `Button` component
ListItemExpandIcon.displayName = 'Icon';
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';

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

import {Button} from '../../../../Button';
import {RadioButton} from '../../../../RadioButton';
import {Text} from '../../../../Text';
import {Flex} from '../../../../layout';
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>;

export const Default = {
render: (args) => (
<Flex gap="5">
<Flex direction="column" gap="2">
<Text>Position: start</Text>
<Flex gap="2">
<ListItemExpandIcon {...args} expanded={true} />
<ListItemExpandIcon {...args} expanded={false} />
</Flex>
</Flex>
<Flex direction="column" gap="2">
<Text>Position: start</Text>
<Flex gap="2">
<ListItemExpandIcon {...args} expanded={true} position="end" />
<ListItemExpandIcon {...args} expanded={false} position="end" />
</Flex>
</Flex>
</Flex>
),
} satisfies Story;

const InsideButtonExample = (props: ListItemExpandIconProps) => {
const [expanded, setExpanded] = React.useState(false);
const [position, setPosition] = React.useState<'start' | 'end'>('start');

return (
<Flex direction="column" gap="3">
<Flex gap="3" alignItems="center">
<Text>Icon position: </Text>
<RadioButton
size="m"
value={position}
onUpdate={setPosition}
options={[
{value: 'start', content: 'Start'},
{value: 'end', content: 'End'},
]}
/>
</Flex>

<Text>Click on button to change state:</Text>

<Button onClick={() => setExpanded((x) => !x)}>
<ListItemExpandIcon {...props} expanded={expanded} position={position} />
</Button>
</Flex>
);
};

export const InsideButton = {
render: InsideButtonExample,
} satisfies Story;
Loading

0 comments on commit 61b8335

Please sign in to comment.