src/ToggleButton.ts

   1/**

   2 * # Button Widget

   3 * A simple button widget

   4 * 

   5 * ### Profile

   6 * invoked as `m(Button, {name:, onclick:});`

   7 * 

   8 * ### Attributes (node.attrs):

   9 * - `onclick:() => void` function to execute when button is clicked

  10 * - `name: string` name to show as button text

  11 * - `css: string` css class to assign to button tag

  12 * - `style: string` style string to apply to button tag

  13 * 

  14 * ### Example

  15 * 

  16 * 'script.js'>

  17 * let clicked = 0;

  18 * let radio = '';

  19 * let toggle = '';

  20 * 

  21 * m.mount(root, {view: () => m('.hs-white', [

  22 *    m('h4', `Please Toggle: (currently ${toggle})`),

  23 *    m(hsWidget.ToggleButton, { desc: {

  24 *        items: ['1st''2nd','3rd'],

  25 *        clicked: (item) => toggle = item

  26 *    }})

  27 * ])});

  28 * 

  29 * 

  30 * 

  31 */

  32

  33/** */

  34import { m, Vnode }                 from 'hslayout';

  35import { Selector, SelectableDesc } from './Selector';

  36

  37/**

  38 * # ToggleButton Widget

  39 * A button widget that toggle through a set of items, or states and 

  40 * shows the current state as button title

  41 * 

  42 * ### Profile

  43 * invoked as `m(ToggleButton, {desc: { items:[], clicked:}});`

  44 * 

  45 * ### Attributes (node.attrs):

  46 * - `desc:` see {@link Selector.SelectorDesc SelectorDesc}

  47 *     - `clicked:(item:string) => void` function to execute when button is selected

  48 *     - `selectedItem?: number|string` the currently selected item, by index or name

  49 *     - `items: string[]` names of individual states to toggle through

  50 *     - `itemCss?:string[]` css to apply to each item;

  51 * - `css?: string` css class to assign to button group

  52 * - `style?: string` style string to apply to button tag

  53 */

  54export class ToggleButton extends Selector {

  55    oninit(node:Vnode) {

  56        super.oninit(node);

  57        node.state.mouseDownCSS = '';

  58        node.state.events.mouseDown = () => node.state.mouseDownCSS = '.hs-button-pressed';

  59        node.state.events.mouseUp   = () => node.state.mouseDownCSS = '';

  60        // node.state.postUpdate = node.state.updateModel;

  61        node.state.itemClicked= (title:string):void => {

  62            const i = node.state.items.map((i:SelectableDesc)=> i.title).indexOf(title);

  63            const newTitle = node.state.items[(i+1) % node.state.items.length].title;

  64            node.state.items[title].isSelected = false;

  65            node.state.items[newTitle].isSelected = true;

  66            return newTitle;

  67        };

  68        Selector.ensureSelected(node);

  69    }

  70    onupdate(node: Vnode) {

  71        super.onupdate(node);

  72        Selector.ensureSelected(node);

  73    }

  74    view(node: Vnode): Vnode {

  75        const css = node.attrs.css || '';

  76        const style = node.attrs.style || '';

  77        const i = node.state.items.findIndex((i:SelectableDesc) => i.isSelected);

  78

  79        return m(`.hs-toggle-button ${css} ${node.state.mouseDownCSS}`, { style:style}, m('span'

  80            Selector.renderItem(node, i)

  81        ));

  82    }

  83}