src/Menu.ts

   1/**

   2 * # Menu Widget

   3 * Creates a simple menu with several items.

   4 * 

   5 * ### Profile

   6 * invoked as `m(Menu, { desc: })`

   7 * 

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

   9 * - `desc:` {@link Menu.MenuDesc MenuDesc}

  10 *     - `items: string[]`                  the items on the menu

  11 *     - `clicked: (item:string) => void`   called when item clicked

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

  13 *     - `itemCSS?: string[]`               css to apply to items;

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

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

  16 * - `size?: string | string[]`             sizes to layout menu items; 

  17 * 

  18 * ### Menu Example

  19 * 

  20 * 'script.js'>

  21 * const items = ['One''Two''Three'];

  22 * const content   = ['1st''2nd''3rd'];

  23 * let  theContent = content[1];

  24 * 

  25 * m.mount(root, {view: () => m(hsLayout.Layout, {

  26 *     rows:["30px""fill"],

  27 *     content:[

  28 *         m(hsWidget.Menu, {desc: {

  29 *             items: items,

  30 *             defaultItem: 'Two',

  31 *             clicked: item => 

  32 *                theContent = content[items.indexOf(item)]

  33 *         }}),

  34 *         m(hsLayout.Layout, { css:'myMain', content: theContent })

  35 *     ]

  36 * })});

  37 *

  38 * 

  39 * 'style.css'>

  40 * .myMain { 

  41 *    border:1px solid #ddd;

  42 *    border-top: 0px solid #ddd;

  43 * } 

  44 * .hs-selectable { 

  45 *     background-color: #f4f4e8; 

  46 * }

  47 * .hs-selected { 

  48 *     background-color: #eed; 

  49 *     border-width:0px;

  50 * }

  51 * 

  52 * 

  53 * 

  54 * ### MenuPanel Example

  55 * 

  56 * 'script.js'>

  57 * m.mount(root, {view: () => m(hsWidget.MenuPanel, {

  58 *    items: ["one""two""three"],  

  59 *    defaultItem: "two",

  60 *    content: ['1st''2nd''3rd']

  61 * })});

  62 *

  63 * 

  64 * 'style.css'>

  65 * .hs-menu { 

  66 *     background-color: #eef; 

  67 * } 

  68 * .hs-menu-panel { 

  69 *     background-color: #dde; 

  70 * } 

  71 * .hs-selectable { 

  72 *     background-color: #f4f4e8; 

  73 * }

  74 * .hs-selected { 

  75 *     background-color: #eed; 

  76 *     border-width:0px;

  77 * }

  78 * 

  79 * 

  80 */

  81

  82 /** */

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

  84import { Layout }       from 'hslayout';

  85import { RadioButton }  from './RadioButton';

  86

  87

  88/**

  89 * Creates a simple menu with several items, as configured by the desc:SelectorDesc object passed as a parameter. 

  90 * 

  91 * Call as: 

  92 * ```

  93 * m(Menu, {desc: {

  94 *    items: ['One''Two''Three'],

  95 *    defaultItem: 'Two',

  96 *    clicked: item => ...  // set the maoin panel content for `item`

  97 * }})

  98 * ```

  99 */

 100export class Menu extends RadioButton {

 101    view(node: Vnode): Vnode { return RadioButton.viewGroup('.hs-menu', node); }

 102}

 103

 104/**

 105 * Creates a compound horizontal menu with several items and a panel directly below the menu items.

 106 * 

 107 * Call as: 

 108 * ```

 109 * m(MenuPanel, {

 110 *    items: ['One''Two''Three'],

 111 *    defaultItem: 'Two',

 112 *    content: [

 113 *      m('div''Main One'),

 114 *      m('div''Main One'),

 115 *      m('div''Main One')

 116 *    ]

 117 * })

 118 * ```

 119 */

 120export class MenuPanel extends Layout {

 121    private selected:number;

 122    oninit(node: Vnode) {

 123        this.selected = node.attrs.items.indexOf(node.attrs.defaultItem);

 124    }

 125    view(node: Vnode): Vnode { 

 126        let items = node.attrs.items;

 127        return m(Layout, {

 128            rows:["30px""fill"],

 129            content:[

 130                m(Menu, { desc: {

 131                    items: items,

 132                    defaultItem: node.attrs.defaultItem,

 133                    clicked: (item:string) => this.selected = items.indexOf(item)

 134                }}),

 135                m(Layout, { css:'.hs-menu-panel', content: node.attrs.content[this.selected] })

 136            ]

 137        });

 138    }

 139}

 140