Skip to content

Commit

Permalink
feat: extend menu options props
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris authored and tassoevan committed Feb 17, 2022
1 parent 74c0089 commit 813dbd8
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 47 deletions.
24 changes: 24 additions & 0 deletions packages/fuselage/.storybook/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,27 @@ export const menuOptions = {
action: () => console.log('[...] no longer exists'),
},
};

export const customMenuOptions = {
example: {
label: 'Example',
action: () => console.log('[...] no longer exists'),
},
divider1: {
type: 'divider',
},
heading: {
type: 'heading',
label: 'Heading Example',
},
delete: {
type: 'option',
label: (
<Box display='flex' alignItems='center' color='danger'>
<Icon mie='x4' name='trash' size='x16' />
Delete
</Box>
),
action: () => console.log('[...] no longer exists'),
},
};
12 changes: 9 additions & 3 deletions packages/fuselage/src/components/Menu/Menu.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import React from 'react';

import { Box, Menu } from '..';
import { menuOptions } from '../../../.storybook/helpers.js';
import { Box, Menu, MenuProps } from '..';
import { menuOptions, customMenuOptions } from '../../../.storybook/helpers.js';

export default {
title: 'Navigation/Menu',
Expand All @@ -16,8 +16,14 @@ export default {
},
} as ComponentMeta<typeof Menu>;

export const Template: ComponentStory<typeof Menu> = () => (
export const Default: ComponentStory<typeof Menu> = () => (
<Box style={{ position: 'relative', maxWidth: 250 }}>
<Menu options={menuOptions} />
</Box>
);

export const CustomOptions: ComponentStory<typeof Menu> = () => (
<Box style={{ position: 'relative', maxWidth: 250 }}>
<Menu options={customMenuOptions as MenuProps['options']} />
</Box>
);
17 changes: 13 additions & 4 deletions packages/fuselage/src/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import type { OptionType } from '../Options';
export type MenuProps = Omit<ComponentProps<typeof ActionButton>, 'icon'> & {
options: {
[id: string]: {
label: ReactElement | string;
action: () => void;
type?: 'option' | 'heading' | 'divider';
label?: ReactElement | string;
action?: () => void;
};
};
optionWidth?: ComponentProps<typeof Box>['width'];
Expand All @@ -24,11 +25,19 @@ export type MenuProps = Omit<ComponentProps<typeof ActionButton>, 'icon'> & {
};

const menuAction = ([selected]: OptionType, options: MenuProps['options']) => {
options[selected].action();
const actionSelected = options[selected].action;
if (actionSelected) {
actionSelected();
}
};

const mapOptions = (options: MenuProps['options']): OptionType[] =>
Object.entries(options).map(([value, { label }]) => [value, label]);
Object.entries(options).map(([value, { type = 'option', label }]) => [
value,
label,
undefined,
type,
]);

export const Menu = ({
tiny,
Expand Down
17 changes: 2 additions & 15 deletions packages/fuselage/src/components/Options/Options.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { ComponentStory, ComponentMeta } from '@storybook/react';
import React, { createRef } from 'react';

import { Options, OptionType } from '.';
import { Box, Menu, Divider } from '..';
import { Box, Menu } from '..';
import { CheckOption } from './CheckOption';
import Option, { OptionHeader } from './Option';
import Option from './Option';

const options: OptionType[] = [
[1, 'a teste 1'],
Expand Down Expand Up @@ -87,16 +87,3 @@ CustomEmpty.args = {
options: [],
customEmpty: 'Custom empty placeholder',
};

export const CustomRender: ComponentStory<typeof Options> = (args) => (
<Box position='relative' maxWidth={250}>
<Options {...args} ref={createRef()}>
<Option>Option Example</Option>
<Divider />
<OptionHeader>Title</OptionHeader>
<CheckOption icon='magnifier'>CheckOption Example</CheckOption>
<CheckOption>CheckOption Example</CheckOption>
<CheckOption>CheckOption Example With Ellipsis</CheckOption>
</Options>
</Box>
);
52 changes: 29 additions & 23 deletions packages/fuselage/src/components/Options/Options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import React, {
import { Box } from '../Box';
import Scrollable from '../Scrollable';
import Tile from '../Tile';
import Option from './Option';
import Option, { OptionHeader, OptionDivider } from './Option';
import { useCursor } from './useCursor';

export { useCursor };
Expand All @@ -24,7 +24,7 @@ const prevent = (e: SyntheticEvent) => {
e.stopPropagation();
};

export type OptionType = [string | number, ReactNode, boolean?];
export type OptionType = [string | number, ReactNode, boolean?, string?];

type OptionsProps = Omit<ComponentProps<typeof Box>, 'onSelect'> & {
multiple?: boolean;
Expand All @@ -51,7 +51,6 @@ export const Options = forwardRef(
renderItem: OptionComponent = Option,
onSelect,
customEmpty,
children,
...props
}: OptionsProps,
ref: Ref<HTMLElement>
Expand All @@ -78,22 +77,31 @@ export const Options = forwardRef(

const optionsMemoized = useMemo(
() =>
options?.map(([value, label, selected], i) => (
<OptionComponent
role='option'
label={label}
onMouseDown={(e: SyntheticEvent) => {
prevent(e);
onSelect([value, label]);
return false;
}}
key={value}
value={value}
selected={selected || (multiple !== true && null)}
focus={cursor === i || null}
/>
)),
[options, multiple, cursor, onSelect]
options?.map(([value, label, selected, type], i) => {
switch (type) {
case 'heading':
return <OptionHeader key={value}>{label}</OptionHeader>;
case 'divider':
return <OptionDivider key={value} />;
default:
return (
<OptionComponent
role='option'
label={label}
onMouseDown={(e: SyntheticEvent) => {
prevent(e);
onSelect([value, label]);
return false;
}}
key={value}
value={value}
selected={selected || (multiple !== true && null)}
focus={cursor === i || null}
/>
);
}
}),
[options, multiple, cursor, onSelect, OptionComponent]
);

return (
Expand All @@ -116,10 +124,8 @@ export const Options = forwardRef(
: undefined
}
>
{options?.length ? optionsMemoized : children}
{!options?.length && !children && (
<EmptyComponent customEmpty={customEmpty} />
)}
{!options.length && <EmptyComponent customEmpty={customEmpty} />}
{optionsMemoized}
</Tile>
</Scrollable>
</Tile>
Expand Down
4 changes: 2 additions & 2 deletions packages/fuselage/src/components/Options/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ $variants: (
opacity: 0;
}

&.rcx-option__column {
.rcx-option__column {
@extend %column;
display: flex;

Expand All @@ -91,7 +91,7 @@ $variants: (
min-height: lengths.size(20);
}

&.rcx-option__description {
.rcx-option__description {
@include typography.use-font-scale(p2);
@extend %column;
display: inline;
Expand Down

0 comments on commit 813dbd8

Please sign in to comment.