ToolBar.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { FC, useMemo } from 'react';
  2. import Grid from '@mui/material/Grid';
  3. import Typography from '@mui/material/Typography';
  4. import IconButton from '@mui/material/IconButton';
  5. import CustomButton from '../customButton/CustomButton';
  6. import Icons from '../icons/Icons';
  7. import SearchInput from '../customInput/SearchInput';
  8. import { throwErrorForDev } from '../../utils/Common';
  9. import CustomIconButton from '../customButton/CustomIconButton';
  10. import type { ToolBarConfig, ToolBarType } from './Types';
  11. const CustomToolBar: FC<ToolBarType> = props => {
  12. const { toolbarConfigs, selected = [], hideOnDisable = false } = props;
  13. // remove hidden button
  14. const leftConfigs = useMemo(() => {
  15. return toolbarConfigs.filter(
  16. (c: ToolBarConfig) =>
  17. !c.hidden &&
  18. c.icon !== 'search' &&
  19. c.type !== 'switch' &&
  20. c.position !== 'right'
  21. );
  22. }, [toolbarConfigs]);
  23. const rightConfigs = useMemo(() => {
  24. return toolbarConfigs.filter(
  25. c => c.icon === 'search' || c.type === 'switch' || c.position === 'right'
  26. );
  27. }, [toolbarConfigs]);
  28. return (
  29. <>
  30. <Grid
  31. container
  32. role="toolbar"
  33. sx={theme => ({ marginBottom: theme.spacing(1) })}
  34. >
  35. <Grid item xs={10}>
  36. {leftConfigs.map((c, i) => {
  37. const isSelect = c.type === 'select' || c.type === 'groupSelect';
  38. if (isSelect) {
  39. return c.component;
  40. }
  41. const Icon = c.icon ? Icons[c.icon!]() : '';
  42. const disabled = c.disabled ? c.disabled(selected) : false;
  43. if (
  44. disabled && // Check if the component is disabled
  45. hideOnDisable && // Check if the component should be hidden when disabled
  46. !c.alwaysShow && // Check if the button is not marked to always be shown
  47. (typeof c.hideOnDisable === 'undefined' || c.hideOnDisable()) // Check if hideOnDisable on button is undefined or returns true
  48. ) {
  49. return null; // Return null to hide the component
  50. }
  51. // when disabled "disabledTooltip" will replace "tooltip"
  52. const tooltip =
  53. disabled && c.disabledTooltip ? c.disabledTooltip : c.tooltip;
  54. const isIcon = c.type === 'iconBtn';
  55. const btn = (
  56. <CustomButton
  57. key={i}
  58. size="small"
  59. onClick={c.onClick}
  60. startIcon={Icon}
  61. color={c.btnColor || 'primary'}
  62. disabled={disabled}
  63. // use contained variant as default
  64. variant={c.btnVariant || 'contained'}
  65. tooltip={tooltip}
  66. sx={theme => ({ marginRight: theme.spacing(0.5) })}
  67. role="button"
  68. >
  69. <Typography variant="button">{c.label}</Typography>
  70. </CustomButton>
  71. );
  72. const iconBtn = (
  73. <CustomIconButton
  74. key={i}
  75. onClick={c.onClick}
  76. tooltip={tooltip}
  77. disabled={disabled}
  78. role="button"
  79. >
  80. {Icon}
  81. </CustomIconButton>
  82. );
  83. return isIcon ? iconBtn : btn;
  84. })}
  85. </Grid>
  86. {rightConfigs.length > 0 && (
  87. <Grid
  88. item
  89. xs={2}
  90. sx={{
  91. display: 'flex',
  92. justifyContent: 'flex-end',
  93. alignItems: 'center',
  94. }}
  95. >
  96. {rightConfigs.map((c, i) => {
  97. if (c.icon === 'search') {
  98. if (!c.onSearch) {
  99. return throwErrorForDev(
  100. `if icon is search onSearch event handler is required`
  101. );
  102. }
  103. return (
  104. <SearchInput
  105. onClear={c.onClear}
  106. onSearch={c.onSearch}
  107. searchText={c.searchText}
  108. placeholder={c.placeholder}
  109. key={i}
  110. />
  111. );
  112. }
  113. switch (c.type) {
  114. case 'select':
  115. case 'groupSelect':
  116. if (!c.component) {
  117. return throwErrorForDev(`component prop is required`);
  118. }
  119. return c.component;
  120. default:
  121. const Icon = c.icon ? Icons[c.icon]() : '';
  122. return Icon ? (
  123. <IconButton onClick={c.onClick} key={i} size="large">
  124. {Icon}
  125. </IconButton>
  126. ) : (
  127. <div key={i}>Need Icon</div>
  128. );
  129. }
  130. })}
  131. </Grid>
  132. )}
  133. </Grid>
  134. </>
  135. );
  136. };
  137. export default CustomToolBar;