{"version":3,"file":"VizLegendTable.mjs","sources":["../../../../src/components/VizLegend/VizLegendTable.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { useMemo, type JSX } from 'react';\n\nimport { type GrafanaTheme2 } from '@grafana/data';\nimport { Trans } from '@grafana/i18n';\nimport { type LegendPlacement } from '@grafana/schema';\n\nimport { useStyles2 } from '../../themes/ThemeContext';\nimport { Button } from '../Button/Button';\nimport { Icon } from '../Icon/Icon';\nimport { useLimit } from '../List/hooks';\n\nimport { LegendTableItem } from './VizLegendTableItem';\nimport { type VizLegendItem, type VizLegendTableProps } from './types';\n\nconst nameSortKey = 'Name';\nconst naturalCompare = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }).compare;\n\n/**\n * @internal\n */\nexport const VizLegendTable = <T extends unknown>({\n  items,\n  sortBy: sortKey,\n  sortDesc,\n  itemRenderer,\n  className,\n  onToggleSort,\n  onLabelClick,\n  onLabelMouseOver,\n  onLabelMouseOut,\n  readonly,\n  isSortable,\n  limit = 0,\n  filterAction,\n  placement,\n  overflow,\n}: VizLegendTableProps<T>): JSX.Element => {\n  const styles = useStyles2(getStyles, placement);\n  const header: Record<string, string> = {\n    [nameSortKey]: '',\n  };\n\n  for (const item of items) {\n    if (item.getDisplayValues) {\n      for (const displayValue of item.getDisplayValues()) {\n        header[displayValue.title ?? '?'] = displayValue.description ?? '';\n      }\n    }\n  }\n\n  if (sortKey != null) {\n    let itemVals = new Map<VizLegendItem, number>();\n\n    items.forEach((item) => {\n      if (sortKey !== nameSortKey && item.getDisplayValues) {\n        const stat = item.getDisplayValues().find((stat) => stat.title === sortKey);\n        const val = stat == null || Number.isNaN(stat.numeric) ? -Infinity : stat.numeric;\n        itemVals.set(item, val);\n      }\n    });\n\n    let sortMult = sortDesc ? -1 : 1;\n\n    if (sortKey === nameSortKey) {\n      items.sort((a, b) => {\n        return sortMult * naturalCompare(a.label, b.label);\n      });\n    } else {\n      items.sort((a, b) => {\n        const aVal = itemVals.get(a) ?? 0;\n        const bVal = itemVals.get(b) ?? 0;\n\n        return sortMult * (aVal - bVal);\n      });\n    }\n  }\n\n  const [curLimit, setLimit] = useLimit(limit);\n\n  const limitedItems = useMemo(() => (curLimit > 0 ? items.slice(0, curLimit) : items), [items, curLimit]);\n\n  const hasMixedAxes = useMemo(() => {\n    const firstYAxis = items[0]?.yAxis ?? 1;\n    return items.some((item) => item.yAxis !== firstYAxis);\n  }, [items]);\n\n  if (!itemRenderer) {\n    /* eslint-disable-next-line react/display-name */\n    itemRenderer = (item, index) => (\n      <LegendTableItem\n        key={`${item.label}-${index}`}\n        item={item}\n        onLabelClick={onLabelClick}\n        onLabelMouseOver={onLabelMouseOver}\n        onLabelMouseOut={onLabelMouseOut}\n        readonly={readonly}\n        hasMixedAxes={hasMixedAxes}\n        overflow={overflow}\n      />\n    );\n  }\n\n  return (\n    <>\n      <table\n        className={cx(styles.grid, className)}\n        style={{\n          gridTemplateColumns: `min-content minmax(55px, auto) ${'min-content '.repeat(Object.keys(header).length - 1)}`,\n        }}\n      >\n        <thead className={styles.header}>\n          <tr>\n            <th>\n              <span className=\"sr-only\">\n                <Trans i18nKey={'legend.container.series-color-and-icon'}>Series color</Trans>\n              </span>\n            </th>\n            {Object.keys(header).map((columnTitle, i) => (\n              <th\n                {...(sortKey === columnTitle ? { 'aria-sort': sortDesc ? 'descending' : 'ascending' } : null)}\n                title={header[columnTitle]}\n                key={columnTitle}\n                className={cx({\n                  [styles.headerSortable]: Boolean(onToggleSort),\n                  [styles.nameHeader]: isSortable,\n                  [styles.calcHeader]: i > 0,\n                  [styles.withIcon]: sortKey === columnTitle,\n                  'sr-only': !isSortable,\n                })}\n                onClick={() => {\n                  if (onToggleSort && isSortable) {\n                    onToggleSort(columnTitle);\n                  }\n                }}\n              >\n                {columnTitle === nameSortKey && filterAction && (\n                  // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions\n                  <span className={styles.filterAction} onClick={(e) => e.stopPropagation()}>\n                    {filterAction}\n                  </span>\n                )}\n                {columnTitle}\n                {sortKey === columnTitle && <Icon size=\"xs\" name={sortDesc ? 'angle-down' : 'angle-up'} />}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>{limitedItems.map(itemRenderer!)}</tbody>\n      </table>\n      {curLimit > 0 && items.length > curLimit && (\n        <Button fill=\"text\" variant=\"primary\" size=\"sm\" onClick={() => setLimit(0)} className={styles.showAll}>\n          <Trans i18nKey={'legend.container.show-all-series'} className={styles.showAll}>\n            ...show all {{ total: items.length }} items\n          </Trans>\n        </Button>\n      )}\n    </>\n  );\n};\n\nconst getStyles = (theme: GrafanaTheme2, placement: LegendPlacement = 'bottom') => ({\n  header: css({\n    position: 'sticky',\n    top: 0,\n    backgroundColor: theme.colors.background.primary,\n\n    color: theme.colors.primary.text,\n  }),\n  nameHeader: css({\n    textAlign: 'left',\n  }),\n  calcHeader: css({\n    textAlign: 'right',\n  }),\n  withIcon: css({\n    paddingRight: '4px',\n  }),\n  headerSortable: css({\n    cursor: 'pointer',\n  }),\n  filterAction: css({\n    marginLeft: theme.spacing(0.5),\n    display: 'inline-flex',\n    verticalAlign: 'middle',\n  }),\n  showAll: css({\n    justifyContent: 'right',\n  }),\n\n  grid: css({\n    display: 'grid',\n    width: '100%',\n\n    // non-layout\n    fontSize: theme.typography.bodySmall.fontSize,\n    textAlign: 'right',\n    whiteSpace: 'nowrap',\n\n    'tbody,thead,tfoot,tr': {\n      display: 'grid',\n      gridColumn: '1 / -1',\n      gridTemplateColumns: 'subgrid',\n    },\n\n    tr: {\n      borderBottom: `1px solid ${theme.colors.border.weak}`,\n    },\n\n    'th,td': {\n      display: 'block',\n      alignContent: 'center',\n      whiteSpace: 'nowrap',\n\n      // non-layout\n      padding: theme.spacing(0.25, 1),\n\n      // series color/icon column\n      '&:nth-child(1)': {\n        paddingLeft: theme.spacing(1),\n      },\n\n      // series name column\n      '&:nth-child(2)': {\n        overflow: 'hidden',\n        textOverflow: 'ellipsis',\n        maxWidth: placement === 'right' ? 600 : undefined,\n      },\n    },\n  }),\n});\n"],"names":["stat","_a","_b"],"mappings":"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"}