table.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import {useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import {COL_WIDTH_MINIMUM} from 'sentry/components/gridEditable';
  4. import type {Alignments} from 'sentry/components/gridEditable/sortLink';
  5. import {
  6. Body as _TableWrapper,
  7. Grid as _Table,
  8. GridBody,
  9. GridBodyCell,
  10. GridBodyCellStatus,
  11. GridHead,
  12. GridHeadCell,
  13. GridRow,
  14. Header,
  15. HeaderButtonContainer,
  16. HeaderTitle,
  17. } from 'sentry/components/gridEditable/styles';
  18. import {Actions} from 'sentry/views/discover/table/cellAction';
  19. interface TableProps extends React.ComponentProps<typeof _TableWrapper> {}
  20. export function Table({children, style, ...props}: TableProps) {
  21. return (
  22. <_TableWrapper {...props}>
  23. <_Table style={style}>{children}</_Table>
  24. </_TableWrapper>
  25. );
  26. }
  27. interface TableStatusProps {
  28. children: React.ReactNode;
  29. }
  30. export function TableStatus({children}: TableStatusProps) {
  31. return (
  32. <GridRow>
  33. <GridBodyCellStatus>{children}</GridBodyCellStatus>
  34. </GridRow>
  35. );
  36. }
  37. export const ALLOWED_CELL_ACTIONS: Actions[] = [
  38. Actions.ADD,
  39. Actions.EXCLUDE,
  40. Actions.SHOW_GREATER_THAN,
  41. Actions.SHOW_LESS_THAN,
  42. ];
  43. const MINIMUM_COLUMN_WIDTH = COL_WIDTH_MINIMUM;
  44. type Item = {
  45. label: React.ReactNode;
  46. value: string;
  47. width?: number | 'min-content';
  48. };
  49. interface UseTableStylesOptions {
  50. items: Item[];
  51. minimumColumnWidth?: number;
  52. }
  53. export function useTableStyles({
  54. items,
  55. minimumColumnWidth = MINIMUM_COLUMN_WIDTH,
  56. }: UseTableStylesOptions) {
  57. const tableStyles = useMemo(() => {
  58. const columns = new Array(items.length);
  59. for (let i = 0; i < items.length; i++) {
  60. if (typeof items[i].width === 'number') {
  61. columns[i] = `${items[i].width}px`;
  62. } else {
  63. columns[i] = items[i].width ?? `minmax(${minimumColumnWidth}px, auto)`;
  64. }
  65. }
  66. return {
  67. gridTemplateColumns: columns.join(' '),
  68. };
  69. }, [items, minimumColumnWidth]);
  70. return {tableStyles};
  71. }
  72. export const TableBody = GridBody;
  73. export const TableRow = GridRow;
  74. export const TableBodyCell = GridBodyCell;
  75. export const TableHead = GridHead;
  76. export const TableHeader = Header;
  77. export const TableHeaderActions = HeaderButtonContainer;
  78. export const TableHeaderTitle = HeaderTitle;
  79. export const TableHeadCell = styled(GridHeadCell)<{align?: Alignments}>`
  80. ${p => p.align && `justify-content: ${p.align};`}
  81. `;