UNPKG

@cbpds/react-components

Version:

React components encapsulating the CBP Design System web components.

92 lines 3.48 kB
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