form-text.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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. marginless?: boolean
  11. }
  12. >
  13. const typeClassMap: Partial<Record<TextType, string>> = {
  14. error: 'text-danger',
  15. success: 'text-success',
  16. warning: 'text-warning',
  17. }
  18. export const getFormTextClass = (type?: TextType) =>
  19. typeClassMap[type || 'default']
  20. function FormTextIcon({ type }: { type?: TextType }) {
  21. switch (type) {
  22. case 'info':
  23. return <MaterialIcon type="info" className="text-info" />
  24. case 'success':
  25. return <MaterialIcon type="check_circle" />
  26. case 'warning':
  27. return <MaterialIcon type="warning" />
  28. case 'error':
  29. return <MaterialIcon type="error" />
  30. default:
  31. return null
  32. }
  33. }
  34. function FormText({
  35. type = 'default',
  36. marginless,
  37. children,
  38. className,
  39. ...rest
  40. }: FormTextProps) {
  41. return (
  42. <Form.Text
  43. className={classnames(className, getFormTextClass(type), { marginless })}
  44. {...rest}
  45. >
  46. <span className="form-text-inner">
  47. <FormTextIcon type={type} />
  48. <span>{children}</span>
  49. </span>
  50. </Form.Text>
  51. )
  52. }
  53. export default FormText