Can I specify location of children in a compound component in backdraftjs?

24 Views Asked by At

I would like to place Gift inside DoubleBox which consists of a PinkBox inside a BlackBox. So here is what I try:

import {Component, e, render} from './node_modules/bd-core/lib.js';
            
class BlackBox extends Component {
    bdElements() {
        return e.div({ style: { border: "1px solid black", padding: '10px' } });
    }
}

class PinkBox extends Component {
    bdElements() {
        return e.div({ style: { border: "1px solid pink", padding: '10px' } });
    }
}

class DoubleBox extends Component {
    bdElements() {
        return e.div(
            e(BlackBox,
                e(PinkBox)
            )
        )
    }
}

class Gift extends Component {
    bdElements() {
        return e.span('A Gift For You')
    }
}

class ThePackage extends Component {
    bdElements() {
        return e.div(
            e(DoubleBox,
                e(Gift)
            ),
        );
    }
}

render(ThePackage, {}, document.body);

This results in

<div>
    <div style="border: 1px solid black; padding: 10px;">
        <div style="border: 1px solid pink; padding: 10px;">
        </div>
    </div>
    <span>A Gift For You</span>
</div>

...with the gift clearly outside the boxes.

If I am only wrapping it in one box it works:

class ThePackage extends Component {
    bdElements() {
        return e.div(
            e(PinkBox,
                e(Gift)
            )
        );
    }
}

This puts the gift inside the pink box:

<div>
    <div style="border: 1px solid pink; padding: 10px;">
        <span>A Gift For You</span>
    </div>
</div>

Is there a way using DoubleBox to put another component inside the boxes?

1

There are 1 best solutions below

0
On BEST ANSWER
class ThePackage extends Component {
    bdElements() {
        return e.div(
            e(DoubleBox,
                e(Gift)
            ),
        );
    }
}

Inserts a Gift instance inside a ThePackage instance. And that is exactly what you saw in the DOM rendered.

Notice the proposed abstractions are defined in an ambiguous manner because a box (black or pink) is a thing that can contain stuff (singular or plural). And a DoubleBox is a thing that HAS two boxes. Now, the op's code wants to put stuff in the DoubleBox. Where should it go? Inside the BlackBox? Inside the PinkBox, inside the DoubleBox. The code that op thinks doesn't work actually works exactly as expected...a gift is indeed put inside the DoubleBox.

What we need is a type that has two boxes and has an interface that inserts stuff inside the inner box. Something like this:

class DoubleBox extends Component {
    bdElements() {
        return e.div(
            e(BlackBox,
                e(PinkBox, {bdAttach:'innerBox'})
            )
        )
    }
  
    addGift(...args) {
      this.innerBox.insChild(...args);
    }
}

which can be used like so...

let doubleBox = render(DoubleBox, 'root');
doubleBox.addGift(Gift, {contents:'gift in double box'});

See https://codepen.io/rcgill/pen/BaWGpqG