@gitlab/ui
Version:
GitLab UI Components
147 lines (128 loc) • 4.29 kB
JavaScript
import { COMMA, labelColorOptions, focusableTags } from './constants';
function debounceByAnimationFrame(fn) {
let requestId;
return function debounced() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (requestId) {
window.cancelAnimationFrame(requestId);
}
requestId = window.requestAnimationFrame(() => fn.apply(this, args));
};
}
function throttle(fn) {
let frameId = null;
return function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
if (frameId) {
return;
}
frameId = window.requestAnimationFrame(() => {
fn(...args);
frameId = null;
});
};
}
function rgbFromHex(hex) {
const cleanHex = hex.replace('#', '');
const rgb = cleanHex.length === 3 ? cleanHex.split('').map(val => val + val) : cleanHex.match(/[\da-f]{2}/gi);
const [r, g, b] = rgb.map(val => parseInt(val, 16));
return [r, g, b];
}
function rgbFromString(color, sub) {
const rgb = color.substring(sub, color.length - 1).split(COMMA);
const [r, g, b] = rgb.map(i => parseInt(i, 10));
return [r, g, b];
}
function hexToRgba(hex) {
let opacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
const [r, g, b] = rgbFromHex(hex);
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
}
function colorFromBackground(backgroundColor) {
let r;
let g;
let b;
if (backgroundColor.startsWith('#')) {
[r, g, b] = rgbFromHex(backgroundColor);
} else if (backgroundColor.startsWith('rgba(')) {
[r, g, b] = rgbFromString(backgroundColor, 5);
} else if (backgroundColor.startsWith('rgb(')) {
[r, g, b] = rgbFromString(backgroundColor, 4);
}
if (r + g + b <= 500) {
return labelColorOptions.light;
}
return labelColorOptions.dark;
}
function uid() {
return Math.random().toString(36).substring(2);
}
/**
* Receives an element and validates that it can be focused
* @param { HTMLElement } The element we want to validate
* @return { boolean } Is the element focusable
*/
function isElementFocusable(elt) {
if (!elt) return false;
const {
tagName
} = elt;
const isValidTag = focusableTags.includes(tagName);
const hasValidType = elt.getAttribute('type') !== 'hidden';
const isDisabled = elt.getAttribute('disabled') === '' || elt.getAttribute('disabled');
const hasValidZIndex = elt.getAttribute('z-index') !== '-1';
const isInvalidAnchorTag = tagName === 'A' && !elt.getAttribute('href');
return isValidTag && hasValidType && !isDisabled && hasValidZIndex && !isInvalidAnchorTag;
}
/**
* Receives an array of HTML elements and focus the first one possible
* @param { Array.<HTMLElement> } An array of element to potentially focus
* @return { undefined }
*/
function focusFirstFocusableElement(elts) {
const focusableElt = elts.find(el => isElementFocusable(el));
if (focusableElt) focusableElt.focus();
}
/**
* Returns true if the current environment is considered a development environment (it's not
* production or test).
*
* @returns {boolean}
*/
function isDev() {
return !['test', 'production'].includes(process.env.NODE_ENV);
}
/**
* Prints a warning message to the console in non-test and non-production environments.
* @param {string} message message to print to the console
*/
function logWarning() {
let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
if (message.length && isDev()) {
console.warn(message); // eslint-disable-line no-console
}
}
/**
* Stop default event handling and propagation
*/
function stopEvent(event) {
let {
preventDefault = true,
stopPropagation = true,
stopImmediatePropagation = false
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (preventDefault) {
event.preventDefault();
}
if (stopPropagation) {
event.stopPropagation();
}
if (stopImmediatePropagation) {
event.stopImmediatePropagation();
}
}
export { colorFromBackground, debounceByAnimationFrame, focusFirstFocusableElement, hexToRgba, isDev, isElementFocusable, logWarning, rgbFromHex, rgbFromString, stopEvent, throttle, uid };