Commit 8f31d248 authored by Igor Stuev's avatar Igor Stuev Committed by GitHub

Merge pull request #2014 from blockscout/tag-group-select

tag group select component
parents 8efd938b f487cf10
...@@ -3,9 +3,11 @@ import { ...@@ -3,9 +3,11 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import getDefaultTransitionProps from '../../utils/getDefaultTransitionProps'; import getDefaultTransitionProps from '../../utils/getDefaultTransitionProps';
import Badge from '../Badge'; import Badge from '../Badge';
const transitionProps = getDefaultTransitionProps(); const transitionProps = getDefaultTransitionProps();
const { defineMultiStyleConfig, definePartsStyle } = const { defineMultiStyleConfig, definePartsStyle } =
...@@ -15,6 +17,23 @@ const variants = { ...@@ -15,6 +17,23 @@ const variants = {
subtle: definePartsStyle((props) => ({ subtle: definePartsStyle((props) => ({
container: Badge.variants?.subtle(props), container: Badge.variants?.subtle(props),
})), })),
select: definePartsStyle((props) => ({
container: {
bg: mode('gray.100', 'gray.800')(props),
color: mode('gray.500', 'whiteAlpha.800')(props),
_hover: {
color: 'blue.400',
opacity: 0.76,
},
[`
&[data-selected=true],
&[data-selected=true][aria-selected=true]
`]: {
bg: mode('blue.500', 'blue.900')(props),
color: 'whiteAlpha.800',
},
},
})),
}; };
const sizes = { const sizes = {
......
import _noop from 'lodash/noop';
import React from 'react';
import { test, expect } from 'playwright/lib';
import TagGroupSelect from './TagGroupSelect';
test.use({ viewport: { width: 480, height: 140 } });
test('base view +@dark-mode', async({ render }) => {
const component = await render(
<TagGroupSelect
items={ [ { id: '1', title: 'Option 1' }, { id: '2', title: 'Option 2' }, { id: 'duck', title: 'Cute little duck' } ] }
value="duck"
onChange={ _noop }
/>,
);
await component.getByText('Option 2').hover();
await expect(component).toHaveScreenshot();
});
import { HStack, Tag } from '@chakra-ui/react';
import React from 'react';
type Props<T extends string> = {
items: Array<{ id: T; title: string }>;
} & (
{
value: T;
onChange: (value: T) => void;
isMulti?: false;
} | {
value: Array<T>;
onChange: (value: Array<T>) => void;
isMulti: true;
}
)
const TagGroupSelect = <T extends string>({ items, value, isMulti, onChange }: Props<T>) => {
const onItemClick = React.useCallback((event: React.SyntheticEvent) => {
const itemValue = (event.currentTarget as HTMLDivElement).getAttribute('data-id') as T;
if (isMulti) {
let newValue;
if (value.includes(itemValue)) {
newValue = value.filter(i => i !== itemValue);
} else {
newValue = [ ...value, itemValue ];
}
onChange(newValue);
} else {
onChange(itemValue);
}
}, [ isMulti, onChange, value ]);
return (
<HStack>
{ items.map(item => {
const isSelected = isMulti ? value.includes(item.id) : value === item.id;
return (
<Tag
variant="select"
key={ item.id }
data-id={ item.id }
data-selected={ isSelected }
fontWeight={ 500 }
cursor="pointer"
onClick={ onItemClick }
>
{ item.title }
</Tag>
);
}) }
</HStack>
);
};
export default TagGroupSelect;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment