Component Composition

Nested components with configurable templates for content injection.

Live Demo

Source

HTML + JavaScript
<!-- Parent renders a list of child components -->
<div data-component="card-manager">
    <button data-action="addCard">+ Add Card</button>
    <div data-list="cards">
        <template>
            <!-- "." passes the entire list item as a prop -->
            <div data-component="info-card" data-prop-card=".">
                <div data-bind-style="borderStyle">
                    <strong data-bind="title"></strong>
                    <p data-bind="body"></p>
                </div>
            </div>
        </template>
    </div>
</div>

<script>
wildflower.component('card-manager', {
    state: {
        cards: [
            { cardTitle: 'Getting Started', cardBody: 'No build step required.', variant: '#6b996a' },
            { cardTitle: 'Components', cardBody: 'Reactive state, lifecycle, computed.', variant: '#3498db' }
        ]
    },
    addCard() {
        const colors = ['#6b996a', '#3498db', '#df9058', '#c0392b'];
        this.cards.push({
            cardTitle: 'Card ' + (this.cards.length + 1),
            cardBody: 'Added dynamically.',
            variant: colors[this.cards.length % colors.length]
        });
    }
});

wildflower.component('info-card', {
    props: { card: { default: () => ({}) } },
    computed: {
        title() { return this.props.card.cardTitle || ''; },
        body() { return this.props.card.cardBody || ''; },
        borderStyle() { return { borderLeft: '3px solid ' + (this.props.card.variant || '#999') }; }
    }
});
</script>

Key Points

  • Child components inside data-list. Each list item becomes a component instance
  • data-prop-card="." passes the entire list item object as a single prop
  • Child computed properties extract and transform prop data for bindings
  • Adding items to the parent's array creates new child instances automatically