mirror of https://github.com/zulip/zulip.git
138 lines
3.8 KiB
JavaScript
138 lines
3.8 KiB
JavaScript
/* USAGE:
|
|
Toggle x = components.toggle({
|
|
selected: Integer selected_index,
|
|
values: Array<Object> [
|
|
{ label: i18n.t("String title") }
|
|
],
|
|
callback: function () {
|
|
// .. on value change.
|
|
},
|
|
}).get();
|
|
*/
|
|
|
|
exports.toggle = function (opts) {
|
|
const component = (function render_component(opts) {
|
|
const _component = $("<div class='tab-switcher'></div>");
|
|
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(function (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 = $("<div class='ind-tab' data-tab-key='" + value.key + "' data-tab-id='" + i + "' tabindex='0'>" + value.label + "</div>");
|
|
|
|
// 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;
|