그리드 테두리 변형 (Variant)

variant prop으로 기본 테두리와 세로 구분선이 있는 표 형태를 전환하고 본문·요약 행에 적용되는 범위를 확인합니다.

#variant#default#vertical-bordered#borders#summary
검토일: 2026-08-19
GitHub
import * as React from 'react';
import { AXDataGrid, type AXDGColumn, type AXDGDataItem, type AXDGProps } from '@axboot/datagrid';
import { Segmented } from 'antd';
import DataGridContainer from '../components/DataGridContainer';
import { useContainerSize } from '../hooks/useContainerSize';

interface SalesRow {
  id: string;
  product: string;
  category: string;
  quantity: number;
  amount: number;
}

type GridVariant = NonNullable<AXDGProps<SalesRow>['variant']>;

const categories = ['하드웨어', '소프트웨어', '서비스'];

const data: AXDGDataItem<SalesRow>[] = Array.from({ length: 30 }, (_, index) => ({
  values: {
    id: `ORD-${String(index + 1).padStart(3, '0')}`,
    product: `상품 ${index + 1}`,
    category: categories[index % categories.length],
    quantity: (index % 5) + 1,
    amount: 28000 + index * 3500,
  },
}));

const columns: AXDGColumn<SalesRow>[] = [
  { key: 'id', label: '주문번호', width: 100, align: 'center' },
  { key: 'product', label: '상품명', width: 180 },
  { key: 'category', label: '분류', width: 120, align: 'center' },
  { key: 'quantity', label: '수량', width: 90, align: 'right' },
  {
    key: 'amount',
    label: '금액',
    width: 140,
    align: 'right',
    itemRender: ({ values }) => `${values.amount.toLocaleString('ko-KR')}원`,
  },
];

const summaryColumns: NonNullable<AXDGProps<SalesRow>['summary']>['columns'] = [
  { columnIndex: 0, align: 'center', itemRender: () => <strong>합계</strong> },
  {
    columnIndex: 3,
    align: 'right',
    itemRender: ({ data }) => data.reduce((sum, item) => sum + item.values.quantity, 0),
  },
  {
    columnIndex: 4,
    align: 'right',
    itemRender: ({ data }) => `${data.reduce((sum, item) => sum + item.values.amount, 0).toLocaleString('ko-KR')}원`,
  },
];

const variantOptions: Array<{ value: GridVariant; label: string; description: string }> = [
  { value: 'default', label: 'default', description: '행 중심의 기본 테두리' },
  { value: 'vertical-bordered', label: 'vertical-bordered', description: '본문과 요약 셀의 세로 구분선 표시' },
];

export default function VariantExample() {
  const [variant, setVariant] = React.useState<GridVariant>('default');
  const containerRef = React.useRef<HTMLDivElement>(null);
  const { width, height } = useContainerSize(containerRef);

  return (
    <div className='flex min-h-0 flex-col gap-3'>
      <div className='flex flex-wrap items-center justify-between gap-3 rounded-lg border border-slate-200 bg-slate-50 p-3 text-sm text-slate-700'>
        <div>
          <strong className='block text-slate-900'>그리드 테두리 Variant</strong>
          <span className='text-xs text-slate-500'>본문과 하단 합계 행의 세로 구분선을 비교해 보세요.</span>
        </div>

        <Segmented
          aria-label='그리드 테두리 variant 선택'
          value={variant}
          options={variantOptions.map(({ value, label }) => ({ value, label }))}
          onChange={value => setVariant(value as GridVariant)}
        />
      </div>

      <p className='m-0 text-xs text-slate-500' aria-live='polite'>
        현재 설정: <code>variant=&quot;{variant}&quot;</code> —{' '}
        {variantOptions.find(option => option.value === variant)?.description}
      </p>

      <DataGridContainer ref={containerRef}>
        <AXDataGrid<SalesRow>
          width={width}
          height={height}
          columns={columns}
          data={data}
          rowKey='id'
          showLineNumber
          frozenColumnIndex={1}
          variant={variant}
          summary={{ position: 'bottom', columns: summaryColumns }}
        />
      </DataGridContainer>
    </div>
  );
}

1. variant가 바꾸는 것

AXDataGridvariant prop은 그리드 본문과 Summary 셀의 세로 테두리 표현을 선택합니다. 데이터, 컬럼, 정렬, 선택 같은 동작은 바꾸지 않습니다.

표현 권장 용도
default 본문 셀 사이의 세로 구분선을 생략한 기본 스타일 행 단위 탐색이 중심인 일반 목록
vertical-bordered 본문과 Summary의 각 셀 오른쪽에 세로 구분선 표시 열 경계를 빠르게 구분해야 하는 밀도 높은 표

값을 생략하면 default가 적용됩니다.


2. 라이브 예제

위의 선택 버튼으로 두 값을 전환해 본문과 하단 합계 행의 세로 구분선을 비교할 수 있습니다. 고정 컬럼을 함께 사용해도 같은 variant가 고정 영역과 스크롤 영역에 일관되게 적용됩니다.

핵심 설정은 다음과 같습니다.

const [variant, setVariant] = useState<'default' | 'vertical-bordered'>('default');

<AXDataGrid
  columns={columns}
  data={data}
  variant={variant}
  summary={{
    position: 'bottom',
    columns: summaryColumns,
  }}
/>;

variant는 그리드 테두리 프리셋이고, scrollbar.variantnative | classic | modern과는 서로 다른 설정입니다. 스크롤바 모양은 스크롤바 설정 가이드를 참고하세요.


3. 테마와 함께 사용하기

vertical-bordered의 선 색상은 --axdg-border-color-light를 사용하며, 값이 없으면 --axdg-border-color-base로 대체됩니다. 서비스 테마에 맞춰 선 색상을 바꿀 때는 그리드 wrapper에서 CSS 변수를 재정의합니다.

.report-grid {
  --axdg-border-color-light: #cbd5e1;
}

선의 대비를 조정한 뒤에는 일반 행, hover/선택 상태, Summary 행에서 컬럼 경계를 충분히 구분할 수 있는지 함께 확인하세요.