@atlassian/aui
Version:
Atlassian User Interface Framework
258 lines (235 loc) • 10.6 kB
JavaScript
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(['./internal/attributes', './jquery', './internal/enforcer', './key-code', 'skatejs-template-html', './internal/skate', './internal/constants', './polyfills/custom-event', './spin', './tooltip'], factory);
} else if (typeof exports !== "undefined") {
factory(require('./internal/attributes'), require('./jquery'), require('./internal/enforcer'), require('./key-code'), require('skatejs-template-html'), require('./internal/skate'), require('./internal/constants'), require('./polyfills/custom-event'), require('./spin'), require('./tooltip'));
} else {
var mod = {
exports: {}
};
factory(global.attributes, global.jquery, global.enforcer, global.keyCode, global.skatejsTemplateHtml, global.skate, global.constants, global.customEvent, global.spin, global.tooltip);
global.toggle = mod.exports;
}
})(this, function (_attributes, _jquery, _enforcer, _keyCode, _skatejsTemplateHtml, _skate, _constants, _customEvent) {
'use strict';
var _jquery2 = _interopRequireDefault(_jquery);
var _enforcer2 = _interopRequireDefault(_enforcer);
var _keyCode2 = _interopRequireDefault(_keyCode);
var _skatejsTemplateHtml2 = _interopRequireDefault(_skatejsTemplateHtml);
var _skate2 = _interopRequireDefault(_skate);
var _customEvent2 = _interopRequireDefault(_customEvent);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function fireChangeEvent(element) {
if (element._canFireEventsNow) {
element.dispatchEvent(new _customEvent2.default('change', { bubbles: true }));
}
}
function getInput(element) {
return element._input || (element._input = element.querySelector('input'));
}
function removedAttributeHandler(attributeName, element) {
getInput(element).removeAttribute(attributeName);
}
function fallbackAttributeHandler(attributeName, element, change) {
getInput(element).setAttribute(attributeName, change.newValue);
}
function getAttributeHandler(attributeName) {
return {
removed: removedAttributeHandler.bind(this, attributeName),
fallback: fallbackAttributeHandler.bind(this, attributeName)
};
}
var formAttributeHandler = {
removed: function removed(element) {
removedAttributeHandler.call(this, 'form', element);
element._formId = null;
},
fallback: function fallback(element, change) {
fallbackAttributeHandler.call(this, 'form', element, change);
element._formId = change.newValue;
}
};
var idAttributeHandler = {
removed: removedAttributeHandler.bind(undefined, 'id'),
fallback: function fallback(element, change) {
getInput(element).setAttribute('id', '' + change.newValue + _constants.INPUT_SUFFIX);
}
};
var checkedAttributeHandler = {
removed: function removed(element) {
getInput(element).checked = false;
fireChangeEvent(element);
},
fallback: function fallback(element) {
getInput(element).checked = true;
fireChangeEvent(element);
}
};
var labelHandler = {
removed: function removed(element) {
getInput(element).removeAttribute('aria-label');
},
fallback: function fallback(element, change) {
getInput(element).setAttribute('aria-label', change.newValue);
}
};
function clickHandler(element, e) {
if (!element.disabled && !element.busy && e.target !== element._input) {
element._input.checked = !element._input.checked;
}
(0, _attributes.setBooleanAttribute)(element, 'checked', getInput(element).checked);
}
function setDisabledForLabels(element, disabled) {
if (!element.id) {
return;
}
Array.prototype.forEach.call(document.querySelectorAll('aui-label[for="' + element.id + '"]'), function (el) {
el.disabled = disabled;
});
}
/**
* Workaround to prevent pressing SPACE on busy state.
* Preventing click event still makes the toggle flip and revert back.
* So on CSS side, the input has "pointer-events: none" on busy state.
*/
function bindEventsToInput(element) {
element._input.addEventListener('keydown', function (e) {
if (element.busy && e.keyCode === _keyCode2.default.SPACE) {
e.preventDefault();
}
});
// prevent toggle can be trigger through SPACE key on Firefox
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
element._input.addEventListener('click', function (e) {
if (element.busy) {
e.preventDefault();
}
});
}
}
(0, _skate2.default)('aui-toggle', {
// "assistive" class avoids direct interaction with the <input> element
// (which prevents our click handler from being called),
// while allow the element to still participate in the form.
template: (0, _skatejsTemplateHtml2.default)('<input type="checkbox" class="aui-toggle-input assistive">', '<span class="aui-toggle-view">', '<span class="aui-toggle-tick aui-icon aui-icon-small aui-iconfont-success"></span>', '<span class="aui-toggle-cross aui-icon aui-icon-small aui-iconfont-close-dialog"></span>', '</span>'),
created: function created(element) {
element._input = getInput(element); // avoid using _input in attribute handlers
element._tick = element.querySelector('.aui-toggle-tick');
element._cross = element.querySelector('.aui-toggle-cross');
(0, _jquery2.default)(element._input).tooltip({
title: function title() {
return this.checked ? this.getAttribute('tooltip-on') : this.getAttribute('tooltip-off');
},
gravity: 's',
hoverable: false
});
bindEventsToInput(element);
if (element.hasAttribute('checked')) {
getInput(element).setAttribute('checked', '');
}
element._canFireEventsNow = true;
},
attached: function attached(element) {
(0, _enforcer2.default)(element).attributeExists('label');
},
events: {
click: clickHandler
},
attributes: {
id: idAttributeHandler,
checked: checkedAttributeHandler,
disabled: getAttributeHandler('disabled'),
form: formAttributeHandler,
name: getAttributeHandler('name'),
value: getAttributeHandler('value'),
'tooltip-on': {
value: AJS.I18n.getText('aui.toggle.on'),
fallback: function fallback(element, change) {
getInput(element).setAttribute('tooltip-on', change.newValue || AJS.I18n.getText('aui.toggle.on'));
}
},
'tooltip-off': {
value: AJS.I18n.getText('aui.toggle.off'),
fallback: function fallback(element, change) {
getInput(element).setAttribute('tooltip-off', change.newValue || AJS.I18n.getText('aui.toggle.off'));
}
},
label: labelHandler
},
prototype: {
focus: function focus() {
this._input.focus();
return this;
},
get checked() {
return this._input.checked;
},
set checked(value) {
// Need to explicitly set the property on the checkbox because the
// checkbox's property doesn't change with it's attribute after it
// is clicked.
if (this._input.checked !== value) {
this._input.checked = value;
(0, _attributes.setBooleanAttribute)(this, 'checked', value);
}
},
get disabled() {
return this._input.disabled;
},
set disabled(value) {
return (0, _attributes.setBooleanAttribute)(this, 'disabled', value);
},
get form() {
return document.getElementById(this._formId);
},
set form(value) {
formAttributeHandler.fallback.call(this, this, { newValue: value || null });
return this.form;
},
get name() {
return this._input.name;
},
set name(value) {
this.setAttribute('name', value);
return value;
},
get value() {
return this._input.value;
},
set value(value) {
// Setting the value of an input to null sets it to empty string.
this.setAttribute('value', value === null ? '' : value);
return value;
},
get busy() {
return this._input.getAttribute('aria-busy') === 'true';
},
set busy(value) {
(0, _attributes.setBooleanAttribute)(this, 'busy', value);
if (value) {
this._input.setAttribute('aria-busy', 'true');
this._input.indeterminate = true;
if (this.checked) {
(0, _jquery2.default)(this._input).addClass('indeterminate-checked');
(0, _jquery2.default)(this._tick).spin({ zIndex: null });
} else {
(0, _jquery2.default)(this._cross).spin({ zIndex: null, color: 'black' });
}
} else {
(0, _jquery2.default)(this._input).removeClass('indeterminate-checked');
this._input.indeterminate = false;
this._input.removeAttribute('aria-busy');
(0, _jquery2.default)(this._cross).spinStop();
(0, _jquery2.default)(this._tick).spinStop();
}
setDisabledForLabels(this, !!value);
return value;
}
}
});
});
//# sourceMappingURL=toggle.js.map