arrayLinks.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import {useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import {LocationDescriptor} from 'history';
  4. import Link from 'sentry/components/links/link';
  5. import {t} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. type Item = {
  8. target: LocationDescriptor;
  9. value: string;
  10. onClick?: () => void;
  11. };
  12. interface ArrayLinksProps {
  13. items: Item[];
  14. }
  15. function ArrayLinks({items}: ArrayLinksProps) {
  16. const [expanded, setExpanded] = useState(false);
  17. const firstItem = items[0];
  18. return (
  19. <ArrayContainer expanded={expanded}>
  20. {firstItem && <LinkedItem item={firstItem} />}
  21. {items.length > 1 &&
  22. expanded &&
  23. items
  24. .slice(1, items.length)
  25. .map(item => <LinkedItem key={item.value} item={item} />)}
  26. {items.length > 1 ? (
  27. <ButtonContainer>
  28. <button onClick={() => setExpanded(!expanded)}>
  29. {expanded ? t('[collapse]') : t('[+%s more]', items.length - 1)}
  30. </button>
  31. </ButtonContainer>
  32. ) : null}
  33. </ArrayContainer>
  34. );
  35. }
  36. function LinkedItem({item}: {item: Item}) {
  37. return (
  38. <ArrayItem>
  39. <Link to={item.target} onClick={item?.onClick}>
  40. {item.value}
  41. </Link>
  42. </ArrayItem>
  43. );
  44. }
  45. const ArrayContainer = styled('div')<{expanded: boolean}>`
  46. display: flex;
  47. flex-direction: ${p => (p.expanded ? 'column' : 'row')};
  48. `;
  49. const ArrayItem = styled('span')`
  50. flex-shrink: 1;
  51. display: block;
  52. ${p => p.theme.overflowEllipsis};
  53. width: unset;
  54. `;
  55. const ButtonContainer = styled('div')`
  56. white-space: nowrap;
  57. & button {
  58. background: none;
  59. border: 0;
  60. outline: none;
  61. padding: 0;
  62. cursor: pointer;
  63. color: ${p => p.theme.linkColor};
  64. margin-left: ${space(0.5)};
  65. }
  66. `;
  67. export {ArrayLinks};