Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

Spinner.tsx 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import { keyframes } from '@emotion/react';
  21. import styled from '@emotion/styled';
  22. import classNames from 'classnames';
  23. import * as React from 'react';
  24. import { useIntl } from 'react-intl';
  25. import tw from 'twin.macro';
  26. import { themeColor } from '../helpers/theme';
  27. interface Props {
  28. ariaLabel?: string;
  29. className?: string;
  30. customSpinner?: JSX.Element;
  31. loading?: boolean;
  32. placeholder?: boolean;
  33. }
  34. /** @deprecated Use Spinner from Echoes instead.
  35. *
  36. * Some of the props have changed or been renamed:
  37. * - ~`customSpinner`~ has been removed
  38. * - `loading` is now `isLoading`
  39. * - `placeholder` is now `hasPlaceholder`
  40. */
  41. export function Spinner(props: React.PropsWithChildren<Props>) {
  42. const intl = useIntl();
  43. const {
  44. customSpinner,
  45. className,
  46. children,
  47. placeholder,
  48. ariaLabel = intl.formatMessage({ id: 'loading' }),
  49. loading = true,
  50. } = props;
  51. if (customSpinner) {
  52. return <>{loading ? customSpinner : children}</>;
  53. }
  54. return (
  55. // Below: using <></> won't work in extenstions ('React' is not defined). This is because the
  56. // name 'React' would already have been minified to something else when <> is resolved to
  57. // React.Fragment
  58. // eslint-disable-next-line react/jsx-fragments
  59. <React.Fragment>
  60. <div className="sw-relative">
  61. <div
  62. className={classNames('sw-overflow-hidden', {
  63. 'sw-sr-only': !loading,
  64. it__loading: loading,
  65. })}
  66. >
  67. <StyledSpinner aria-live="polite" className={className} role="status">
  68. {loading && <span className="sw-sr-only">{ariaLabel}</span>}
  69. </StyledSpinner>
  70. </div>
  71. </div>
  72. {!loading && (children ?? (placeholder && <Placeholder className={className} />) ?? null)}
  73. </React.Fragment>
  74. );
  75. }
  76. const spinAnimation = keyframes`
  77. from {
  78. transform: rotate(0deg);
  79. }
  80. to {
  81. transform: rotate(-360deg);
  82. }
  83. `;
  84. const StyledSpinner = styled.div`
  85. border: 2px solid transparent;
  86. background:
  87. linear-gradient(0deg, ${themeColor('primary')} 50%, transparent 50% 100%) border-box,
  88. linear-gradient(90deg, ${themeColor('primary')} 25%, transparent 75% 100%) border-box;
  89. mask:
  90. linear-gradient(#fff 0 0) padding-box,
  91. linear-gradient(#fff 0 0);
  92. -webkit-mask-composite: xor;
  93. mask-composite: exclude;
  94. animation: ${spinAnimation} 1s infinite linear;
  95. ${tw`sw-h-4 sw-w-4`};
  96. ${tw`sw-inline-block`};
  97. ${tw`sw-box-border`};
  98. ${tw`sw-rounded-pill`}
  99. `;
  100. const Placeholder = styled.div`
  101. position: relative;
  102. visibility: hidden;
  103. ${tw`sw-inline-flex sw-items-center sw-justify-center`};
  104. ${tw`sw-h-4 sw-w-4`};
  105. `;