mockup.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. 'use client'
  2. import { View, Row } from 'app/design/view'
  3. import { Text } from 'app/design/typography'
  4. import { NeoButton, NeoButtonLink } from 'app/design/controls'
  5. import { Icon } from 'app/ui/atoms/icon'
  6. import Image from 'app/ui/atoms/image'
  7. import { BlockWrapper } from 'app/components/block-wrapper'
  8. import { isMockupEmpty, parseMockup } from 'app/lib/mockup-parse'
  9. function MockupNode({ node }) {
  10. if (!node) return null
  11. const { type, className } = node
  12. const children = Array.isArray(node.children)
  13. ? node.children.map((child, index) => (
  14. <MockupNode key={child.id || index} node={child} />
  15. ))
  16. : null
  17. if (type === 'text') {
  18. return <Text className={className || 'text-foreground'}>{node.text}</Text>
  19. }
  20. if (type === 'icon') {
  21. return <Icon icon={node.icon} size={node.size || 24} className={className} />
  22. }
  23. if (type === 'image') {
  24. return (
  25. <Image
  26. src={node.src}
  27. alt={node.alt || ''}
  28. className={className || 'w-full h-48 rounded-xl'}
  29. />
  30. )
  31. }
  32. if (type === 'button') {
  33. if (node.href) {
  34. return <NeoButtonLink href={node.href} style={node.style} label={node.label} className={className} />
  35. }
  36. return <NeoButton style={node.style} label={node.label} className={className} />
  37. }
  38. if (type === 'row') {
  39. return <Row className={className}>{children}</Row>
  40. }
  41. return <View className={className}>{children}</View>
  42. }
  43. export default function ElementMockup(props) {
  44. const tree = parseMockup(props.data ?? props.content ?? props)
  45. if (!tree) return null
  46. return (
  47. <BlockWrapper {...props.blockWrapperProps}>
  48. <MockupNode node={tree} />
  49. </BlockWrapper>
  50. )
  51. }
  52. ElementMockup.checkEmpty = (item) => !isMockupEmpty(item)