form-text.tsx 1.9 KB

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