Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions documentation-site/examples/menu/dividers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @flow
import * as React from 'react';
import {StatefulMenu} from 'baseui/menu';

const ITEMS = [
{label: 'Menu option A'},
{label: 'Menu option B'},
{divider: true},
{label: 'Menu option X'},
{label: 'Menu option Y'},
{label: 'Menu option Z'},
{divider: true},
{label: 'Menu option 1'},
{label: 'Menu option 2'},
{label: 'Menu option 3'},
];

export default function Example() {
return (
<StatefulMenu
items={ITEMS}
onItemSelect={console.log}
overrides={{
List: {
style: {
height: '250px',
width: '350px',
},
},
Option: {
props: {
getItemLabel: (item) => item.label,
},
},
}}
/>
);
}
37 changes: 37 additions & 0 deletions documentation-site/examples/menu/dividers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from 'react';
import {StatefulMenu} from 'baseui/menu';

const ITEMS = [
{label: 'Menu option A'},
{label: 'Menu option B'},
{divider: true},
{label: 'Menu option X'},
{label: 'Menu option Y'},
{label: 'Menu option Z'},
{divider: true},
{label: 'Menu option 1'},
{label: 'Menu option 2'},
{label: 'Menu option 3'},
];

export default function Example() {
return (
<StatefulMenu
items={ITEMS}
onItemSelect={console.log}
overrides={{
List: {
style: {
height: '250px',
width: '350px',
},
},
Option: {
props: {
getItemLabel: (item: {label: string}) => item.label,
},
},
}}
/>
);
}
7 changes: 7 additions & 0 deletions documentation-site/pages/components/menu.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ChildRenderAll from 'examples/menu/child-render-all.js';
import Grouped from 'examples/menu/grouped.js';
import VirtualList from 'examples/menu/virtual-list.js';
import Href from 'examples/menu/href.js';
import Dividers from 'examples/menu/dividers.js';

import Overrides from '../../components/overrides';
import { StatefulMenu, OptionProfile } from 'baseui/menu';
Expand Down Expand Up @@ -96,6 +97,10 @@ The provided id will be set as a value for the item container's `id` attribute t
<Href />
</Example>

<Example title="Menu with Dividers" path="menu/dividers.js">
<Dividers />
</Example>

## Overrides

<Overrides
Expand All @@ -108,8 +113,10 @@ The provided id will be set as a value for the item container's `id` attribute t
items={[
{ label: 'Item One' },
{ label: 'Item Two' },
{ divider: true },
{ label: 'Item Three', disabled: true },
{ label: 'Item Four', disabled: true },
{ divider: true },
{ label: 'Item Five' },
{ label: 'Item Six' },
]}
Expand Down
43 changes: 43 additions & 0 deletions src/menu/__tests__/menu-dividers.scenario.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright (c) Uber Technologies, Inc.

This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';

import { Menu } from '..';

const ITEMS = [
{ label: 'Menu option A' },
{ label: 'Menu option B' },
{ divider: true },
{ label: 'Menu option X' },
{ label: 'Menu option Y' },
{ label: 'Menu option Z' },
{ divider: true },
{ label: 'Menu option 1' },
{ label: 'Menu option 2' },
{ label: 'Menu option 3' },
];

export function Scenario() {
return (
<Menu
items={ITEMS}
rootRef={React.createRef()}
overrides={{
List: {
style: {
width: '200px',
},
},
Option: {
props: {
getItemLabel: (item) => item.label,
},
},
}}
/>
);
}
2 changes: 2 additions & 0 deletions src/menu/__tests__/menu.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Scenario as MenuStateful } from './menu-stateful.scenario';
import { Scenario as MenuVirtualized } from './menu-virtualized.scenario';
import { Scenario as MenuDefault } from './menu.scenario';
import { Scenario as MenuProfileMenu } from './menu-profile-menu.scenario';
import { Scenario as MenuDividers } from './menu-dividers.scenario';

export const ChildInPopover = () => <MenuChildInPopover />;
export const ChildRenderAll = () => <MenuChildRenderAll />;
Expand All @@ -26,3 +27,4 @@ export const Stateful = () => <MenuStateful />;
export const Virtualized = () => <MenuVirtualized />;
export const Menu = () => <MenuDefault />;
export const ProfileMenu = () => <MenuProfileMenu />;
export const Dividers = () => <MenuDividers />;
1 change: 1 addition & 0 deletions src/menu/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export {
StyledProfileTitle,
StyledProfileSubtitle,
StyledProfileBody,
StyledMenuDivider,
} from './styled-components.js';
// Flow
export type * from './types.js';
1 change: 1 addition & 0 deletions src/menu/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export {
StyledProfileTitle,
StyledProfileSubtitle,
StyledProfileBody,
StyledMenuDivider,
} from './styled-components';
// Flow
export * from './types';
Expand Down
12 changes: 11 additions & 1 deletion src/menu/menu.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ LICENSE file in the root directory of this source tree.
import * as React from 'react';
import { LocaleContext } from '../locale/index.js';
// Components
import { StyledList, StyledEmptyState, StyledOptgroupHeader } from './styled-components.js';
import {
StyledList,
StyledEmptyState,
StyledOptgroupHeader,
StyledMenuDivider,
} from './styled-components.js';
import OptionList from './option-list.js';
import { getOverrides } from '../helpers/overrides.js';
// Types
Expand Down Expand Up @@ -49,6 +54,7 @@ export default function Menu(props: StatelessMenuPropsT) {
overrides.OptgroupHeader,
StyledOptgroupHeader
);
const [MenuDivider, menuDividerProps] = getOverrides(overrides.MenuDivider, StyledMenuDivider);

const groupedItems = Array.isArray(props.items) ? { __ungrouped: props.items } : props.items;
const optgroups = Object.keys(groupedItems);
Expand All @@ -65,6 +71,10 @@ export default function Menu(props: StatelessMenuPropsT) {
itemIndex = itemIndex + 1;
const { getRequiredItemProps = (item, index) => ({}) } = props;

if (item.divider === true) {
return <MenuDivider {...menuDividerProps} />;
}

const {
disabled,
isFocused,
Expand Down
12 changes: 11 additions & 1 deletion src/menu/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ LICENSE file in the root directory of this source tree.
import * as React from 'react';
import { LocaleContext } from '../locale';
// Components
import { StyledList, StyledEmptyState, StyledOptgroupHeader } from './styled-components';
import {
StyledList,
StyledEmptyState,
StyledOptgroupHeader,
StyledMenuDivider,
} from './styled-components';
import OptionList from './option-list';
import { getOverrides } from '../helpers/overrides';
// Types
Expand Down Expand Up @@ -52,6 +57,7 @@ export default function Menu(props: StatelessMenuProps) {
overrides.OptgroupHeader,
StyledOptgroupHeader
);
const [MenuDivider, menuDividerProps] = getOverrides(overrides.MenuDivider, StyledMenuDivider);

const groupedItems = Array.isArray(props.items) ? { __ungrouped: props.items } : props.items;
const optgroups = Object.keys(groupedItems);
Expand All @@ -70,6 +76,10 @@ export default function Menu(props: StatelessMenuProps) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { getRequiredItemProps = (item, index) => ({} as RenderItemProps) } = props;

if (item.divider === true) {
return <MenuDivider {...menuDividerProps} />;
}

const {
disabled,
isFocused,
Expand Down
13 changes: 13 additions & 0 deletions src/menu/styled-components.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,16 @@ export const StyledProfileBody = styled<StyledPropsT>('p', ({ $theme }) => ({
marginLeft: 0,
marginRight: 0,
}));

export const StyledMenuDivider = styled<StyledPropsT>('li', ({ $theme }) => ({
color: $theme.colors.contentPrimary,
borderBottomWidth: $theme.borders.border300.borderWidth,
borderBottomStyle: $theme.borders.border300.borderStyle,
borderBottomColor: $theme.borders.border300.borderColor,
marginTop: $theme.sizing.scale100,
marginBottom: $theme.sizing.scale100,
marginLeft: $theme.sizing.scale600,
marginRight: $theme.sizing.scale600,
listStyle: 'none',
height: 0,
}));
14 changes: 14 additions & 0 deletions src/menu/styled-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,17 @@ export const StyledProfileBody = styled<'p', StyledProps>('p', ({ $theme }) => (
marginRight: 0,
}));
StyledProfileBody.displayName = 'StyledProfileBody';

export const StyledMenuDivider = styled<'li', StyledProps>('li', ({ $theme }) => ({
color: $theme.colors.contentPrimary,
borderBottomWidth: $theme.borders.border300.borderWidth,
borderBottomStyle: $theme.borders.border300.borderStyle,
borderBottomColor: $theme.borders.border300.borderColor,
marginTop: $theme.sizing.scale100,
marginBottom: $theme.sizing.scale100,
marginLeft: $theme.sizing.scale500,
marginRight: $theme.sizing.scale500,
listStyle: 'none',
height: 0,
}));
StyledProfileBody.displayName = 'StyledMenuDivider';
1 change: 1 addition & 0 deletions src/menu/types.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export type MenuPropsT = {
Option?: OverrideT,
OptgroupHeader?: OverrideT,
ListItem?: OverrideT,
MenuDivider?: OverrideT;
},
/** Renders all menu content for SEO purposes regardless of menu state */
renderAll?: boolean,
Expand Down
1 change: 1 addition & 0 deletions src/menu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export type MenuOverrides = {
Option?: Override;
OptgroupHeader?: Override;
ListItem?: Override;
MenuDivider?: Override;
};
export type MenuProps = {
overrides?: MenuOverrides;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.