psychobolt / react-pie-menu Goto Github PK
View Code? Open in Web Editor NEWA configurable radial menu for React
Home Page: https://psychobolt.github.io/react-pie-menu/
License: MIT License
A configurable radial menu for React
Home Page: https://psychobolt.github.io/react-pie-menu/
License: MIT License
Hi,
It's looking great. I have couple of questions.
Thanks,
Raja K
Just to test things out, I tried adding a very simple pie menu like this:
const PopupMenu = ({ graphNode }) => {
return (
graphNode && (
<PieMenu radius="125px" centerRadius="30px" centerX={200} centerY={300}>
<Slice>Slice 1</Slice>
<Slice>Slice 2</Slice>
<Slice>Slice 3</Slice>
<Slice>Slice 4</Slice>
</PieMenu>
)
);
};
This results in the pie menu being at the bottom of the page because the top and left are not set. See screenshot below.
Based on your readme you already know TypeScript. So it should be easy for you to provide a definition file.
when we click on the slice, the callback provided gets called twice.
Hi, thanks for the awesome project!
I was wondering if it's possible to add a delay so that if i mouse press for (for example) more than 0.5 seconds the pie menu pops out, otherwise it does not.
My idea was to add the pie-menu to only a specific part of the UI, that already interacts with mouse presses.
Thanks in advance :)
Hi,
Firstly thanks for the great package.
Having trouble getting the Pin Wheel to open on top of Full Calender package (https://fullcalendar.io/) for mobile views. Works great on desktop views. Versions and Calender plug-ins below:
//Imports:
import FullCalendar, {
CalendarApi,
DateSelectArg,
EventApi,
EventInput,
} from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import listPlugin from "@fullcalendar/list";
import { EventClickArg } from "@fullcalendar/core";
import PieMenu, { Slice } from "react-pie-menu";
import React, { useState } from "react";
//Open Wheel Repex:
//Boolean determines if Wheel renders
const [wheel, setWheel] = useState<
[CalendarApi | null, boolean, DateSelectArg | null]
>([null, false, null]);
function handleDateSelect(selectInfo: DateSelectArg) {
const calendarApi = selectInfo.view.calendar;
setWheel([calendarApi, true, selectInfo]);
};
//Calender
plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin, listPlugin]}
headerToolbar={{
left: "prev,next today",
center: "title",
right: "dayGridMonth,listMonth",
// right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek",
}}
initialView="dayGridMonth"
editable={true}
selectable={true}
selectMirror={true}
dayMaxEvents={true}
weekNumbers={true}
nowIndicator={true}
select={handleDateSelect}
firstDay={1}
/>```
Cheers
I used your PieMenu component in my ContextMenu Component, which is awesome! but there is a small problem, how to set the Border style of each Slice, For example, add a blue border to each Slice in the figure below
You can view the source code here:https://github.com/antvis/Graphin/blob/graphin-2.0/packages/graphin-components/src/ContextMenu/demos/PieMenu.tsx
thanks~
Hi,
Your readme file has a few pieces of information about styling, but it's very hard for me to figure out how to join these pieces together into a working example.
For example you document that the Slice
component has a bg
prop but don't provide any information about what it should be set to. I tried this:
{views &&
views.map((view) => (
<Slice
key={view.id}
bg="rgba(220, 220, 220, 0.8)"
onSelect={() => {
handleRelated(view);
}}>
<Typography variant="caption" color="textPrimary">
{view.name}
</Typography>
</Slice>
))}
but the background does not change at all.
You have a piece on "coloring a slice's background" like this:
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')}
`;
which just exports a string constant. Unless something else is importing this constant I can't see it having any effect, and in any case I want different background colors for different kinds of slice.
Please update the readme file with an example that brings these things together into a practical working example.
Thanks.
onMouseOver causes child elements to trigger it's callback which results in functions being run multiple times even if the mouse hasn't left the element. I think adding onMouseEnter would add flexibility since it will only run once "on mouse enter" since it does not react to event bubbling.
Hi, the latest version of styled-components doesn't seem to work with the version of styled-components-theme-connector
used by this package. Do you think you could bump it?
The <li>
element has its CSS set to overflow:hidden
and the <div>
element within it (I think this is contentContainer
) is wider than the pie slice, so the content inside of it is clipped.
I tried setting overflow:visible
in the container
css as follows, but this doesn't help. Ideally the contentContainer
<div>
should be sized to the pie slice to avoid this issue.
const theme = {
pieMenu: {
container: css`
border: 1px solid lightgrey;
background-color: rgba(255, 255, 255, 0.85);
`,
},
slice: {
container: css`
cursor: pointer;
overflow: visible;
background: rgba(0, 0, 0, 0.02);
&[kind='action'] {
background: rgba(128, 255, 128, 0.1);
}
&[kind='nav'] {
background: rgba(128, 128, 255, 0.05);
}
&:hover,
&[active='true'],
&[_highlight='true'] {
background: rgba(255, 255, 255, 0.85);
}
`,
},
};
Hi,
is it somehow possible to add tooltips to the slices, if hovering the slice e.g.
<Slice tooltip="Does something />
?
NPM repository version has the following for peer dependencies
"peerDependencies": { "react": "^17.0.2", "react-dom": "^17.0.2", "styled-components": "^5.2.3" }
but the Github version has
"peerDependencies": { "react": "^17.0.2 || ^18.0.0", "react-dom": "^17.0.2 || ^18.0.0", "styled-components": "^5.2.5" },
As a result, I'm unable to update the react version in my project even though react-pie-menu apparently supports version ^8.0.0.
The component would not install with React v17, so I downgraded to v16, but I still cannot get this component to install.
This is the dependencies section of my package.json
file:
"dependencies": {
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^4.0.0-alpha.56",
"@slack/web-api": "^5.14.0",
"d3": "^6.2.0",
"d3-force": "^2.1.1",
"pinch-zoom-js": "^2.3.4",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-is": "^17.0.1",
"react-router-dom": "^5.2.0",
"regenerator-runtime": "^0.13.7",
"styled-components": "^4.4.1"
},
I get an error message "Cannot read property 'length' of undefined" when I run the command npm i react-pie-menu
.
I am running node v15.2.1
Hi everyone,
I've rewritten react-pie-menu to simplify the DOM structure, improve accessibility and use more modern React patterns. Unfortuantely, I don't have time to contribute these changes as a PR here or maintain them as a fork, but I've published them as part of my app's GitHub repo, which you can find here.
Feel free to use these changes as you see fit. They're MIT licensed, so you can contribute them to react-pie-menu, publish them as a standalone package, or use them directly in your app. 😃
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
Warning
These dependencies are deprecated:
These branches will be created by Renovate only once you click their checkbox below.
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
eslint-plugin-react-hooks
, react
, react-dom
, react-is
)actions/download-artifact
, actions/upload-artifact
)@storybook/addon-actions
, @storybook/addon-docs
, @storybook/addon-essentials
, @storybook/addon-interactions
, @storybook/addon-links
, @storybook/builder-webpack5
, @storybook/react
)@yarnpkg/core
, @yarnpkg/sdks
, yarn
)These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@fortawesome/fontawesome-svg-core
, @fortawesome/free-brands-svg-icons
, @fortawesome/free-solid-svg-icons
, @fortawesome/react-fontawesome
)@babel/cli
, @babel/core
, @babel/eslint-parser
, @babel/helper-compilation-targets
, @babel/node
, @babel/plugin-proposal-decorators
, @babel/plugin-proposal-do-expressions
, @babel/plugin-proposal-export-default-from
, @babel/plugin-proposal-throw-expressions
, @babel/plugin-syntax-flow
, @babel/plugin-transform-react-jsx
, @babel/preset-env
, @babel/preset-flow
, @babel/preset-react
, @babel/template
)@yarnpkg/core
, @yarnpkg/sdks
, yarn
)jest
, jest-cli
).github/workflows/bundle.yml
actions/checkout v3
actions/setup-node v3
actions/upload-artifact v3
.github/workflows/codeql-analysis.yml
actions/checkout v3
github/codeql-action v2
github/codeql-action v2
github/codeql-action v2
.github/workflows/main.yml
actions/download-artifact v3
peaceiris/actions-gh-pages v3
.github/workflows/test.yml
actions/checkout v3
actions/setup-node v3
actions/checkout v3
actions/setup-node v3
actions/download-artifact v3
actions/checkout v3
actions/setup-node v3
actions/upload-artifact v3
actions/checkout v3
actions/download-artifact v3
chromaui/action v1
actions/checkout v3
actions/download-artifact v3
codecov/codecov-action v3
.yarn/sdks/eslint/package.json
.yarn/sdks/flow-bin/package.json
package.json
@babel/cli 7.21.0
@babel/core 7.21.4
@babel/eslint-parser 7.21.3
@babel/helper-compilation-targets 7.21.4
@babel/node 7.20.7
@babel/plugin-proposal-class-properties 7.18.6
@babel/plugin-proposal-decorators 7.21.0
@babel/plugin-proposal-do-expressions 7.18.6
@babel/plugin-proposal-export-default-from 7.18.10
@babel/plugin-proposal-export-namespace-from 7.18.9
@babel/plugin-proposal-json-strings 7.18.6
@babel/plugin-proposal-nullish-coalescing-operator 7.18.6
@babel/plugin-proposal-numeric-separator 7.18.6
@babel/plugin-proposal-optional-chaining 7.21.0
@babel/plugin-proposal-private-methods 7.18.6
@babel/plugin-proposal-private-property-in-object 7.21.11
@babel/plugin-proposal-throw-expressions 7.18.6
@babel/plugin-syntax-dynamic-import 7.8.3
@babel/plugin-syntax-flow 7.21.4
@babel/plugin-transform-react-jsx 7.21.0
@babel/preset-env 7.21.4
@babel/preset-flow 7.21.4
@babel/preset-react 7.18.6
@babel/template 7.20.7
@fortawesome/fontawesome-svg-core 6.1.2
@fortawesome/free-brands-svg-icons 6.1.2
@fortawesome/free-solid-svg-icons 6.1.2
@fortawesome/react-fontawesome 0.2.0
@mdx-js/react 1.6.22
@rollup/plugin-alias 5.0.0
@rollup/plugin-babel 6.0.3
@rollup/plugin-commonjs 25.0.4
@rollup/plugin-node-resolve 15.2.1
@rollup/plugin-replace 5.0.2
@storybook/addon-actions 6.5.16
@storybook/addon-console 2.0.0
@storybook/addon-docs 6.5.16
@storybook/addon-essentials 6.5.16
@storybook/addon-interactions 6.5.16
@storybook/addon-links 6.5.16
@storybook/builder-webpack5 6.5.16
@storybook/jest 0.2.1
@storybook/manager-webpack5 6.5.16
@storybook/react 6.5.16
@storybook/testing-library 0.2.0
@styled-system/color 5.1.2
@styled-system/core 5.1.2
@styled-system/theme-get 5.1.2
@testing-library/react 14.0.0
@yarnpkg/core 3.5.0
@yarnpkg/sdks 2.7.0
app-root-path 3.1.0
babel-jest 29.6.4
babel-loader 9.1.3
babel-plugin-add-module-exports 1.0.4
babel-plugin-dynamic-import-node 2.3.3
babel-plugin-lodash 3.3.4
babel-plugin-module-resolver 5.0.0
babel-plugin-named-exports-order 0.0.2
babel-plugin-styled-components 2.1.4
cash-true 0.0.2
concurrently 8.2.1
cross-env 7.0.3
eslint 8.14.0
eslint-config-airbnb 19.0.4
eslint-config-react-app 7.0.1
eslint-import-resolver-alias 1.1.2
eslint-import-resolver-node 0.3.9
eslint-import-resolver-webpack 0.13.7
eslint-plugin-flowtype 8.0.3
eslint-plugin-import 2.28.1
eslint-plugin-jest 27.2.3
eslint-plugin-jsx-a11y 6.7.1
eslint-plugin-react 7.30.1
eslint-plugin-react-hooks 4.6.0
eslint-plugin-storybook 0.6.13
execa 8.0.1
flow-bin 0.183.0
flow-typed 3.9.0
glob 7.2.3
http-server 14.1.1
is-class 0.0.9
jest 27.5.1
jest-cli 27.5.1
jest-specific-snapshot 8.0.0
jest-styled-components 7.1.1
lodash 4.17.21
micromatch 4.0.5
postcss 8.4.28
postcss-scss 4.0.7
prop-types 15.8.1
raf 3.4.1
raf-schd 4.0.3
react 18.2.0
react-dom 18.2.0
react-is 18.2.0
react-router-dom 5.3.4
require-from-string 2.0.2
rimraf 5.0.1
rollup 3.28.1
rollup-plugin-flow-entry 0.3.6
rollup-plugin-mjs-entry 0.1.1
rollup-plugin-terser 7.0.2
slash 3.0.0
source-map-loader 4.0.1
styled-components 5.3.11
styled-components-theme-connector 0.1.8
stylelint 14.16.1
stylelint-config-standard-scss 5.0.0
stylelint-config-styled-components 0.1.1
symlink-dir 5.1.1
to-px 1.1.0
webpack 5.88.2
yargs 17.7.2
react ^17.0.2 || ^18.0.0
react-dom ^17.0.2 || ^18.0.0
styled-components ^5.2.5
yarn 3.5.0
shared/flow-deps/package.json
raf-schd 4.0.3
styled-components-theme-connector 0.1.8
yarn 3.5.0
I have placed a red region over the approximate area where mouse collision occurs. The first is with no scrolling having being done yet (page positioning on load) which shows the expected behaviour:
If I scroll the page down, however, this region seems to scroll faster than the rest of the page (this also happens with side to side scrolling it seems):
Is there anything we're missing that would interfere with the collision regions in this way?
Cheers!
I am experiencing an issue where the pie menu is double its normal size when there are very few slices. In this case the slices are also clipped, presumably because they overflow the pie menu container.
This is the code for my component:
import React, { useState, useEffect } from 'react';
import { Typography } from '@material-ui/core';
import PieMenu, { Slice } from 'react-pie-menu';
import { ThemeProvider, css } from 'styled-components';
import OctopediaService from '~services/OctopediaService';
// See https://github.com/psychobolt/react-pie-menu
export const PopupMenu = ({ selected, onProperties, onDrillDown, onExpandNode, onHideNode, onChangeView }) => {
const [views, setViews] = useState(null);
// This effect gets a list of views relating to the node
useEffect(() => {
if (!selected || !selected.graphNode || !selected.graphNode.tags || !onChangeView) {
setViews(null);
return;
}
const promises = [];
const relatedViews = [];
const octopediaService = new OctopediaService();
selected.graphNode.tags.forEach((tag) => {
promises.push(
octopediaService.getViews(tag).then((viewsByCategory) => {
viewsByCategory.forEach((category) => {
category.views.forEach((categoryView) => {
categoryView.nodeType = tag;
relatedViews.push(categoryView);
});
});
}),
);
});
Promise.all(promises).then(() => {
setViews(relatedViews);
});
}, [onChangeView, selected]);
const handleProperties = () => {
if (onProperties) onProperties(selected.graphNode);
};
const handleExpand = () => {
if (onExpandNode) onExpandNode(selected.graphNode);
};
const handleHide = () => {
if (onHideNode) onHideNode(selected.graphNode);
};
const handleDrillDown = () => {
if (onDrillDown) onDrillDown(selected.graphNode);
};
const handleRelated = (view) => {
if (onChangeView) onChangeView(selected.graphNode, view);
};
const showExpand = !!onExpandNode;
const showHide = !!onHideNode;
const showDrillDown = !!onDrillDown;
const theme = {
pieMenu: {
item: css`
overflow: hidden;
`,
container: css`
border: 4px solid white;
background: rgba(255, 255, 255, 0.85);
overflow: visible;
`,
center: css`
background: rgba(0, 0, 0, 0.1);
`,
},
slice: {
item: css`
overflow: visible;
`,
container: css`
cursor: pointer;
overflow: visible;
border: 1px solid lightgrey;
background: rgba(0, 0, 0, 0.02);
&[kind='action'] {
background: rgba(128, 255, 128, 0.1);
}
&[kind='nav'] {
background: rgba(128, 128, 255, 0.08);
}
&:hover,
&[active='true'],
&[_highlight='true'] {
background: rgba(255, 255, 255, 0.85);
}
`,
contentContainer: css``,
content: css`
padding-left: 60px;
padding-right: 60px;
`,
},
};
return (
selected &&
views && (
<ThemeProvider theme={theme}>
<PieMenu radius="120px" centerRadius="30px" centerX={selected.x + 'px'} centerY={selected.y + 'px'}>
<Slice onSelect={handleProperties} contentHeight="5em" attrs={{ kind: 'action' }}>
<Typography variant="caption" color="primary">
{selected.graphNode.name} properties
</Typography>
</Slice>
{showExpand && (
<Slice onSelect={handleExpand} contentHeight="5em" attrs={{ kind: 'action' }}>
<Typography variant="caption" color="primary">
Expand {selected.graphNode.name}
</Typography>
</Slice>
)}
{showHide && (
<Slice onSelect={handleHide} contentHeight="5em" attrs={{ kind: 'action' }}>
<Typography variant="caption" color="primary">
Hide {selected.graphNode.name}
</Typography>
</Slice>
)}
{showDrillDown && (
<Slice onSelect={handleDrillDown} contentHeight="5em" attrs={{ kind: 'action' }}>
<Typography variant="caption" color="primary">
Focus on {selected.graphNode.name}
</Typography>
</Slice>
)}
{views.map((view) => (
<Slice
key={view.id}
contentHeight="5em"
attrs={{ kind: 'nav' }}
onSelect={() => {
handleRelated(view);
}}>
<Typography variant="caption" color="textPrimary">
{view.name}
</Typography>
</Slice>
))}
</PieMenu>
</ThemeProvider>
)
);
};
Thoughts on getting this to work on react-native?
Trying to render a basic pie via Next.js, I ran into the error
Warning: Prop `id` did not match. Server: "slice_nRYwgw795" Client: "slice_A6Q3M3Ww1"
and the pie isn't interactive.
This isn't a big problem for me because the workaround is easy, and I don't really need to render this server-side, but I spent time debugging, and SSR is default in Next.js, so I thought I'd at least post my findings.
Workaround:
Don't render on the server (I was able to wrap the component via NoSSR)
Reproduction steps:
cd web
npm i
npm run dev # open localhost:3000/pie and see the `Prop did not match` error in devtools console
Info discovered from debugging:
Solution ideas:
I'm not aware of the intent of using a time-based id, but if the main reason is to solve the list-key uniqueness problem, perhaps
Slice
could accept a key as a propA declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.