Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Allow to optionally only toggle if clicked on the toggler #9

Closed
bkniffler opened this issue Dec 1, 2015 · 11 comments
Closed

Allow to optionally only toggle if clicked on the toggler #9

bkniffler opened this issue Dec 1, 2015 · 11 comments
Labels
😎 enhancement New feature or request

Comments

@bkniffler
Copy link
Contributor

Hey,
Sometimes its necessary, to only toggle if explicitly the trigger component was clicked.
Currently I'm overriding the Header and I put a click handler with preventDefault() on my node.

I think there should be a better way for handling that case. Maybe the onClick should be placed in the default decorator Header/Toggle component, and if overwritten, we handle it ourself.

Header: (props, toggle) => {
        return (
            <div style={props.style} onClick={toggle}>
                {props.node.name}
            </div>
        );
    }
@alexcurtis
Copy link
Collaborator

@bkniffler That makes sense to me. The only problem is, we will have to push the onClick to the toggle component as well, which makes it more complicated overall. Especially when you have custom toggle and header decorators, you will have to remember to use onClick twice. What do you think?

@alexcurtis alexcurtis added the 😎 enhancement New feature or request label Dec 2, 2015
@bkniffler
Copy link
Contributor Author

I think it would make sense to join header and toggle decorators, this would give us more flexibility. What do you think about that?

@bkniffler
Copy link
Contributor Author

Just as an example, this is how my header looks like now. It checks weather its a terminal node to insert the caret. Also, it checks for active state for bold font. And if a 'code' is present, an additional link is displayed.

const {id, toggled, code, name, active, terminal} = props.node;
<div onClick={toggle} style={{...props.style.base}}>
   {!terminal ? <strong style={{display: 'table-cell', width:'20px'}}>
      <i className={"icon caret " + (toggled ? 'down' : 'right')} style={{position:'absolute', top:'1px'}}></i>
   </strong> : <strong style={{display: 'table-cell', width:'20px'}}> </strong>}
   {code ? <a onClick={activate} href="javascript:;" style={{display: 'table-cell', minWidth: '27px', paddingRight:'10px', whiteSpace: 'nowrap'}}>{code}</a> : null}
   <span style={{display: 'table-cell', fontWeight: active?'bold':'initial'}}>{name}</span>
</div>

@alexcurtis
Copy link
Collaborator

Its a difficult one. Because a lot of times you will want to use another header, but keep the toggle the same, as a lot of people will be happy with the default toggle decorator. But the header must be changed for simple things like icons. I'll have a think about it.

@bkniffler
Copy link
Contributor Author

Its true. So why not adding a 'row' decorator? The default one would just render the default toggle and header.

{row: [toggle, header]}
Row could be something like renderRow(props, onToggle, DefaultToggle, DefaultHeader). onToggle could also live within the props object.

Also you could think about handing the decorators one by one as props, e.g. renderToggle, renderHeader, renderRow, renderLoader. Your current approach only allows for all or nothing.

@gbmhunter
Copy link

+1 I was looking for this exact functionality! Otherwise parts of the tree get toggled when all the user wants to do is select a particular item.

@alexcurtis
Copy link
Collaborator

@bkniffler @gbmhunter I agree with you guys. I'm going to look into this issue in more depth, to find a good balance between extensibility and out-of-the-box usability. I'll take some ideas from @bkniffler's work and try to get a good mix.

@alexcurtis
Copy link
Collaborator

@bkniffler @gbmhunter. I have release 1.1.0 to npm. This includes a new decorator called Container which should allow you to fully rewrite a node. It also pulls down the onClick event. Most of this comes from @bkniffler's work, so id like to say thanks to him for helping out with this one!

@bkniffler
Copy link
Contributor Author

Cool, couldn't be happier with your new version

import {Treebeard, decorators} from 'react-treebeard';
import TreeStyle from './tree-style';

var Container = (props)=>{
    // Handle node render with inline loading indicator, custom toggle and header
}

const Loading = (props) => <div></div>;

<Treebeard data={lists} decorators={{...decorators, Loading, Container}} onToggle={updateTreeItem} style={TreeStyle} animations={false}/>

Separating the decorators as multiple props would still make this a bit better. But it works great!

@bkniffler
Copy link
Contributor Author

ps. Feel free to remove my pull requests as soon as you're done incorporating the parts you like.

@eladfrn
Copy link

eladfrn commented Feb 21, 2017

We also need to be able to expand/collapse the tree only by the toggle icon.
Can anyone please share their solution?
Thanks

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
😎 enhancement New feature or request
Development

No branches or pull requests

4 participants