Skip to content

Commit

Permalink
Switch Context API
Browse files Browse the repository at this point in the history
  • Loading branch information
psychobolt committed Feb 17, 2021
1 parent c39cd3f commit 185c0ff
Show file tree
Hide file tree
Showing 14 changed files with 264 additions and 1,026 deletions.
91 changes: 64 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ yarn add styled-components react-pie-menu

There are several [demos](https://psychobolt.github.io/react-pie-menu/). Also check out their [sources](stories). Here is one to get you started:

```jsx
```js
import React from 'react';
import PieMenu, { Slice } from 'react-pie-menu';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
Expand Down Expand Up @@ -72,13 +72,13 @@ For configuration of Components, see bellow.

Inner elements:

```jsx
<div class="container" centerX centerY radius {..attrs}>
<ul class="list" radius>
<li class="item" startAngle endAngle skew centralAngle></li>
...p
```js
<div class="container" centerX centerY {...attrs}>
<ul class="list">
<li class="item">{slice}</li>
...
</ul>
<Center centerRadius={centerRadius} />
<Center />
</div>
```

Expand Down Expand Up @@ -116,7 +116,7 @@ You can add custom attributes by specifying in `attrs`. For example, `{ resize:

You can define your own center by importing the Component. For example:

```jsx
```js
import { PieCenter } from 'react-pie-menu';

export default (props) => (
Expand All @@ -137,7 +137,7 @@ Same as Pie Menu. If you define your own center, you can specify your own value
Inner elements:

```html
<div class="container" radius centralAngle centralRadius contentHeight {..attrs}>
<div class="container" contentHeight {...attrs}>
<div class="content-container">
<div class="content">{children}</div>
</div>
Expand Down Expand Up @@ -166,45 +166,65 @@ 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' }`.

### Contexts
## Theme Context

PieMenu supplies [context](https://reactjs.org/docs/context.html) props for child elements.
PieMenu supplies contextual values for child elements in the theme's context object. e.g.

#### propTypes
```js
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} />
};
```

By default the [Slice](#slice) Component inherits properties from [PieMenu](#piemenu) globally:
### Context Props

##### `radius: string`
#### `radius: string`

[PieMenu](#piemenu)'s radius

##### `centerRadius: string`
#### `centerRadius: string`

[PieCenter](#piecenter)'s center radius

##### `centralAngle: number`
#### `centralAngle: number`

Computed angle for every slice (360 / # number of slices). Calculated internally.

##### `polar: boolean`
#### `polar: boolean`

If true, the library detects that there is at most 2 slices.

#### itemTypes

Additionally, the [Slice](#slice) Component inherits calculated local properties from [PieMenu](#piemenu):
#### Item's Context

##### `startAngle: number`

Uniform offset angle.
Uniform offset angle for the current Slice.

##### `endAngle: number`

Target location angle
Target location angle for the current Slice.

##### `skew: number`

Number to skew the rectangle container which adjusts tip angle of the slice (e.g. 90 - centralAngle). This is a CSS trick. See [references](#reference), for details.
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](#reference), for details.


##### `active: boolean`

If true, the current Slice is active from mouse/touch over.

### Styling

Expand Down Expand Up @@ -267,6 +287,10 @@ export default () => (
);
```

Refer to default styles from source files:
- [PieMenu & PieCenter](src/PieMenu.style.js)
- [Slice](src/Slice/Slice.style.js)

##### Style Functions

###### `background`
Expand All @@ -286,13 +310,26 @@ export const slice = css`
`;
```

Refer to default styles from source files:
- [PieMenu & PieCenter](src/PieMenu.style.js)
- [Slice](src/Slice/Slice.style.js)
##### Context Selectors

Usage e.g.

```js
import { endAngle } from 'react-pie-menu';
import { css } from 'styled-components';

export const content = css`
transform: rotate(-${endAngle}deg);
`;
```

See available selectors:
- [PieMenu](src/PieMenu.selectors.js)
- [Slice](src/Slice/Slice.selectors.js)

## Notable Change Notes

- v0.2.6 introduce the ability to use style props and add touch support.
- v0.3.0 introduce the ability to use style functions, context props, touch device, and React 17 support.
- v0.2.0 deprecated inline css styles in favor of CSS-in-JS.

## Reference
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
"@babel/preset-flow": "^7.12.13",
"@babel/preset-react": "^7.12.13",
"@babel/register": "^7.12.13",
"@fortawesome/fontawesome-svg-core": "^1.2.34",
"@fortawesome/free-brands-svg-icons": "^5.15.2",
"@fortawesome/free-solid-svg-icons": "^5.15.2",
"@fortawesome/react-fontawesome": "^0.1.14",
"@lerna/project": "^4.0.0",
"@rollup/plugin-alias": "^3.1.2",
"@rollup/plugin-babel": "^5.3.0",
Expand Down Expand Up @@ -99,13 +103,12 @@
"react": "^17.0.1",
"react-cache": "^2.0.0-alpha.1",
"react-dom": "^17.0.1",
"react-router-dom": "^5.0.0",
"react-router-dom": "^5.2.0",
"rimraf": "^3.0.2",
"rollup": "2.39.0",
"rollup-plugin-terser": "^7.0.2",
"slash": "^3.0.0",
"source-map-loader": "1.1.0",
"storybook-readme": "^5.0.3",
"styled-components": "^5.2.1",
"stylelint": "^13.10.0",
"stylelint-config-recommended": "^3.0.0",
Expand All @@ -116,7 +119,7 @@
"hashids": "^2.2.8",
"raf-schd": "^4.0.2",
"react-is": "^17.0.1",
"styled-components-theme-connector": "^0.1.4"
"styled-components-theme-connector": "^0.1.5"
},
"peerDependencies": {
"react": "^17.0.1",
Expand Down
32 changes: 16 additions & 16 deletions src/PieMenu.component.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
// @flow
import * as React from 'react';
import { connectTheme } from 'styled-components-theme-connector';
import { connectTheme, ThemeContextProvider } from 'styled-components-theme-connector';
import rafSchedule from 'raf-schd';

import { type ContextType, Context, ItemContext } from './Slice';
import { type Context } from './Slice/Slice.component';

const List = connectTheme('pieMenu.list')('ul');

const Item = connectTheme('pieMenu.item')(({ startAngle, endAngle, skew, active, children, className }) => (
<ItemContext.Provider value={{ startAngle, endAngle, skew, active }}>
<li className={className}>{children}</li>
</ItemContext.Provider>
));
const Item = connectTheme('pieMenu.item')('li');

export const PieCenter: any = connectTheme('pieMenu.center')('div');

Expand Down Expand Up @@ -46,17 +42,19 @@ type Props = {
Center: any,
attrs: {},
children: React.Node,
} & ContextType;
} & Context;

const PieMenu = ({
className,
startOffsetAngle = 0,
radius,
centerRadius,
centralAngle,
polar,
Center = PieCenter,
slices,
attrs = {},
}: Props) => {
const { radius, centerRadius, centralAngle } = React.useContext(Context);
const deltaAngle = 90 - centralAngle;
const startAngle = polar ? 45 : startOffsetAngle + deltaAngle + (centralAngle / 2);
const isMounted = React.useRef(false);
Expand Down Expand Up @@ -100,18 +98,20 @@ const PieMenu = ({
<div {...attrs} className={className}>
<List radius={radius}>
{slices.map(({ itemId, slice }, i) => (
<Item
id={itemId}
<ThemeContextProvider
key={itemId}
data-id={itemId}
active={activeSlice === itemId}
startAngle={startAngle}
endAngle={centralAngle * i}
skew={polar ? 0 : deltaAngle}
centralAngle={centralAngle}
active={activeSlice === itemId}
>
{slice}
</Item>
<Item
id={itemId}
data-id={itemId}
>
{slice}
</Item>
</ThemeContextProvider>
))}
</List>
<Center id="center" centerRadius={centerRadius} />
Expand Down
15 changes: 10 additions & 5 deletions src/PieMenu.container.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// @flow
import * as React from 'react';
import { isFragment, isElement } from 'react-is';
import { ThemeContextProvider } from 'styled-components-theme-connector';
import Hashids from 'hashids';

import PieMenu from './PieMenu.component';

import { Context } from './Slice';

const hashids = new Hashids();

const getSlices = (child, index) => {
Expand Down Expand Up @@ -41,9 +40,15 @@ export default (({
});
const centralAngle = 360 / slices.length || 360;
const polar = centralAngle % 180 === 0;
const context = {
radius,
centerRadius,
centralAngle,
polar,
};
return (
<Context.Provider value={{ radius, centerRadius, centralAngle, polar }}>
<PieMenu {...props} radius={radius} polar={polar} slices={slices} />
</Context.Provider>
<ThemeContextProvider {...context}>
<PieMenu {...props} {...context} slices={slices} />
</ThemeContextProvider>
);
}: React.AbstractComponent<any>);
8 changes: 8 additions & 0 deletions src/PieMenu.selectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const context = key => ({ theme }) => theme.context?.[key];

export const radius = context('radius');
export const centerRadius = context('centerRadius');
export const centralAngle = context('centralAngle');
export const polar = context('polar');
export const ifObtuse = (value, _default) => props => (context('centralAngle')(props) > 90
? value : _default);
31 changes: 17 additions & 14 deletions src/PieMenu.style.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { css } from 'styled-components';

const position = ({ radius, centerX, centerY }) => css`
import { radius, centerRadius, ifObtuse } from './PieMenu.selectors';
import { startAngle, endAngle, skew } from './Slice/Slice.selectors';

const position = ({ centerX, centerY, ...props }) => css`
position: ${centerX || centerY ? 'absolute' : 'relative'};
${centerX ? `left: calc(${centerX} - ${radius})` : ''};
${centerY ? `top: calc(${centerY} - ${radius})` : ''};
${centerX ? `left: calc(${centerX} - ${radius(props)})` : ''};
${centerY ? `top: calc(${centerY} - ${radius(props)})` : ''};
`;

export const container = css`
Expand All @@ -19,17 +22,17 @@ export const list = css`
padding: 0;
margin: 0;
border-radius: 50%;
width: calc(2 * ${({ radius }) => radius});
height: calc(2 * ${({ radius }) => radius});
width: calc(2 * ${radius});
height: calc(2 * ${radius});
`;

export const item = css`
width: ${({ centralAngle }) => (centralAngle > 90 ? '100%' : '50%')};
height: ${({ centralAngle }) => (centralAngle > 90 ? '100%' : '50%')};
bottom: ${({ centralAngle }) => (centralAngle > 90 ? '50%' : 'initial')};
right: ${({ centralAngle }) => (centralAngle > 90 ? '50%' : 'initial')};
width: ${ifObtuse('100%', '50%')};
height: ${ifObtuse('100%', '50%')};
bottom: ${ifObtuse('50%', 'initial')};
right: ${ifObtuse('50%', 'initial')};
position: absolute;
transform: rotate(${({ startAngle, endAngle }) => startAngle + endAngle}deg) skew(${({ skew }) => skew}deg);
transform: rotate(${props => startAngle(props) + endAngle(props)}deg) skew(${skew}deg);
transform-origin: bottom right;
overflow: hidden;
`;
Expand All @@ -38,8 +41,8 @@ export const center = css`
position: absolute;
border-radius: 50%;
background: transparent;
top: calc(50% - ${({ centerRadius }) => centerRadius});
left: calc(50% - ${({ centerRadius }) => centerRadius});
width: calc(2 * ${({ centerRadius }) => centerRadius});
height: calc(2 * ${({ centerRadius }) => centerRadius});
top: calc(50% - ${centerRadius});
left: calc(50% - ${centerRadius});
width: calc(2 * ${centerRadius});
height: calc(2 * ${centerRadius});
`;
2 changes: 1 addition & 1 deletion src/PieMenu.theme.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as pieMenuStyles from './PieMenu.style';
import { sliceStyles } from './Slice';
import * as sliceStyles from './Slice/Slice.style';

export default {
pieMenu: pieMenuStyles,
Expand Down
Loading

0 comments on commit 185c0ff

Please sign in to comment.