form-text.tsx 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { Form, FormTextProps as BS5FormTextProps } from 'react-bootstrap'
  2. import MaterialIcon from '@/shared/components/material-icon'
  3. import classnames from 'classnames'
  4. import { MergeAndOverride } from '../../../../../types/utils'
  5. type TextType = 'default' | 'info' | 'success' | 'warning' | 'error'
  6. export type FormTextProps = MergeAndOverride<
  7. BS5FormTextProps,
  8. {
  9. type?: TextType
  10. }
  11. >
  12. const typeClassMap: Partial<Record<TextType, string>> = {
  13. error: 'text-danger',
  14. success: 'text-success',
  15. warning: 'text-warning',
  16. }
  17. export const getFormTextClass = (type?: TextType) =>
  18. typeClassMap[type || 'default']
  19. function FormTextIcon({ type }: { type?: TextType }) {
  20. switch (type) {
  21. case 'info':
  22. return <MaterialIcon type="info" className="text-info" />
  23. case 'success':
  24. return <MaterialIcon type="check_circle" />
  25. case 'warning':
  26. return <MaterialIcon type="warning" />
  27. case 'error':
  28. return <MaterialIcon type="error" />
  29. default:
  30. return null
  31. }
  32. }
  33. function FormText({
  34. type = 'default',
  35. children,
  36. className,
  37. ...rest
  38. }: FormTextProps) {
  39. return (
  40. <Form.Text
  41. className={classnames(className, getFormTextClass(type))}
  42. {...rest}
  43. >
  44. <span className="form-text-inner">
  45. <FormTextIcon type={type} />
  46. {children}
  47. </span>
  48. </Form.Text>
  49. )
  50. }
  51. export default FormText