antBUtton 생성
topButton 이미지 변경 엑셀 버튼 조정 tab 컨트론 생성 detailGrid, layout 생성 modal motion 적용
This commit is contained in:
127
src/components/common/Layout/DetailLayout.js
Normal file
127
src/components/common/Layout/DetailLayout.js
Normal file
@@ -0,0 +1,127 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Card } from 'antd';
|
||||
import DetailGrid from './DetailGrid';
|
||||
|
||||
/**
|
||||
* Ant Design 방식의 DetailModalWrapper 컴포넌트
|
||||
* @param {Array} itemGroups - 표시할 항목 그룹 배열
|
||||
* @param {Object} formData - 폼 데이터 객체
|
||||
* @param {Function} onChange - 값 변경 시 호출할 함수
|
||||
* @param {boolean} disabled - 전체 비활성화 여부
|
||||
* @param {number} columnCount - 한 행에 표시할 컬럼 수 (기본값: 4)
|
||||
* @param {ReactNode} children - 추가 컨텐츠
|
||||
*/
|
||||
const DetailLayout = ({
|
||||
itemGroups,
|
||||
formData,
|
||||
onChange,
|
||||
disabled = false,
|
||||
columnCount = 4,
|
||||
children
|
||||
}) => {
|
||||
// 값 변경 핸들러
|
||||
const handleChange = (key, value, handler) => {
|
||||
// 핸들러가 있으면 핸들러 실행
|
||||
if (handler) {
|
||||
handler(value, key, formData);
|
||||
}
|
||||
|
||||
// 키가 점 표기법이면 중첩 객체 업데이트
|
||||
if (key.includes('.')) {
|
||||
const [parentKey, childKey] = key.split('.');
|
||||
onChange({
|
||||
...formData,
|
||||
[parentKey]: {
|
||||
...formData[parentKey],
|
||||
[childKey]: value
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 일반 키는 직접 업데이트
|
||||
onChange({ ...formData, [key]: value });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DetailWrapper>
|
||||
{itemGroups.map((group, index) => (
|
||||
<Card
|
||||
key={`group-${index}`}
|
||||
title={group.title}
|
||||
style={{ marginBottom: 16 }}
|
||||
>
|
||||
<DetailGrid
|
||||
items={group.items}
|
||||
formData={formData}
|
||||
onChange={handleChange}
|
||||
disabled={disabled || group.disabled}
|
||||
columnCount={group.columnCount || columnCount}
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
{children}
|
||||
</DetailWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const DetailWrapper = styled.div`
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
`;
|
||||
|
||||
export default DetailLayout;
|
||||
|
||||
//예시
|
||||
// const itemGroupsExample = [
|
||||
// {
|
||||
// title: '기본 정보',
|
||||
// items: [
|
||||
// {
|
||||
// row: 0,
|
||||
// col: 0,
|
||||
// colSpan: 2,
|
||||
// type: 'text',
|
||||
// key: 'title',
|
||||
// label: '제목',
|
||||
// required: true,
|
||||
// disabled: !isView('title'),
|
||||
// width: '300px',
|
||||
// },
|
||||
// {
|
||||
// row: 0,
|
||||
// col: 2,
|
||||
// colSpan: 2,
|
||||
// type: 'number',
|
||||
// key: 'order_id',
|
||||
// label: '순서',
|
||||
// required: true,
|
||||
// disabled: !isView('order_id'),
|
||||
// width: '200px',
|
||||
// min: 1,
|
||||
// },
|
||||
// {
|
||||
// row: 1,
|
||||
// col: 0,
|
||||
// colSpan: 2,
|
||||
// type: 'status',
|
||||
// key: 'status',
|
||||
// label: '상태',
|
||||
// value: resultData.status,
|
||||
// },
|
||||
// {
|
||||
// row: 1,
|
||||
// col: 2,
|
||||
// colSpan: 2,
|
||||
// type: 'switch',
|
||||
// key: 'is_link',
|
||||
// label: '링크 사용',
|
||||
// disabled: !isView('is_link'),
|
||||
// },
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// title: ''
|
||||
// }
|
||||
// ];
|
||||
Reference in New Issue
Block a user