@cbpds/react-components
Version:
React components encapsulating the CBP Design System web components.
92 lines • 3.48 kB
JavaScript
import { camelToDashCase } from './case';
export const attachProps = (node, newProps, oldProps = {}) => {
if (node instanceof Element) {
const className = getClassName(node.classList, newProps, oldProps);
if (className !== '') {
node.className = className;
}
Object.keys(newProps).forEach((name) => {
if (name === 'children' ||
name === 'style' ||
name === 'ref' ||
name === 'class' ||
name === 'className' ||
name === 'forwardedRef') {
return;
}
if (name.indexOf('on') === 0 && name[2] === name[2].toUpperCase()) {
const eventName = name.substring(2);
const eventNameLc = eventName[0].toLowerCase() + eventName.substring(1);
if (!isCoveredByReact(eventNameLc)) {
syncEvent(node, eventNameLc, newProps[name]);
}
}
else {
node[name] = newProps[name];
const propType = typeof newProps[name];
if (propType === 'string') {
node.setAttribute(camelToDashCase(name), newProps[name]);
}
}
});
}
};
export const getClassName = (classList, newProps, oldProps) => {
const newClassProp = newProps.className || newProps.class;
const oldClassProp = oldProps.className || oldProps.class;
const currentClasses = arrayToMap(classList);
const incomingPropClasses = arrayToMap(newClassProp ? newClassProp.split(' ') : []);
const oldPropClasses = arrayToMap(oldClassProp ? oldClassProp.split(' ') : []);
const finalClassNames = [];
currentClasses.forEach((currentClass) => {
if (incomingPropClasses.has(currentClass)) {
finalClassNames.push(currentClass);
incomingPropClasses.delete(currentClass);
}
else if (!oldPropClasses.has(currentClass)) {
finalClassNames.push(currentClass);
}
});
incomingPropClasses.forEach((s) => finalClassNames.push(s));
return finalClassNames.join(' ');
};
export const transformReactEventName = (eventNameSuffix) => {
switch (eventNameSuffix) {
case 'doubleclick':
return 'dblclick';
}
return eventNameSuffix;
};
export const isCoveredByReact = (eventNameSuffix) => {
if (typeof document === 'undefined') {
return true;
}
else {
const eventName = 'on' + transformReactEventName(eventNameSuffix);
let isSupported = eventName in document;
if (!isSupported) {
const element = document.createElement('div');
element.setAttribute(eventName, 'return;');
isSupported = typeof element[eventName] === 'function';
}
return isSupported;
}
};
export const syncEvent = (node, eventName, newEventHandler) => {
const eventStore = node.__events || (node.__events = {});
const oldEventHandler = eventStore[eventName];
if (oldEventHandler) {
node.removeEventListener(eventName, oldEventHandler);
}
node.addEventListener(eventName, (eventStore[eventName] = function handler(e) {
if (newEventHandler) {
newEventHandler.call(this, e);
}
}));
};
const arrayToMap = (arr) => {
const map = new Map();
arr.forEach((s) => map.set(s, s));
return map;
};
//# sourceMappingURL=attachProps.js.map