Skip to content

Commit

Permalink
feat: added Multiselect component
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Aug 18, 2020
1 parent 3d1e48a commit 7d75327
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 0 deletions.
37 changes: 37 additions & 0 deletions ui/components/src/Multiselect/Multiselect.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { Button } from 'theme-ui';
import { Multiselect, MultiselectItem } from './Multiselect';

export default {
title: 'Components/Multiselect',
component: Multiselect,
};

export const overview = () => {
const [state, setState] = React.useState<MultiselectItem[]>([
{
label: 'option-1',
selected: true,
},
{
label: 'option-2',
selected: false,
},
{
label: 'option-3',
selected: false,
},
]);
return (
<Multiselect
items={state}
onChange={item => {
setState(
state.map(i => (i === item ? { ...i, selected: !i.selected } : i)),
);
}}
>
<Button>open</Button>
</Multiselect>
);
};
53 changes: 53 additions & 0 deletions ui/components/src/Multiselect/Multiselect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/** @jsx jsx */
import { FC } from 'react';
import { jsx, Box, Label, Checkbox } from 'theme-ui';
import { Popover, PopoverProps } from '../Popover';

export interface MultiselectItem {
label: string;
selected: boolean;
}
export interface MultiselectOwnProps {
/**
* array of items to select from
*/
items: MultiselectItem[];
/**
* function called when the selected state of an item changes
*/
onChange: (item: MultiselectItem) => void;
}

export type MultiselectProps = MultiselectOwnProps &
Omit<PopoverProps, 'tooltip'>;

/**
* A Popover multiselect displaying checkboxes for select/unselect.
*/
export const Multiselect: FC<MultiselectProps> = ({
items,
onChange,
...props
}) => {
return (
<Popover
trigger={['click']}
{...props}
tooltip={() => (
<Box variant="multiselect.container">
{items.map(item => (
<Box key={`multi_select_${item.label}`} variant="multiselect.item">
<Label>
<Checkbox
onChange={() => onChange(item)}
checked={item.selected}
/>
{item.label}
</Label>
</Box>
))}
</Box>
)}
/>
);
};
1 change: 1 addition & 0 deletions ui/components/src/Multiselect/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Multiselect';
10 changes: 10 additions & 0 deletions ui/components/src/ThemeContext/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type ControlsTheme = {
blockcontainer: Record<string, ThemeUIStyleObject>;
blockpagecontainer: Record<string, ThemeUIStyleObject>;
linkheading: Record<string, ThemeUIStyleObject>;
multiselect: Record<string, ThemeUIStyleObject>;
searchinput: Record<string, ThemeUIStyleObject>;
subtitle: ThemeUIStyleObject;
subheading: ThemeUIStyleObject;
Expand Down Expand Up @@ -472,6 +473,15 @@ export const theme: ControlsTheme = {
},
},
},
multiselect: {
container: {
px: 3,
py: 1,
},
item: {
py: 1,
},
},
searchinput: {
popover: {
minWidth: 300,
Expand Down
1 change: 1 addition & 0 deletions ui/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './Header';
export * from './Keyboard';
export * from './Link';
export * from './Markdown';
export * from './Multiselect';
export * from './Navmenu';
export * from './Pagination';
export * from './PanelContainer';
Expand Down

0 comments on commit 7d75327

Please sign in to comment.