Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.00 KB | None | 0 0
  1. import React, { FunctionComponent, ReactChild } from 'react'
  2.  
  3. const listeners = Symbol('jsx-web-comp/event-listeners')
  4. const eventPattern = /^onEvent/
  5.  
  6. const toKebabCase = (str: string) => str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase()
  7.  
  8. export default function jsx (type: string | FunctionComponent, props: Record<string, any>, ...children: ReactChild[]) {
  9. const isCustomElement = customElements.get(type as string)
  10. const newProps = { ...props }
  11.  
  12. if (typeof type === 'string' && isCustomElement) {
  13. newProps.ref = (element: any) => {
  14. if (element) {
  15. if (props) {
  16. /** Map custom events as objects (must have onEvent prefix) */
  17. const events = Object.entries(props).filter(([k, v]) => k.match(eventPattern)).map(([k, v]) => ({ [k]: v }))
  18. /** Get only the complex props (objects and arrays) */
  19. const complexProps = Object.entries(props).filter(([k, v]) => typeof v === 'object').map(([k, v]) => ({ [k]: v }))
  20.  
  21. for (const event of events) {
  22. const [key, impl] = Object.entries(event)[0]
  23. const eventName = toKebabCase(
  24. key.replace('onEvent', '')
  25. ).replace('-', '')
  26.  
  27. /** Add the listeners Map if not present */
  28. if (!element[listeners]) {
  29. element[listeners] = new Map()
  30. }
  31. /** If the listener hasn't be attached, attach it */
  32. if (!element[listeners].has(eventName)) {
  33. element.addEventListener(eventName, impl)
  34. /** Save a reference to avoid listening to the same value twice */
  35. element[listeners].set(eventName, impl)
  36. delete newProps[key]
  37. }
  38. }
  39.  
  40. for (const prop of complexProps) {
  41. const [key, value] = Object.entries(prop)[0]
  42. delete newProps[key] // remove the complex prop from props
  43. element[key] = value
  44. }
  45. }
  46. }
  47. }
  48. }
  49. return React.createElement.apply(null, [type, newProps, ...children])
  50. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement