utils.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import React from 'react'
  2. export type AbstractNode = {
  3. name: string
  4. attributes: {
  5. [key: string]: string
  6. }
  7. children?: AbstractNode[]
  8. }
  9. export type Attrs = {
  10. [key: string]: string
  11. }
  12. export function normalizeAttrs(attrs: Attrs = {}): Attrs {
  13. return Object.keys(attrs).reduce((acc: Attrs, key) => {
  14. const val = attrs[key]
  15. key = key.replace(/([-]\w)/g, (g: string) => g[1].toUpperCase())
  16. key = key.replace(/([:]\w)/g, (g: string) => g[1].toUpperCase())
  17. switch (key) {
  18. case 'class':
  19. acc.className = val
  20. delete acc.class
  21. break
  22. case 'style':
  23. (acc.style as any) = val.split(';').reduce((prev, next) => {
  24. const pairs = next?.split(':')
  25. if (pairs[0] && pairs[1]) {
  26. const k = pairs[0].replace(/([-]\w)/g, (g: string) => g[1].toUpperCase())
  27. prev[k] = pairs[1]
  28. }
  29. return prev
  30. }, {} as Attrs)
  31. break
  32. default:
  33. acc[key] = val
  34. }
  35. return acc
  36. }, {})
  37. }
  38. export function generate(
  39. node: AbstractNode,
  40. key: string,
  41. rootProps?: { [key: string]: any } | false,
  42. ): any {
  43. if (!rootProps) {
  44. return React.createElement(
  45. node.name,
  46. { key, ...normalizeAttrs(node.attributes) },
  47. (node.children || []).map((child, index) => generate(child, `${key}-${node.name}-${index}`)),
  48. )
  49. }
  50. return React.createElement(
  51. node.name,
  52. {
  53. key,
  54. ...normalizeAttrs(node.attributes),
  55. ...rootProps,
  56. },
  57. (node.children || []).map((child, index) => generate(child, `${key}-${node.name}-${index}`)),
  58. )
  59. }