/* USAGE: Toggle x = components.toggle({ selected: Integer selected_index, values: Array [ { label: i18n.t("String title") } ], callback: function () { // .. on value change. }, }).get(); */ exports.toggle = function (opts) { const component = (function render_component(opts) { const _component = $("
"); if (opts.html_class) { // add a check inside passed arguments in case some extra // classes need to be added for correct alignment or other purposes _component.addClass(opts.html_class); } opts.values.forEach((value, i) => { // create a tab with a tab-id so they don't have to be referenced // by text value which can be inconsistent. const tab = $("
" + value.label + "
"); // add proper classes for styling in CSS. if (i === 0) { // this should be default selected unless otherwise specified. tab.addClass("first selected"); } else if (i === opts.values.length - 1) { tab.addClass("last"); } else { tab.addClass("middle"); } _component.append(tab); }); return _component; }(opts)); const meta = { $ind_tab: component.find(".ind-tab"), idx: -1, }; function select_tab(idx) { const elem = meta.$ind_tab.eq(idx); if (elem.hasClass('disabled')) { return; } meta.$ind_tab.removeClass("selected"); elem.addClass("selected"); meta.idx = idx; if (opts.callback) { opts.callback( opts.values[idx].label, opts.values[idx].key, ); } if (!opts.child_wants_focus) { elem.focus(); } } function maybe_go_left() { if (meta.idx > 0) { select_tab(meta.idx - 1); return true; } } function maybe_go_right() { if (meta.idx < opts.values.length - 1) { select_tab(meta.idx + 1); return true; } } (function () { meta.$ind_tab.click(function () { const idx = $(this).data("tab-id"); select_tab(idx); }); keydown_util.handle({ elem: meta.$ind_tab, handlers: { left_arrow: maybe_go_left, right_arrow: maybe_go_right, }, }); // We should arguably default opts.selected to 0. if (typeof opts.selected === "number") { select_tab(opts.selected); } }()); const prototype = { maybe_go_left: maybe_go_left, maybe_go_right: maybe_go_right, disable_tab: function (name) { const value = opts.values.find((o) => o.key === name); const idx = opts.values.indexOf(value); meta.$ind_tab.eq(idx).addClass('disabled'); }, value: function () { if (meta.idx >= 0) { return opts.values[meta.idx].label; } }, get: function () { return component; }, // go through the process of finding the correct tab for a given name, // and when found, select that one and provide the proper callback. goto: function (name) { const value = opts.values.find((o) => o.label === name || o.key === name); const idx = opts.values.indexOf(value); if (idx >= 0) { select_tab(idx); } }, }; return prototype; }; window.components = exports;