form.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import Button from '@/app/components/base/button'
  2. import Input from '@/app/components/base/input'
  3. import Textarea from '@/app/components/base/textarea'
  4. import { useChatContext } from '@/app/components/base/chat/chat/context'
  5. enum DATA_FORMAT {
  6. TEXT = 'text',
  7. JSON = 'json',
  8. }
  9. enum SUPPORTED_TAGS {
  10. LABEL = 'label',
  11. INPUT = 'input',
  12. TEXTAREA = 'textarea',
  13. BUTTON = 'button',
  14. }
  15. enum SUPPORTED_TYPES {
  16. TEXT = 'text',
  17. PASSWORD = 'password',
  18. EMAIL = 'email',
  19. NUMBER = 'number',
  20. }
  21. const MarkdownForm = ({ node }: any) => {
  22. // const supportedTypes = ['text', 'password', 'email', 'number']
  23. // <form data-format="text">
  24. // <label for="username">Username:</label>
  25. // <input type="text" name="username" />
  26. // <label for="password">Password:</label>
  27. // <input type="password" name="password" />
  28. // <label for="content">Content:</label>
  29. // <textarea name="content"></textarea>
  30. // <button data-size="small" data-variant="primary">Login</button>
  31. // </form>
  32. const { onSend } = useChatContext()
  33. const getFormValues = (children: any) => {
  34. const formValues: { [key: string]: any } = {}
  35. children.forEach((child: any) => {
  36. if (child.tagName === SUPPORTED_TAGS.INPUT)
  37. formValues[child.properties.name] = child.properties.value
  38. if (child.tagName === SUPPORTED_TAGS.TEXTAREA)
  39. formValues[child.properties.name] = child.properties.value
  40. })
  41. return formValues
  42. }
  43. const onSubmit = (e: any) => {
  44. e.preventDefault()
  45. const format = node.properties.dataFormat || DATA_FORMAT.TEXT
  46. const result = getFormValues(node.children)
  47. if (format === DATA_FORMAT.JSON) {
  48. onSend?.(JSON.stringify(result))
  49. }
  50. else {
  51. const textResult = Object.entries(result)
  52. .map(([key, value]) => `${key}: ${value}`)
  53. .join('\n')
  54. onSend?.(textResult)
  55. }
  56. }
  57. return (
  58. <form
  59. autoComplete="off"
  60. className='flex flex-col self-stretch'
  61. onSubmit={(e: any) => {
  62. e.preventDefault()
  63. e.stopPropagation()
  64. }}
  65. >
  66. {node.children.filter((i: any) => i.type === 'element').map((child: any, index: number) => {
  67. if (child.tagName === SUPPORTED_TAGS.LABEL) {
  68. return (
  69. <label
  70. key={index}
  71. htmlFor={child.properties.for}
  72. className="my-2 system-md-semibold text-text-secondary"
  73. >
  74. {child.children[0]?.value || ''}
  75. </label>
  76. )
  77. }
  78. if (child.tagName === SUPPORTED_TAGS.INPUT) {
  79. if (Object.values(SUPPORTED_TYPES).includes(child.properties.type)) {
  80. return (
  81. <Input
  82. key={index}
  83. type={child.properties.type}
  84. name={child.properties.name}
  85. placeholder={child.properties.placeholder}
  86. value={child.properties.value}
  87. onChange={(e) => {
  88. e.preventDefault()
  89. child.properties.value = e.target.value
  90. }}
  91. />
  92. )
  93. }
  94. else {
  95. return <p key={index}>Unsupported input type: {child.properties.type}</p>
  96. }
  97. }
  98. if (child.tagName === SUPPORTED_TAGS.TEXTAREA) {
  99. return (
  100. <Textarea
  101. key={index}
  102. name={child.properties.name}
  103. placeholder={child.properties.placeholder}
  104. value={child.properties.value}
  105. onChange={(e) => {
  106. e.preventDefault()
  107. child.properties.value = e.target.value
  108. }}
  109. />
  110. )
  111. }
  112. if (child.tagName === SUPPORTED_TAGS.BUTTON) {
  113. const variant = child.properties.dataVariant
  114. const size = child.properties.dataSize
  115. return (
  116. <Button
  117. variant={variant}
  118. size={size}
  119. className='mt-4'
  120. key={index}
  121. onClick={onSubmit}
  122. >
  123. <span className='text-[13px]'>{child.children[0]?.value || ''}</span>
  124. </Button>
  125. )
  126. }
  127. return <p key={index}>Unsupported tag: {child.tagName}</p>
  128. })}
  129. </form>
  130. )
  131. }
  132. MarkdownForm.displayName = 'MarkdownForm'
  133. export default MarkdownForm