jchristman / react-context-menus

A library to make context menus very easy for React.
http://jchristman.github.io/react-context-menus/
MIT License
11 stars 2 forks source link

How to obtain context sensitive values #3

Closed MonkeyJumps closed 6 years ago

MonkeyJumps commented 6 years ago

I am trying to display a list of images. I am wrapping the context menu around the thumbnails. How do i pass along to the context menu information about the thumbnail. I need to pass along the page number of the thumbnail. I can only seem to get access to the parent component of the view component.

import React from 'react';
import './styles/ThumbnailView.scss';
import ContextMenu from 'react-context-menus';
import { menu_items, menu_options } from './ContextMenu/ThumbViewMenuItems';

const Thumbnail = (props)=>{
    const {page,path} = props;

    return (
        <div key={page.PageNumber} className='thumbnail'>
                <div className='img-container'>
                    <a href="#">
                        <img src={path} />
                    </a>
                </div>
                <div className='img-caption'>Page {page.PageNumber}</div>
            </div>
    );
}
class ThumbnailView extends React.Component {
    constructor(props) {
        super(props);        
        this.createThumbnailTemplate = this.createThumbnailTemplate.bind(this);            
    }    
    createThumbnailTemplate(page) {
        const { imageDirectory, onThumbnailSelected} = this.props;
        console.log("props from template : ", this.props);
        const path = imageDirectory + page.FileName;          

        return ( <Thumbnail page={page} path={path}  />);
    }
    render() {
        const { pages } = this.props;
        return this.props.connectContextMenu(<section id="gallery">
            {pages.map(this.createThumbnailTemplate)}
        </section>);
    }
}

export default ContextMenu(menu_items, menu_options)(ThumbnailView);
MonkeyJumps commented 6 years ago

After following your dynamic menus example I realized I was setting it up incorrectly. Now I am importing my thumbnail component from where I define the context menu items as seen below. Everything renders fine, but now i get no context menu. Using the React Dev tools i can see the props for the ContextMenu. If i set the prop showContextMenu = true; then the context menu displays but not when i right click around thumbnail.


'use strict';
import ContextMenu from 'react-context-menus';
import Thumbnail from './../Thumbnail';

const menu_items = (props) => {
    return [
        {
            label: 'Rotate Page Left',           
            onClick: (event, props,item) => {console.log(props);

                console.log("item ", item);
                console.log("event : ", event.target);}
        },
        {
            label: 'Rotate Page Right',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        {
            label: 'Save Rotation',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        '-',
        {
            label: 'Split Document at Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        '-',
        {
            label: 'Insert After Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        {
            label: 'Insert Before Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        {
            label: 'Replace Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },        
        '-',
        {
            label: 'Delete Page',
            disabled: false  ,                
            onClick: (event, props) => {onDeleteDocuments(props.document,props.onDelete)}
        }
    ];
}

const menu_options = (props) => {
    return {
        theme: '',
        style: { border: '1px solid #e7ada9', color: '#000', 'text-align': 'left' },
        container: {
            zIndex: 1000
        }
    }
}

export default ContextMenu(menu_items, menu_options)(Thumbnail);
 strict';
import ContextMenu from 'react-context-menus';
import Thumbnail from './../Thumbnail';

const menu_items = (props) => {
    return [
        {
            label: 'Rotate Page Left',           
            onClick: (event, props,item) => {console.log(props);

                console.log("item ", item);
                console.log("event : ", event.target);}
        },
        {
            label: 'Rotate Page Right',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        {
            label: 'Save Rotation',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        '-',
        {
            label: 'Split Document at Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        '-',
        {
            label: 'Insert After Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        {
            label: 'Insert Before Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },
        {
            label: 'Replace Page',           
            onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
        },        
        '-',
        {
            label: 'Delete Page',
            disabled: false  ,                
            onClick: (event, props) => {onDeleteDocuments(props.document,props.onDelete)}
        }
    ];
}

const menu_options = (props) => {
    return {
        theme: '',
        style: { border: '1px solid #e7ada9', color: '#000', 'text-align': 'left' },
        container: {
            zIndex: 1000
        }
    }
}

export default ContextMenu(menu_items, menu_options)(Thumbnail);

Then i insert the component into my view.


import React from 'react';
import './styles/ThumbnailView.scss';
import Thumbnail from './ContextMenu/ThumbViewMenuItems';

class ThumbnailView extends React.Component {
    constructor(props) {
        super(props);        
        this.createThumbnailTemplate = this.createThumbnailTemplate.bind(this);            
    }    
    createThumbnailTemplate(page) {
        const { imageDirectory, onThumbnailSelected} = this.props;
        //console.log("props from template : ", this.props);
        const path = imageDirectory + page.FileName;          

        return ( <Thumbnail key={page.PageNumber} page={page} path={path}  />);
    }
    render() {
        const { pages } = this.props;
        return (<section id="gallery">
            {pages.map(this.createThumbnailTemplate)}            
        </section>);
    }
}

export default ThumbnailView;
jchristman commented 6 years ago

I’ll take a look tonight and let you know what I see

🙂

Sent from my iPhone

On Sep 28, 2017, at 17:24, Michael notifications@github.com wrote:

After following your dynamic menus example I realized I was setting it up incorrectly. Now I am importing my thumbnail component from where I define the context menu items as seen below. Everything renders fine, but now i get no context menu. Using the React Dev tools i can see the props for the ContextMenu. If i set the prop showContextMenu = true; then the context menu displays but not when i right click around thumbnail.

'use strict'; import ContextMenu from 'react-context-menus'; import Thumbnail from './../Thumbnail';

const menu_items = (props) => { return [ { label: 'Rotate Page Left',
onClick: (event, props,item) => {console.log(props);

            console.log("item ", item);
            console.log("event : ", event.target);}
    },
    {
        label: 'Rotate Page Right',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    {
        label: 'Save Rotation',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    '-',
    {
        label: 'Split Document at Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    '-',
    {
        label: 'Insert After Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    {
        label: 'Insert Before Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    {
        label: 'Replace Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },        
    '-',
    {
        label: 'Delete Page',
        disabled: false  ,                
        onClick: (event, props) => {onDeleteDocuments(props.document,props.onDelete)}
    }
];

}

const menu_options = (props) => { return { theme: '', style: { border: '1px solid #e7ada9', color: '#000', 'text-align': 'left' }, container: { zIndex: 1000 } } }

export default ContextMenu(menu_items, menu_options)(Thumbnail); strict'; import ContextMenu from 'react-context-menus'; import Thumbnail from './../Thumbnail';

const menu_items = (props) => { return [ { label: 'Rotate Page Left',
onClick: (event, props,item) => {console.log(props);

            console.log("item ", item);
            console.log("event : ", event.target);}
    },
    {
        label: 'Rotate Page Right',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    {
        label: 'Save Rotation',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    '-',
    {
        label: 'Split Document at Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    '-',
    {
        label: 'Insert After Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    {
        label: 'Insert Before Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },
    {
        label: 'Replace Page',           
        onClick: (event, props) => {props.onMenuAction('copy',props.document.Name);}
    },        
    '-',
    {
        label: 'Delete Page',
        disabled: false  ,                
        onClick: (event, props) => {onDeleteDocuments(props.document,props.onDelete)}
    }
];

}

const menu_options = (props) => { return { theme: '', style: { border: '1px solid #e7ada9', color: '#000', 'text-align': 'left' }, container: { zIndex: 1000 } } }

export default ContextMenu(menu_items, menu_options)(Thumbnail); Then i insert the component into my view.

import React from 'react'; import './styles/ThumbnailView.scss'; import Thumbnail from './ContextMenu/ThumbViewMenuItems';

class ThumbnailView extends React.Component { constructor(props) { super(props);
this.createThumbnailTemplate = this.createThumbnailTemplate.bind(this);
}
createThumbnailTemplate(page) { const { imageDirectory, onThumbnailSelected} = this.props; //console.log("props from template : ", this.props); const path = imageDirectory + page.FileName;

    return ( <Thumbnail key={page.PageNumber} page={page} path={path}  />);
}
render() {
    const { pages } = this.props;
    return (<section id="gallery">
        {pages.map(this.createThumbnailTemplate)}            
    </section>);
}

}

export default ThumbnailView; — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

MonkeyJumps commented 6 years ago

My apologies, I checked one more time and found the error. I was not calling connectContextMenu from my target render method. Cheers! working now.

import React from 'react';
import './styles/ThumbnailView.scss';
const Thumbnail = (props)=>{
    const {page,path} = props;    
    return props.connectContextMenu(
        <div key={page.PageNumber} className='thumbnail'>
                <div className='img-container'>
                    <a href="#">
                        <img src={path} />
                    </a>
                </div>
                <div className='img-caption'>Page {page.PageNumber}</div>
            </div>
    );
}

export default Thumbnail;
jchristman commented 6 years ago

Glad to hear it!

If you have any ideas on a way to improve this library, please let me know. I built this for myself, got it working, and don’t really have many ideas on how to improve it. I suppose a further step could be bringing in the source of the original menu...

But I’m mainly focused on usability here. Is it easy enough to use? Too hard? Documentation need more explanation?

MonkeyJumps commented 6 years ago

I think its much easier to use the any other context menus. I was testing out https://www.npmjs.com/package/react-contextmenu and it took lots of work to set up. I found your code to be much easier. Yes the menu items are being a pain and hopefully you can get that set, but its working. I would create a better readme on the NPM package page like the one for react-contextmenu and i am sure you will get many more hits. Thanks for your help! Please keep me posted on the menu items, I go live soon :)

Do you happen to have any good example styling the menu items? Its a bit frustrating that their page is down. I need to place some icons to the left of each label and maybe a vertical margin.

jchristman commented 6 years ago

Unfortunately I don't have any of their documentation laying around, but I tried to dig up some old code. Here's a chunk that I used to make icon'd things. I'm having trouble getting some of my older code to compile (it's been a long time since I wrote an application for this because life) so I don't have any of my css around. I cloned the react-menus README.md from the npm package and it has some info on styling.

import ContextMenu from 'react-context-menus';
import FontAwesome from '../components/v_font_awesome.jsx';

import WindowTabbedTabbarTab from '../components/window_tabbed_tabbar_tab.jsx';

import {tabMoveType} from '../configs/drag_types.js';

const items = (props) => {
    return [
        {
            label: ( <span><FontAwesome name='edit'/>&nbsp;Rename</span> ),
            onClick: () => props.setEditing(true)
        },
        '-',
        {
            label: ( <span><FontAwesome name='close'/>&nbsp;Close This</span> ),
            onClick: () => props.actions.closeTab(props.path)
        },
        {
            label: ( <span><FontAwesome name='close'/>&nbsp;Close All But This</span> ),
            onClick: () => props.actions.closeAllTabsBut(props.path)
        },
        {
            label: ( <span><FontAwesome name='close'/>&nbsp;Close All</span> ),
            onClick: () => props.actions.closeAllTabs(props.path)
        }
    ];
}

const options = {
    container: {
        zIndex: 3
    }
}

export default ContextMenu(items, options)(WindowTabbedTabbarTab);