A configurable radial menu for React.
This README is for the next release 0.3.x. Please see 0.2.x.
Recommended: React and React-DOM 17.x
npm install --save styled-components react-pie-menu
# or
yarn add styled-components react-pie-menu
There are several demos. Also check out their sources. Here is one to get you started:
import React from 'react';
import PieMenu, { Slice } from 'react-pie-menu';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
export default ({ x, y }) => (
<PieMenu
radius="125px"
centerRadius="30px"
centerX={x}
centerY={y}
>
{/* Contents */}
<Slice><FontAwesomeIcon icon="home" size="2x" /></Slice>
<Slice onSelect={() => window.open('https://www.facebook.com', '_blank')}>
<FontAwesomeIcon icon="facebook-f" size="2x" />
</Slice>
<Slice onSelect={() => window.open('https://www.twitter.com', '_blank')}>
<FontAwesomeIcon icon="twitter" size="2x" />
</Slice>
<Slice onSelect={() => window.open('https://www.linkedin.com', '_blank')}>
<FontAwesomeIcon icon="linkedin-in" size="2x" />
</Slice>
<Slice onSelect={() => window.open('https://github.com/psychobolt/react-pie-menu', '_blank')}>
<FontAwesomeIcon icon="github" size="2x" />
</Slice>
<Slice onSelect={() => window.open('https://en.wikipedia.org/wiki/RSS', '_blank')}>
<FontAwesomeIcon icon="rss" size="2x" />
</Slice>
<Slice onSelect={() => window.open('https://www.pinterest.com/', '_blank')}>
<FontAwesomeIcon icon="pintrest" size="2x" />
</Slice>
<Slice><FontAwesomeIcon icon="asterisk" size="2x" /></Slice>
</PieMenu>
);
The code will display a 125 pixel radial menu with 8 slices and a 30 pixel radial center. Each slice is configured to open a url when selected.
For configuration of Components, see bellow.
Inner elements:
<div class="container" centerX centerY {...attrs}>
<ul class="list" radius>
<li class="item">{slice}</li>
...
</ul>
<PieCenter centerRadius />
</div>
Defines pie menu's radius in CSS Unit. For example, 150px
.
`
Defines the position of the pie menu in CSS Unit. For example, 0px
will be left-most position of its parent container.
Defines the position of the pie menu in CSS Unit. For example, 0px
will be the top-most position of its parent container.
Defines the center radius. For example, 30px
or 0
(no center). This prop is forwarded to the Center Component.
Offsets the starting slice. By default, the first slice's tip is facing north position (0 degrees).
You can provide your own React Component to be the Center (by default PieCenter). You may also import
PieCenter as a Component.
You can add custom attributes by specifying in attrs
. For example, { resize: 'false' }
.
You can define your own center by importing the Component. For example:
import { PieCenter } from 'react-pie-menu';
export default props => (
<PieMenu centerRadius={props.centerRadius || '30px'}>
{ /* my content */}
</PieMenu>
);
Same as Pie Menu. If you define your own center, you can specify your own value instead.
Inner elements:
<div class="container" contentHeight _highlight {...attrs}>
<div class="content-container">
<div class="content">{children}</div>
</div>
</div>
Height of the content in CSS Size. This prop is used to center the content between top and bottom of the slice. For example, 2em
.
Callback when mouse up event is triggered.
Callback when mouse over event is triggered.
Callback when slice is selected. This event is chained from a mouse up event.
You can add custom attributes by specifying in attrs
. For example, { enabled: 'true' }
.
Provided by PieMenu when a user input/touch hover a Slice. If true, by default the slice will be highlighted.
PieMenu supplies contextual values for child elements in the theme's context object. e.g.
import React from 'react';
import { ThemeContext } from 'styled-component';
import Content from './Content.component';
export default props => {
const { context } = React.useContext(ThemeContext);
/* returns e.g.
context = {
radius,
centerRadius,
...
};
*/
return <Content {...props} {...context} />
};
PieMenu's radius
PieCenter's center radius
Computed angle for every slice (360 / # number of slices). Calculated internally.
If true, the library detects that there is at most 2 slices.
Uniform offset angle for the current Slice.
Target location angle for the current Slice.
Number to skew the rectangle container for the current Slice, which adjusts tip angle of the slice (e.g. 90 - centralAngle). This is a CSS trick. See references, for details.
If true, the current Slice is active from mouse/touch over.
Style Pie Menu Components with styled-component's ThemeProvder.
import React from 'react';
import { ThemeProvder, css } from 'styled-components';
import MyCustomPie from './MyCustomPie';
const theme = {
pieMenu: {
container: css`
// style color...
`,
list: css`
// set pie size...
`,
item: css`
// rotate slice...
`,
center: css`
// style color...
`;
},
slice: {
container: css`
// style color...
`,
contentContainer: css`
// center content...
`,
content: css`
// rotate content...
`,
}
}
export default () => (
<ThemeProvider theme={theme}>
<MyCustomPie />
</ThemeProvider>
);
Refer to default styles from source files:
Useful functions for styling.
For coloring a slice's background
// ./Slice.style.js
import { background } from 'react-pie-menu';
import { css } from 'styled-components';
export const slice = css`
${background('#ff0000')}
/* or interpolate from colors scale in a theme */
${background('red.100')}
${background('tomato')}
`;
import { endAngle } from 'react-pie-menu';
import { css } from 'styled-components';
export const content = css`
transform: rotate(-${endAngle}deg);
`;
See available selectors:
You can use props to provide style values. React Pie Menu uses, as well as extends Styled System. See below for available props:
None
Category | Supported Props | Added Props |
---|---|---|
Text Color | color |
textHighlight |
Background Color | backgroundColor, bg |
highlight |
Usage:
import { Slice } from 'react-pie-menu';
export default props => <Slice {...props} backgroundColor="red" />
- v0.3.0 introduce the ability to use style props, context props, touch device, and React 17 support.
- v0.2.0 deprecated inline css styles in favor of CSS-in-JS.