Skip to content

The header object has the 'rowSpan' property, but there is an issue where it is not applied even when defined through 'columnHelper'. #5202

Description

@HwangInUng

The header object has the 'rowSpan' property, but there is an issue where it is not applied even when defined through 'columnHelper'.

Therefore, I have written a function as follows that compares the length of the header group generated by 'columnHelper.group' and returns 'rowSpan.' There are still many areas that need improvement, and a lot of refactoring is pending, so feedback from many people is needed.

Information
Code : JavaScript

export const getMergeHeaderGroups = (tableHeaderGroups) => {
  const headerGroups = tableHeaderGroups;
  const headerIds = new Set(); // 동일한 컬럼명 중복 방지
  const resultHeaderGroups = [];

  if (headerGroups.length === 1) return [tableHeaderGroups[0].headers];

  for (let i = 0; i < headerGroups.length; i++) {
    const headerGroup = i === 0 ? headerGroups[i].headers : resultHeaderGroups[i];

    // 행 객체 평면화
    const preHeaders = headerGroup.map(header =>
      header.isPlaceholder ?
        {
          ...header,
          isPlaceholder: false,
          rowSpan: tableHeaderGroups.length - i
        } :
        { ...header, rowSpan: 1 }
    );
    resultHeaderGroups.pop(); // 마지막 배열을 꺼냄
    resultHeaderGroups.push(preHeaders); // 수정된 배열을 저장
    preHeaders.forEach(preHeader => headerIds.add(preHeader.column.id)); // 현재까지 보유한 header 누적

    const targetHeaders = headerGroups[i + 1].headers;
    const newHeaders = targetHeaders.filter(header => !headerIds.has(header.column.id));
    resultHeaderGroups.push(newHeaders);

    if (i === headerGroups.length - 2) {
      break;
    }
  }
  return resultHeaderGroups;
};

columns example

  const defaultColumns = [
    columnHelper.display({
      id: 'status',
      size: 40,
      cell: TestStatusCell,
      header: <StatusIcon />,
    }),
    columnHelper.group({
      id: 'test',
      header: 'test',
      columns: [

        columnHelper.accessor('name', {
          header: '이름',
          cell: TestTableCell,
          size: 300,
          filterFn: 'arrIncludesSome',
          meta: {
            type: 'text',
            required: true,
            readOnly: true, // 읽기전용(default: false)
          }
        }),
        columnHelper.accessor('age', {
          header: '나이',
          cell: TestTableCell,
          size: 40,
          filterFn: 'arrIncludesSome',
          meta: {
            type: 'text',
            required: true,
            justify: 'right', // 가로 방향
          }
        }),
      ]
    }),
    columnHelper.accessor('gender', {
      header: '성별',
      cell: TestTableCell,
      size: 40,
      filterFn: 'arrIncludesSome',
      meta: {
        type: 'select',
        options: ['남자', '여자'], // select 옵션
      }
    }),
    columnHelper.accessor('createdAt', {
      header: '생일',
      cell: TestTableCell,
      size: 100,
      filterFn: 'arrIncludesSome',
      meta: {
        type: 'date',
      }
    }),
    columnHelper.display({
      id: 'auth', // row.id로 해당 키의 값을 획득
      header: '체크',
      cell: DisplayCheckInput,
      size: 40,
      meta: {
        readOnly: true,
      }
    }),
];
const memoizedColumns = useMemo(() => defalutColumns, []);

Usage example

...skip
const table = useReactTable({...});
const mergeHeaderGropus = getMergeHeaderGroups(table.getHeaderGroups());
...skip

Result
스크린샷 2023-12-13 115325

Originally posted by @HwangInUng in #5201

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions