Produce

Nothing here is new. Produce composes Switch, Filter, Val, and a small script that runs on load. Each was shown on its own. Here they work together.

    <div produce-space filter-space switch-space switch-state="category">
        <div>
            <input filter-query type="text" oninput="Filter.Filter(this)">
            <button onclick="Switch.Toggle(this, '[switch-space]', 'category', 'hidden', 'category')">
                <span switch-tag="category">Hide category</span>
                <span switch-tag="hidden" style="display:none">Show category</span>
            </button>
        </div>
        <ul produce-list val-tpl="[produce-row-tpl]"></ul>
        <template produce-row-tpl>
            <li filter-item>
                <i val val-fx="Pattr" val-key="match" val-attr="filter-item" hidden></i>
                <span val val-fx="Text" val-key="name"></span>
                <span val val-fx="Text" val-key="category" switch-tag="category"></span>
            </li>
        </template>
        <script>
            Produce.Init(document.currentScript, [
                { name: 'Apple',  category: 'Fruit' },
                { name: 'Banana', category: 'Fruit' },
                { name: 'Cherry', category: 'Fruit' },
                { name: 'Carrot', category: 'Vegetable' },
                { name: 'Potato', category: 'Vegetable' },
            ]);
        </script>
    </div>
    const Produce = (() => {
        const Init = (ctx, items) => {
            const space = ctx.up('[produce-space]');
            space.one('[produce-list]')
                .vappend(items.map(p => ({ ...p, match: `${p.name} ${p.category}` })), space.one('[produce-row-tpl]'));
        };
    
        return { Init };
    })();

    Next: Tic-tac-toe →