Image.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Copyright 2023 Avaiga Private Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  5. * the License. You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  10. * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  11. * specific language governing permissions and limitations under the License.
  12. */
  13. import React, { useCallback, useEffect, useMemo, useRef } from "react";
  14. import axios from "axios";
  15. import Button from "@mui/material/Button";
  16. import Tooltip from "@mui/material/Tooltip";
  17. import { createSendActionNameAction } from "../../context/taipyReducers";
  18. import { useClassNames, useDispatch, useDynamicProperty, useModule } from "../../utils/hooks";
  19. import { TaipyActiveProps } from "./utils";
  20. interface ImageProps extends TaipyActiveProps {
  21. onAction?: string;
  22. label?: string;
  23. defaultLabel?: string;
  24. width?: string | number;
  25. height?: string | number;
  26. content?: string;
  27. defaultContent: string;
  28. }
  29. const Image = (props: ImageProps) => {
  30. const { id, onAction, width = 300, height } = props;
  31. const dispatch = useDispatch();
  32. const divRef = useRef<HTMLDivElement>(null);
  33. const module = useModule();
  34. const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);
  35. const active = useDynamicProperty(props.active, props.defaultActive, true);
  36. const hover = useDynamicProperty(props.hoverText, props.defaultHoverText, undefined);
  37. const label = useDynamicProperty(props.label, props.defaultLabel, undefined);
  38. const content = useDynamicProperty(props.content, props.defaultContent, "");
  39. const handleClick = useCallback(() => {
  40. if (onAction) {
  41. dispatch(createSendActionNameAction(id, module, onAction));
  42. }
  43. }, [id, onAction, dispatch, module]);
  44. const [svg, svgContent, inlineSvg] = useMemo(() => {
  45. const p = (content || "").trim();
  46. if (p.length > 3) {
  47. const svgFile = p.substring(p.length - 4).toLowerCase() === ".svg";
  48. const svgXml = p.substring(0, 4).toLowerCase() === "<svg";
  49. return [svgFile && content, svgXml && content, svgFile || svgXml];
  50. }
  51. return [undefined, undefined, false];
  52. }, [content]);
  53. const style = useMemo(() => ({
  54. width: width,
  55. height: height,
  56. display: inlineSvg ? "inline-flex" : undefined,
  57. verticalAlign: inlineSvg ? "middle" : undefined
  58. }), [width, height, inlineSvg]);
  59. useEffect(() => {
  60. if (svg) {
  61. axios.get<string>(svg).then((response) => divRef.current && (divRef.current.innerHTML = response.data));
  62. } else if (svgContent && divRef.current) {
  63. divRef.current.innerHTML = svgContent;
  64. }
  65. }, [svg, svgContent]);
  66. return (
  67. <Tooltip title={hover || label}>
  68. {onAction ? (
  69. <Button
  70. id={id}
  71. className={className}
  72. onClick={handleClick}
  73. aria-label={label}
  74. variant="outlined"
  75. disabled={!active}
  76. title={label}
  77. >
  78. {inlineSvg ? (
  79. <div ref={divRef} style={style} />
  80. ) : (
  81. <img src={content} style={style} alt={label} />
  82. )}
  83. </Button>
  84. ) : inlineSvg ? (
  85. <div id={id} className={className} style={style} ref={divRef} title={label}></div>
  86. ) : (
  87. <img id={id} src={content} style={style} className={className} alt={label} />
  88. )}
  89. </Tooltip>
  90. );
  91. };
  92. export default Image;