index.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import {Children, cloneElement, isValidElement} from 'react';
  2. import styled from '@emotion/styled';
  3. import space from 'sentry/styles/space';
  4. import {getListSymbolStyle, listSymbol} from './utils';
  5. type Props = {
  6. children: React.ReactNode;
  7. className?: string;
  8. 'data-test-id'?: string;
  9. initialCounterValue?: number;
  10. symbol?: keyof typeof listSymbol | React.ReactElement;
  11. };
  12. const List = styled(
  13. ({
  14. children,
  15. className,
  16. symbol,
  17. initialCounterValue: _initialCounterValue,
  18. ...props
  19. }: Props) => {
  20. const getWrapperComponent = () => {
  21. switch (symbol) {
  22. case 'numeric':
  23. case 'colored-numeric':
  24. return 'ol';
  25. default:
  26. return 'ul';
  27. }
  28. };
  29. const Wrapper = getWrapperComponent();
  30. return (
  31. <Wrapper className={className} {...props}>
  32. {!symbol || typeof symbol === 'string'
  33. ? children
  34. : Children.map(children, child => {
  35. if (!isValidElement(child)) {
  36. return child;
  37. }
  38. return cloneElement(child as React.ReactElement, {
  39. symbol,
  40. });
  41. })}
  42. </Wrapper>
  43. );
  44. }
  45. )`
  46. margin: 0;
  47. padding: 0;
  48. list-style: none;
  49. display: grid;
  50. grid-template-columns: minmax(0, 1fr);
  51. gap: ${space(0.5)};
  52. ${p =>
  53. typeof p.symbol === 'string' &&
  54. listSymbol[p.symbol] &&
  55. getListSymbolStyle(p.theme, p.symbol, p.initialCounterValue)}
  56. `;
  57. export default List;