ToolBar.tsx 5.5 KB

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