import { Meta } from '@storybook/react';
import map from 'lodash/map';
import noop from 'lodash/noop';
import startCase from 'lodash/startCase';
import uniqueId from 'lodash/uniqueId';
import Typography from '@mui/material/Typography';
import { ASSETS_URL } from '../../../../consts/common';
import { countryCodesMap } from '../../../../consts';
import { getMockUsersDropdownMenuItems } from '../../../dropdown-menu';
import type { DropdownMenuItem, MenuContentProps } from '../../../dropdown-menu';
import { Select } from '../select';
import type { AutocompleteOptionProps } from '../../autocomplete';
import {
AutoCompleteTemplate,
IconAndSearchTemplate,
MultipleTemplate,
NestedShowDeletedTemplate,
NestedSelectAllTemplate,
PrimaryTemplate
} from './templates';
export default {
component: Select,
title: 'Forms/Dropdown Menu/Drop-Downs',
argTypes: {
size: {
options: ['small', 'medium'],
control: { type: 'radio' }
},
color: {
options: ['primary', 'secondary'],
control: { type: 'select' }
},
label: {
description: 'The label of the input.'
},
placeholder: {
description: 'The short hint displayed in the input before the user enters a value.'
},
showLimitItemsTooltip: {
description: 'Whether to show a tooltip with a list of limited items.',
control: {
type: 'boolean'
}
},
showSelectClearButton: {
description: 'Whether to show a select field clear button.',
control: {
type: 'boolean'
}
},
menuContentProps: {
description: 'Props which will be passed into the menu content component.'
},
handleSelectClickCB: {
description: 'A callback function to handle a select field click.'
}
}
} as Meta;
export const Primary = PrimaryTemplate.bind({});
Primary.args = {
menuContentProps: {
listItems: [
{ name: 'Ini', selected: false },
{ name: 'Mini', selected: false },
{ name: 'Miny', selected: false },
{ name: 'Mo', selected: false }
],
handleClick: () => noop
},
autoFocus: true,
error: false,
label: '',
placeholder: 'Placeholder',
disabled: false
};
export const IconAndSearch = IconAndSearchTemplate.bind({});
IconAndSearch.args = {
...Primary.args,
menuContentProps: {
...(Primary.args.menuContentProps as MenuContentProps),
showSelectedIcon: true,
search: true,
noOptionsText: 'No options'
}
};
export const MenuWidth = IconAndSearchTemplate.bind({});
MenuWidth.args = {
...Primary.args,
menuContentProps: {
listItems: [
{ name: 'Lorem ipsum' },
{ name: 'Dolor sit amet' },
{ name: 'Consectetur adipiscing elit' },
{ name: 'Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua' },
{ name: 'Ut enim ad minim veniam' },
{ name: 'Quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat' },
{ name: 'Duis aute irure dolor' },
{ name: 'Reprehenderit in voluptate' },
{ name: 'Velit esse cillum dolore eu fugiat nulla pariatur' }
],
noOptionsText: 'No options',
search: true
},
menuMaxWidth: 320,
menuWidth: 0
};
export const Multiple = MultipleTemplate.bind({});
Multiple.args = {
multiple: true,
showLimitItemsTooltip: false,
menuContentProps: {
search: true,
listItems: [
{ name: 'Ini', selected: false },
{ name: 'Mini', selected: false },
{ name: 'Miny', selected: false },
{ name: 'Mo', selected: false },
{ name: 'Test1', selected: false },
{ name: 'Test2', selected: false },
{ name: 'Test3', selected: false },
{ name: 'Test4', selected: false },
{ name: 'Test5', selected: false }
],
noOptionsText: 'No options',
handleClick: () => noop
},
placeholder: 'Placeholder'
};
export const Countries = MultipleTemplate.bind({});
Countries.args = {
...Multiple.args,
showLimitItemsTooltip: true,
showSelectClearButton: true,
menuContentProps: {
...Multiple.args.menuContentProps,
listItems: map(countryCodesMap, item => {
const itemName = startCase(item.code.toString());
const countryData = countryCodesMap[item.code];
const countryFlag = countryData?.flag || 'worldwide';
const countryFlagSrc = `${ASSETS_URL}/flags/${countryFlag}.svg`;
return {
name: itemName,
textNode: countryData.name,
selected: false,
checkboxProps: {
icon:
}
};
}),
variableSizeList: true,
searchBy: ['textNode', 'name'],
noOptionsText: 'No options',
handleClick: () => noop
},
style: { width: 280 }
};
export const WithTitleInside = NestedSelectAllTemplate.bind({});
WithTitleInside.args = {
...Multiple.args,
showLimitItemsTooltip: true,
showSelectClearButton: true,
menuContentProps: {
...Multiple.args.menuContentProps,
listItems: [
{
id: '__first',
name: 'Very First Title',
textNode: Very First Title,
options: [
{
id: uniqueId(),
name: 'Check body text 1'
},
{
id: uniqueId(),
name: 'Check body text 2'
},
{
id: uniqueId(),
name: 'Check body text 3'
}
]
},
{
id: '__second',
name: 'Second Title',
textNode: Second Title,
options: [
{
id: uniqueId(),
name: 'Check body text 4'
},
{
id: uniqueId(),
name: 'Check body text 5'
}
]
} as DropdownMenuItem
],
InsertBeforeList: () => null, // overrides template's checkbox
search: false,
handleClick: () => noop
},
style: { width: 280 }
};
export const WithTitleCounter = NestedSelectAllTemplate.bind({});
WithTitleCounter.args = {
...Multiple.args,
showLimitItemsTooltip: true,
showSelectClearButton: true,
menuContentProps: {
...Multiple.args.menuContentProps,
listItems: [
{
id: '__compare',
name: 'Compare',
options: [
{
id: uniqueId(),
name: 'Check body text 1'
},
{
id: uniqueId(),
name: 'Check body text 2'
},
{
id: uniqueId(),
name: 'Check body text 3'
},
{
id: uniqueId(),
name: 'Check body text 4'
}
]
}
],
search: false,
handleClick: () => noop
},
style: { width: 280 }
};
// Create groups of users, 50% of which are disabled
const mockUsersGroup0 = getMockUsersDropdownMenuItems(21, 0.5);
const mockUsersGroup1 = getMockUsersDropdownMenuItems(7, 0.5);
export const Users = NestedShowDeletedTemplate.bind({});
Users.args = {
...Multiple.args,
showLimitItemsTooltip: true,
showSelectClearButton: true,
menuContentProps: {
...Multiple.args.menuContentProps,
listItems: [
{
id: '__group0',
name: 'All Users',
textNode: All Users,
options: mockUsersGroup0
},
{
id: '__group1',
name: 'Managers',
textNode: Managers,
options: mockUsersGroup1
} as DropdownMenuItem
],
search: false,
handleClick: () => noop
},
style: { width: 280 }
};
export const DragAndDrop = MultipleTemplate.bind({});
DragAndDrop.args = {
...Multiple.args,
showLimitItemsTooltip: false,
menuContentProps: {
...(Multiple.args.menuContentProps as MenuContentProps),
deletable: true,
sortable: true,
showSort: true,
noOptionsText: 'No options',
handleDelete: name => () => alert(`Will delete ${name}`),
onSortEnd: noop
}
};
const mockItems: AutocompleteOptionProps[] = [];
for (let i = 1; i <= 20; i++) {
const randomNum = Math.random() * 10;
const randomStr = randomNum.toString(36).substring(2);
const randomText = randomNum < 5 ? ' - ' + randomStr.substring(Math.floor(randomNum)) : '';
mockItems.push({
name: `Item${i}${randomText}`,
selected: false
});
}
const autocompleteItems = mockItems;
export const AutoComplete = AutoCompleteTemplate.bind({});
AutoComplete.args = {
size: 'medium',
placeholder: 'Autocomplete',
multiple: false,
defaultLimitTags: 2,
showLimitTagsTooltip: false,
freeSolo: false,
options: autocompleteItems,
handleDelete: () => alert('Will delete a single chip'),
handleClear: () => alert('Will clear all chips')
};