# Component/Table/DataTable > Props: component-table-datatable.props.txt ## Examples ### Auto Reset Row Select Off autoResetRowSelect=false일 경우 rows 변경시에도 selection 상태가 유지됩니다. ```tsx { render: (args: DataTableProps) => { const [rows, setRows] = useState>((args.rows as DataTableRowsType) || []); const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => rows, [rows]); const [selectedRows, setSelectedRows] = useState>([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { setSelectedRows(rows); }; return ( {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify(
                {
                  selectedRows: selectedRows.map((row) => row),
                },
                null,
                2,
              )}
            
          
); }, args: { rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'autoResetRowSelect=false일 경우 rows 변경시에도 selection 상태가 유지됩니다.' } } } } ``` ### Auto Reset Row Select On autoResetRowSelect=true일 경우 rows 변경시 Row select 상태는 자동 초기화됩니다 ```tsx { render: (args: DataTableProps) => { const [rows, setRows] = useState>((args.rows as DataTableRowsType) || []); const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => rows, [rows]); const [selectedRows, setSelectedRows] = useState>([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { setSelectedRows(rows); }; return ( {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify(
                {
                  selectedRows: selectedRows.map((row) => row),
                },
                null,
                2,
              )}
            
          
); }, args: { rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'autoResetRowSelect=true일 경우 rows 변경시 Row select 상태는 자동 초기화됩니다' } } } } ``` ### Base ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => args.columns as DataTableColumnsType ?? columns, []); const cachedRows = useMemo(() => args.rows as DataTableRowsType ?? rows, []); return ; } } ``` ### Beforehand Expansion By Key ```tsx { render: (args: DataTableProps) => { const [is_selectable, setSelectable] = useState(false); const [is_fixed, setFixed] = useState(false); const [isNoData, setNoData] = useState(false); const [is_page, setPage] = useState(false); const [expanded, setExpanded] = useState(args.rowExpansion as Key[]); const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); const tableRows = useMemo(() => (isNoData ? [] : cachedRows), [cachedRows, isNoData]); const handleExpandRows = (rowKeys: Key[]) => { setExpanded(rowKeys); args.onExpandRows?.(rowKeys); }; return ( Selectable setSelectable(!is_selectable)} onText='ON' /> Fixed setFixed(!is_fixed)} onText='ON' /> No Data setNoData(!isNoData)} onText='ON' /> stickyHeader (page) setPage(!is_page)} onText='ON' /> { const is_expanded = row.expandable as boolean; return is_expanded ? index === 2 ? : : null; }} selectableRows={is_selectable} columns={is_fixed ? fixedExpandRowCellColumns : cachedColumns} rows={tableRows} stickyHeader={is_page ? { mode: 'page', offset: 0 } : true} rowExpansion={expanded} onExpandRows={handleExpandRows} /> {args.rowExpansion && ( RowExpansion: Array key
              
                {JSON.stringify(
                  {
                    rowExpansion: expanded,
                  },
                  null,
                  2,
                )}
              
            
)}
); }, args: { columns: customRowCellColumns, rows: ExpandRows, scroll: { x: 1200 }, rowExpansion: ['fruit-1'], onExpandRows: (rowKeys: Key[]) => { console.log('Expand Row Keys =>', rowKeys); } } } ``` ### Beforehand Selection By Function rowSelection 속성을 함수형태로 전달하여 해당하는 row 선택 상태를 업데이트할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const rowSelectFilter = (row: DataType) => row.amount < 20; const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); }; return ( RowSelection: function type
            
              {JSON.stringify(
                {
                  rowSelectionFunction: '(row: DataType) => row.amount < 20',
                },
                null,
                2,
              )}
            
          
); }, args: { rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'rowSelection 속성을 함수형태로 전달하여 해당하는 row 선택 상태를 업데이트할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다.' } } } } ``` ### Beforehand Selection By Key rowSelection 속성을 row 고유 key값을 배열로 전달하여 row 선택 상태를 업데이트할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); }; return ( RowSelection: Array key
            
              {JSON.stringify(
                {
                  rowSelectionList: args.rowSelection,
                },
                null,
                2,
              )}
            
          
); }, args: { rows: selectionRows, selectableRows: true, rowSelection: ['fruit-1', 'fruit-2', 'fruit-4', 'fruit-5'] }, parameters: { docs: { description: { story: 'rowSelection 속성을 row 고유 key값을 배열로 전달하여 row 선택 상태를 업데이트할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다.' } } } } ``` ### Cell Span 테이블 컬럼 cellAttributes 속성을 통해 특정 테이블 셀 rowSpan, colSpan, hidden 여부를 지정할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: SpanColumns, rows: SpanRows, cellHoverStyle: false }, parameters: { docs: { description: { story: '테이블 컬럼 cellAttributes 속성을 통해 특정 테이블 셀 rowSpan, colSpan, hidden 여부를 지정할 수 있습니다.' } } } } ``` ### Clickable Selection selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const [selectedRows, setSelectedRows] = useState>([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return ( {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify(
                {
                  selectedRowKeys: selectedRowKeys,
                  selectedRows: selectedRows.map((row) => row),
                },
                null,
                2,
              )}
            
          
); }, args: { rows: selectionRows, selectableRows: true, clickableRows: true }, parameters: { docs: { description: { story: 'selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다.' } } } } ``` ### Column Align 테이블 컬럼별 정렬과 셀단위 정렬을 지정할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: customColumns }, parameters: { docs: { description: { story: '테이블 컬럼별 정렬과 셀단위 정렬을 지정할 수 있습니다.' } } } } ``` ### Column Fixed 가로스크롤 발생시 테이블 컬럼을 고정할 수 있습니다. 그룹 컬럼일 경우 지원하지 않습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: fixedColumns, scroll: { x: 1200 } }, parameters: { docs: { description: { story: '가로스크롤 발생시 테이블 컬럼을 고정할 수 있습니다. 그룹 컬럼일 경우 지원하지 않습니다.' } } } } ``` ### Column Group 테이블 컬럼 그룹을 구성할 수 있습니다. 상위 부모 컬럼은 id 속성이 없습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: groupColumns, rows: groupRows }, parameters: { docs: { description: { story: '테이블 컬럼 그룹을 구성할 수 있습니다. 상위 부모 컬럼은 id 속성이 없습니다.' } } } } ``` ### Column Width Min Width 테이블 컬럼별 너비, 최소 너비를 지정할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( (참고) scroll.x 또는 resize props 사용시 table-layout은 fixed 처리됩니다.(기본값: auto)
scroll.x 값 사용하는 경우 각 셀의 너비를 명시적으로 모두 지정하는것을 권장합니다.
Width
  • minWidth 속성없이 사용된다면 자동으로 해당 width값으로 minWidth 처리됩니다.
  • table-layout: auto 일 경우
    • 모든 셀의 너비가 고정된다면 모든 셀의 너비를 더한 값보다 브라우저 크기가 커질때 동적으로 변할 수 있습니다.
    • 특정 셀의 너비를 필수로 고정해야한다면 모든 셀의 너비를 지정하지 않고 고정할 셀만 너비를 지정하세요. 너비를 지정하지 않은 셀들은 가변으로, 지정된 셀은 너비를 보장할 수 있습니다.
MinWidth
  • width 속성없이 minWidth만 사용된다면 가변 너비를 가지되 최소 너비를 보장합니다.
  • width 속성과 함께 사용된다면 해당 width값으로 너비를 기본을 가지되 작아질 경우 minWidth 최소 너비를 보장합니다.
); }, args: { columns: customWidthColumns }, parameters: { docs: { description: { story: '테이블 컬럼별 너비, 최소 너비를 지정할 수 있습니다.' } } } } ``` ### Custom Column Cell 테이블 컬럼별 커스텀을 할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: customColumnCell }, parameters: { docs: { description: { story: '테이블 컬럼별 커스텀을 할 수 있습니다.' } } } } ``` ### Custom No Data Padding ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { rows: [], noDataPadding: 24 } } ``` ### Custom No Data Text 테이블 데이터가 없을 경우 노출할 텍스트를 커스텀할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { noDataText: 조회 가능한 신청 목록이 없습니다. , rows: [] }, parameters: { docs: { description: { story: '테이블 데이터가 없을 경우 노출할 텍스트를 커스텀할 수 있습니다.' } } } } ``` ### Custom Row Cell 테이블 로우별 커스텀을 할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: customRowCellColumns, rows: rows }, parameters: { docs: { description: { story: '테이블 로우별 커스텀을 할 수 있습니다.' } } } } ``` ### Custom Row Cell Style 테이블 컬럼 cellAttributes 속성을 통해 특정 테이블 셀 스타일을 지정할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: customRowStyleColumns, cellHoverStyle: false }, parameters: { docs: { description: { story: '테이블 컬럼 cellAttributes 속성을 통해 특정 테이블 셀 스타일을 지정할 수 있습니다.' } } } } ``` ### Custom Row Color ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: customRowCellColumns, rows: selectionRows, selectableRows: true, rowColor: (row: DataType, index: number) => index % 2 === 0 ? colors.red50 : colors.white } } ``` ### Default All Selection selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const [selectedRows, setSelectedRows] = useState>(args.rows); const [selectedRowKeys, setSelectedRowKeys] = useState(args.rows.map((row) => row.key ?? '')); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return ( {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify(
                {
                  selectedRowKeys: selectedRowKeys,
                  selectedRows: selectedRows.map((row) => row),
                },
                null,
                2,
              )}
            
          
); }, args: { rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다.' } } } } ``` ### Disabled row에 disabled 속성을 지정할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const [, setSelectedRows] = useState>([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); }; return ( ); }, args: { columns: comprehensiveCustomColumns, rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'row에 disabled 속성을 지정할 수 있습니다.' } } } } ``` ### Disabled Cell Off ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: customRowCellColumns, rows: selectionRows, selectableRows: true, clickableRows: true, cellDisabledStyle: false } } ``` ### Disabled Sticky Header 세로 스크롤 발생시 테이블 헤더는 자동으로 고정됩니다. false로 지정할 경우 스크롤 발생 여부와 상관없이 해제할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { stickyHeader: false, rows: [...rows, ...rows, ...rows, ...rows], scroll: { y: 300 } }, parameters: { docs: { description: { story: '세로 스크롤 발생시 테이블 헤더는 자동으로 고정됩니다. false로 지정할 경우 스크롤 발생 여부와 상관없이 해제할 수 있습니다.' } } } } ``` ### Divider Rows 테이블에 각 row의 하단에 구분자를 추가할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: customColumns, rows: SpanRows, dividerRows: (row, index) => index % 2 === 0 }, parameters: { docs: { description: { story: '테이블에 각 row의 하단에 구분자를 추가할 수 있습니다.' } } } } ``` ### Expandable Row ```tsx { render: (args: DataTableProps) => { const [is_selectable, setSelectable] = useState(false); const [is_fixed, setFixed] = useState(false); const [isNoData, setNoData] = useState(false); const [is_page, setPage] = useState(false); const [expanded, setExpanded] = useState(args.rowExpansion as Key[]); const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); const tableRows = useMemo(() => (isNoData ? [] : cachedRows), [cachedRows, isNoData]); const handleExpandRows = (rowKeys: Key[]) => { setExpanded(rowKeys); args.onExpandRows?.(rowKeys); }; return ( Selectable setSelectable(!is_selectable)} onText='ON' /> Fixed setFixed(!is_fixed)} onText='ON' /> No Data setNoData(!isNoData)} onText='ON' /> stickyHeader (page) setPage(!is_page)} onText='ON' /> { const is_expanded = row.expandable as boolean; return is_expanded ? index === 2 ? : : null; }} selectableRows={is_selectable} columns={is_fixed ? fixedExpandRowCellColumns : cachedColumns} rows={tableRows} stickyHeader={is_page ? { mode: 'page', offset: 0 } : true} rowExpansion={expanded} onExpandRows={handleExpandRows} /> {args.rowExpansion && ( RowExpansion: Array key
              
                {JSON.stringify(
                  {
                    rowExpansion: expanded,
                  },
                  null,
                  2,
                )}
              
            
)}
); }, args: { columns: customRowCellColumns, rows: ExpandRows, scroll: { x: 1200 } } } ``` ### Expandable Row No Button ```tsx { render: (args: DataTableProps) => { const [is_selectable, setSelectable] = useState(false); const [is_fixed, setFixed] = useState(false); const [isNoData, setNoData] = useState(false); const [is_page, setPage] = useState(false); const [expanded, setExpanded] = useState(args.rowExpansion as Key[]); const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); const tableRows = useMemo(() => (isNoData ? [] : cachedRows), [cachedRows, isNoData]); const handleExpandRows = (rowKeys: Key[]) => { setExpanded(rowKeys); args.onExpandRows?.(rowKeys); }; return ( Selectable setSelectable(!is_selectable)} onText='ON' /> Fixed setFixed(!is_fixed)} onText='ON' /> No Data setNoData(!isNoData)} onText='ON' /> stickyHeader (page) setPage(!is_page)} onText='ON' /> { const is_expanded = row.expandable as boolean; return is_expanded ? index === 2 ? : : null; }} selectableRows={is_selectable} columns={is_fixed ? fixedExpandRowCellColumns : cachedColumns} rows={tableRows} stickyHeader={is_page ? { mode: 'page', offset: 0 } : true} rowExpansion={expanded} onExpandRows={handleExpandRows} /> {args.rowExpansion && ( RowExpansion: Array key
              
                {JSON.stringify(
                  {
                    rowExpansion: expanded,
                  },
                  null,
                  2,
                )}
              
            
)}
); }, args: { columns: customRowCellColumns, rows: ExpandRows, expandableButton: false, scroll: { x: 1200 } } } ``` ### Loading ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { loading: true } } ``` ### No Data ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { rows: [] } } ``` ### Page Sticky Header page mode에서는 테이블 박스가 아니라 viewport 스크롤 기준으로 헤더가 고정됩니다. (Docs 미리보기에서는 sticky 헤더가 보이지 않습니다. Canvas 모드에서 스크롤하여 확인하세요.) ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? groupColumns, []); const cachedRows = useMemo( () => Array.from({ length: 50 }, (_, index) => { const row = groupRows[index % groupRows.length]; return { ...row, id: row.id + index * 100000, name: `${row.name} ${index + 1}`, }; }), [], ); return ( Page mode ); }, args: { columns: groupColumns, stickyHeader: { mode: 'page', offset: 0 } }, parameters: { docs: { description: { story: 'page mode에서는 테이블 박스가 아니라 viewport 스크롤 기준으로 헤더가 고정됩니다. (Docs 미리보기에서는 sticky 헤더가 보이지 않습니다. Canvas 모드에서 스크롤하여 확인하세요.)' } } } } ``` ### Page Sticky Header With Scroll Fixed Group page mode에서 가로 스크롤, fixed 컬럼, 그룹 헤더, 전체 선택, 정렬을 함께 사용하는 조합입니다. (Docs 미리보기에서는 sticky 헤더가 보이지 않습니다. Canvas 모드에서 스크롤하여 확인하세요.) ```tsx { render: (args: DataTableProps) => { const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [filter, setFilter] = useState({ sortBy: 'id', sortDirection: 'default' as SortDirection }); const pageRows = useMemo( () => Array.from({ length: 60 }, (_, index) => { const row = groupRows[index % groupRows.length]; return { ...row, key: `page-sticky-${index}`, id: row.id + index * 100000, name: `${row.name} ${index + 1}`, }; }), [], ); const sortedRows = useMemo(() => { switch (filter.sortDirection) { case 'asc': return sortBy([...pageRows], filter.sortBy); case 'desc': return sortBy([...pageRows], filter.sortBy).reverse(); case 'default': default: return pageRows; } }, [filter, pageRows]); const handleSort = (sortByColumn: string) => { const sortDirections: SortDirection[] = ['asc', 'desc', 'default']; const currentOrderIndex = sortDirections.indexOf(filter.sortDirection) + 1; const nextSortDirection = currentOrderIndex === sortDirections.length ? sortDirections[0] : sortDirections[currentOrderIndex]; setFilter({ sortBy: sortByColumn, sortDirection: nextSortDirection }); }; const handleSelectedRows = (rowKeys: Key[]) => { setSelectedRowKeys(rowKeys); }; return ( Page sticky header {selectedRowKeys.length}개 선택됨 ); }, args: { stickyHeader: { mode: 'page', offset: 0 }, scroll: { x: 1168 }, selectableRows: true }, parameters: { docs: { description: { story: 'page mode에서 가로 스크롤, fixed 컬럼, 그룹 헤더, 전체 선택, 정렬을 함께 사용하는 조합입니다. (Docs 미리보기에서는 sticky 헤더가 보이지 않습니다. Canvas 모드에서 스크롤하여 확인하세요.)' } } } } ``` ### Partial Disabled Cell Off Table 전체 row가 disabled 상태일 때, cellAttributes에서 disabled: false를 반환하면 해당 셀만 활성화됩니다. 이를 통해 row 레벨의 disabled 스타일(opacity 등)이 적용되지 않고, 해당 셀만 정상적으로 동작합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: [...columns, { text: 'disabled 해지', id: 'id', cellAttributes: () => { return { disabled: false }; } }], rows: rows.map(row => ({ ...row, disabled: true })) }, parameters: { docs: { description: { story: '전체 row가 disabled 상태일 때, cellAttributes에서 disabled: false를 반환하면 해당 셀만 활성화됩니다. 이를 통해 row 레벨의 disabled 스타일(opacity 등)이 적용되지 않고, 해당 셀만 정상적으로 동작합니다.' } } } } ``` ### Partial Disabled Cell On Table 전체 row가 활성화 상태일 때, cellAttributes에서 disabled: true를 반환하면 해당 셀만 비활성화됩니다. 이 경우 disabled 스타일(opacity 등)이 해당 셀에만 적용됩니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: [...columns, { text: '부분 disabled', id: 'id', cellAttributes: () => { return { disabled: true }; } }], rows: rows.map(row => ({ ...row })) }, parameters: { docs: { description: { story: '전체 row가 활성화 상태일 때, cellAttributes에서 disabled: true를 반환하면 해당 셀만 비활성화됩니다. 이 경우 disabled 스타일(opacity 등)이 해당 셀에만 적용됩니다.' } } } } ``` ### Resize width값 지정된 컬럼은 resize가 불가합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { resize: true }, parameters: { docs: { description: { story: 'width값 지정된 컬럼은 resize가 불가합니다.' } } } } ``` ### Scroll 가로, 세로 스크롤 영역 너비/높이를 지정할 수 있습니다 ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo( () => (args.rows as DataTableRowsType) ?? [...rows, ...rows, ...rows, ...rows], [], ); return ( 기본 Scroll y : 250 Scroll y : 1000 ); }, args: { scroll: { x: 1200 } }, parameters: { docs: { description: { story: '가로, 세로 스크롤 영역 너비/높이를 지정할 수 있습니다' } } } } ``` ### Selection selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const [selectedRows, setSelectedRows] = useState>([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return ( {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify(
                {
                  selectedRowKeys: selectedRowKeys,
                  selectedRows: selectedRows.map((row) => row),
                },
                null,
                2,
              )}
            
          
); }, args: { rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다.' } } } } ``` ### Selection Cell Span selectableRows의 cellAttributes 속성을 통해 체크박스의 rowSpan, colSpan, hidden 여부를 지정할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const [selectedRows, setSelectedRows] = useState>([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return ( {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify(
                {
                  selectedRowKeys: selectedRowKeys,
                  selectedRows: selectedRows.map((row) => row),
                },
                null,
                2,
              )}
            
          
); }, args: { columns: SpanColumns, rows: SpanRows, cellHoverStyle: false, selectableRows: { cellAttributes: (row: DataType) => ({ rowSpan: row.code === 410 ? 2 : 1, hidden: row.code === 410 && row.amount === 20 }) } }, parameters: { docs: { description: { story: 'selectableRows의 cellAttributes 속성을 통해 체크박스의 rowSpan, colSpan, hidden 여부를 지정할 수 있습니다.' } } } } ``` ### Selection Large Data selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => args.columns as DataTableColumnsType ?? columns, []); const cachedRows = useMemo(() => Array.from({ length: 1000 }, (_, i) => ({ ...selectionRows[i % selectionRows.length], key: 'fruit-' + i })), []); const [selectedRows, setSelectedRows] = useState>([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return {selectedRows.length}개 Row 선택되었습니다. ; }, args: { selectableRows: true }, parameters: { a11y: { disable: true }, docs: { description: { story: 'selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다.' } } } } ``` ### Selection With Custom Key Extractor rowSelectionKeyExtractor를 지정하면 row.key가 아닌 다른 값을 사용할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const [selectedRows, setSelectedRows] = useState>([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return ( {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify(
                {
                  selectedRowKeys: selectedRowKeys,
                  selectedRows: selectedRows.map((row) => row),
                },
                null,
                2,
              )}
            
          
); }, render: (args: DataTableProps) => { const cachedColumns = useMemo(() => args.columns as DataTableColumnsType ?? columns, []); const cachedRows = useMemo(() => args.rows as DataTableRowsType ?? selectionRows, []); const [selectedRows, setSelectedRows] = useState>([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return index} rowSelection={selectedRowKeys} /> {selectedRows.length}개 Row 선택되었습니다.
            
              {JSON.stringify({
              selectedRowKeys: selectedRowKeys,
              selectedRows: selectedRows.map(row => row)
            }, null, 2)}
            
          
; }, args: { rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'rowSelectionKeyExtractor를 지정하면 row.key가 아닌 다른 값을 사용할 수 있습니다.' } } } } ``` ### Sort 테이블 컬럼 sortable 속성 사용시 해당 열 데이터 Sorting을 위한 onSortBy 이벤트를 전달합니다. Server side 소팅만 지원합니다. ```tsx { render: (args: DataTableProps) => { const DEFAULT_FILTER_ORDER: SortDirection[] = ['asc', 'desc', 'default']; const [data, setData] = useState>(rows); const [filter, setFilter] = useState({ sortBy: 'name', sortDirection: 'default' as SortDirection }); const getSortDirection = (sortDirections: SortDirection[], current: SortDirection | null) => { if (!current) { return sortDirections[0]; } const currentOrderIndex = sortDirections.indexOf(current) + 1; return currentOrderIndex === sortDirections.length ? sortDirections[0] : sortDirections[currentOrderIndex]; }; const handleSort = (sortByColumn: string) => { const nextSortOrder = getSortDirection(DEFAULT_FILTER_ORDER, filter.sortDirection); setFilter((prevFilter) => ({ ...prevFilter, sortBy: sortByColumn, sortDirection: nextSortOrder })); // server api call by sortId.. // 정렬 예시를 위한 샘플 코드 => 실제 api 호출후 갱신된 데이터를 가정합니다. switch (nextSortOrder) { case 'asc': setData(sortBy([...data], sortByColumn)); return; case 'desc': setData(sortBy([...data], sortByColumn).reverse()); return; case 'default': default: setData(rows); return; } }; return (
정렬 예시를 위한 샘플 코드로 실제 서버 사이드 소팅 api 호출후 갱신된 데이터를 가정합니다. ) ?? sortColumns} rows={data} sortBy={filter.sortBy} sortDirection={filter.sortDirection} onSortBy={handleSort} />
); }, args: {}, parameters: { docs: { description: { story: '테이블 컬럼 sortable 속성 사용시 해당 열 데이터 Sorting을 위한 onSortBy 이벤트를 전달합니다. Server side 소팅만 지원합니다.' } } } } ``` ### Strict Default All Selection selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? selectionRows, []); const [selectedRows, setSelectedRows] = useState>(args.rows); const [selectedRowKeys, setSelectedRowKeys] = useState(args.rows.map((row) => row.key ?? '')); const handleSelectedRows = (rowsKey: Key[], rows: DataTableRowsType) => { console.log('Select Rows =>', rowsKey, rows); setSelectedRows(rows); setSelectedRowKeys(rowsKey); }; return ( {selectedRows.length}개 Row 선택되었습니다.
              
                {JSON.stringify(
                  {
                    selectedRowKeys: selectedRowKeys,
                    selectedRows: selectedRows.map((row) => row),
                  },
                  null,
                  2,
                )}
              
            
); }, args: { rows: selectionRows, selectableRows: true }, parameters: { docs: { description: { story: 'selectableRows 속성 사용시 Selection 테이블을 구성할 수 있습니다. 각 테이블 로우는 고유의 key 속성이 존재해야합니다.' } } } } ``` ### With Pagination ```tsx { render: (args: DataTableProps) => { const [currentPage, setCurrentPage] = useState(1); const [data, setData] = useState>(rows); const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => data, [data]); useEffect(() => { // server api call by pagination // Pagination 예시를 위한 샘플 코드 => 실제 api 호출후 갱신된 데이터를 가정합니다. const sampleData = [...data]; setData(sampleData.reverse()); }, [currentPage]); return (
Pagination 동작 예시를 위한 샘플 코드로 실제 api 호출후 갱신된 데이터를 가정합니다.
); }, args: {} } ``` ### Wrapper Sticky columns의 wrapper를 false로 설정하면 cell 아래의 Stack을 제거할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: WrapperColumns, rows: SpanRows }, parameters: { docs: { description: { story: 'columns의 wrapper를 false로 설정하면 cell 아래의 Stack을 제거할 수 있습니다.' } } } } ``` ### Wrapper Sticky Disabled columns의 wrapper를 false로 설정하면 cell 아래의 Stack을 제거할 수 있습니다. ```tsx { render: (args: DataTableProps) => { const cachedColumns = useMemo(() => (args.columns as DataTableColumnsType) ?? columns, []); const cachedRows = useMemo(() => (args.rows as DataTableRowsType) ?? rows, []); return ( {args?.scroll && ( {args?.scroll?.x && Scroll x: {args.scroll.x}} {args?.scroll?.y && Scroll y: {args.scroll.y}} )} ); }, args: { columns: WrapperColumns, rows: SpanRows.map(row => ({ ...row, disabled: true })) }, parameters: { docs: { description: { story: 'columns의 wrapper를 false로 설정하면 cell 아래의 Stack을 제거할 수 있습니다.' } } } } ```