fix: FoxCard가 children과 제목·설명을 함께 그리도록 머리말·몸통을 나눈다
가맹몰 상세 등록 화면의 카드들이 title/description을 넘기는데도 children이 있으면 FoxCard가 머리말을 버려 시안(FOX-PAY_2.0 2805:635)의 카드 제목·설명이 보이지 않았다. contents를 header(gap 2)·body로 나누고 그 사이를 gap 5로 띄운다. 제목·설명만 있는 기존 카드는 모양이 같다. Co-Authored-By: Claude Opus 5
@fd4a1b44d47bab5757e18334e533d307f8ace2ed
--- @fox/core/components/fox-card/fox-card.tsx
+++ @fox/core/components/fox-card/fox-card.tsx
... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 |
title?: ReactNode; |
| 13 | 13 |
/** 제목 아래 한두 줄 설명. */ |
| 14 | 14 |
description?: ReactNode; |
| 15 |
- /** 제목·설명 대신 넣을 것. 주면 `title`·`description`은 쓰이지 않는다. */ |
|
| 15 |
+ /** 제목·설명 아래에 서는 내용. 폼 구역처럼 카드 한 장으로 묶는 것을 넣는다. */ |
|
| 16 | 16 |
children?: ReactNode; |
| 17 | 17 |
/** 아래쪽 줄. 시안은 글자 버튼이다. */ |
| 18 | 18 |
actions?: ReactNode; |
... | ... | @@ -23,7 +23,10 @@ |
| 23 | 23 |
} |
| 24 | 24 |
|
| 25 | 25 |
/** |
| 26 |
- * @fox 카드. 그림·글·동작이 위에서 아래로 쌓인다. |
|
| 26 |
+ * @fox 카드. 그림·글·내용·동작이 위에서 아래로 쌓인다. |
|
| 27 |
+ * |
|
| 28 |
+ * 제목·설명은 머리말이고 `children`은 그 아래 몸통이다 — 둘 다 주면 함께 그린다 |
|
| 29 |
+ * (가맹몰 등록처럼 폼 구역을 카드로 묶을 때). 어느 한쪽만 줘도 된다. |
|
| 27 | 30 |
* |
| 28 | 31 |
* 크기는 여백과 모서리만 바꾼다 — 폭은 놓이는 자리가 정한다. |
| 29 | 32 |
* |
... | ... | @@ -44,16 +47,19 @@ |
| 44 | 47 |
return null; |
| 45 | 48 |
} |
| 46 | 49 |
|
| 50 |
+ const hasHeader = Boolean(title) || Boolean(description); |
|
| 51 |
+ |
|
| 47 | 52 |
return ( |
| 48 | 53 |
<div className={cx("fox-card", `fox-card--${size}`, className)}>
|
| 49 | 54 |
{image && <div className="fox-card__image">{image}</div>}
|
| 50 | 55 |
<div className="fox-card__contents"> |
| 51 |
- {children ?? (
|
|
| 52 |
- <> |
|
| 56 |
+ {hasHeader && (
|
|
| 57 |
+ <div className="fox-card__header"> |
|
| 53 | 58 |
{title && <p className="fox-card__title">{title}</p>}
|
| 54 | 59 |
{description && <p className="fox-card__description">{description}</p>}
|
| 55 |
- </> |
|
| 60 |
+ </div> |
|
| 56 | 61 |
)} |
| 62 |
+ {children && <div className="fox-card__body">{children}</div>}
|
|
| 57 | 63 |
</div> |
| 58 | 64 |
{actions && <div className="fox-card__actions">{actions}</div>}
|
| 59 | 65 |
</div> |
--- @fox/dev-test/component-registry.tsx
+++ @fox/dev-test/component-registry.tsx
... | ... | @@ -3833,6 +3833,20 @@ |
| 3833 | 3833 |
</div> |
| 3834 | 3834 |
), |
| 3835 | 3835 |
}, |
| 3836 |
+ {
|
|
| 3837 |
+ label: "내용과 함께 — 제목·설명이 머리말로 서고 그 아래에 내용이 놓입니다 (폼 구역을 카드로 묶을 때)", |
|
| 3838 |
+ node: ( |
|
| 3839 |
+ <div style={{ inlineSize: 480 }}>
|
|
| 3840 |
+ <FoxCard |
|
| 3841 |
+ size="lg" |
|
| 3842 |
+ title="기본 정보" |
|
| 3843 |
+ description="머리말 안은 4px, 머리말과 내용 사이는 16px입니다." |
|
| 3844 |
+ > |
|
| 3845 |
+ <FoxInput size="md" label="업체명" requirement="required" placeholder="예) 타볼라타" /> |
|
| 3846 |
+ </FoxCard> |
|
| 3847 |
+ </div> |
|
| 3848 |
+ ), |
|
| 3849 |
+ }, |
|
| 3836 | 3850 |
], |
| 3837 | 3851 |
}, |
| 3838 | 3852 |
{
|
--- @fox/styles/_fox-card.scss
+++ @fox/styles/_fox-card.scss
... | ... | @@ -5,11 +5,17 @@ |
| 5 | 5 |
// <div class="fox-card fox-card--md"> |
| 6 | 6 |
// <div class="fox-card__image">…img…</div> <!-- 선택 --> |
| 7 | 7 |
// <div class="fox-card__contents"> |
| 8 |
-// <p class="fox-card__title">타이틀</p> |
|
| 9 |
-// <p class="fox-card__description">설명</p> |
|
| 8 |
+// <div class="fox-card__header"> <!-- 선택 --> |
|
| 9 |
+// <p class="fox-card__title">타이틀</p> |
|
| 10 |
+// <p class="fox-card__description">설명</p> |
|
| 11 |
+// </div> |
|
| 12 |
+// <div class="fox-card__body">…</div> <!-- 선택 --> |
|
| 10 | 13 |
// </div> |
| 11 | 14 |
// <div class="fox-card__actions">…fox-text-button…</div> <!-- 선택 --> |
| 12 | 15 |
// </div> |
| 16 |
+// |
|
| 17 |
+// 머리말(제목·설명)과 몸통은 함께 설 수 있다 — 폼 구역을 카드로 묶는 가맹몰 등록 시안 |
|
| 18 |
+// (FOX-PAY_2.0 2805:635)이 그 예다. 머리말 안은 4px, 머리말과 몸통 사이는 16px이다. |
|
| 13 | 19 |
// |
| 14 | 20 |
// 크기 넷은 여백과 모서리만 바꾼다 — 폭은 놓이는 자리가 정한다(시안은 320px 자리에 뒀다). |
| 15 | 21 |
// |
... | ... | @@ -51,11 +57,23 @@ |
| 51 | 57 |
display: flex; |
| 52 | 58 |
flex-direction: column; |
| 53 | 59 |
align-items: flex-start; |
| 54 |
- gap: fox.gap(2); |
|
| 60 |
+ gap: fox.gap(5); |
|
| 55 | 61 |
inline-size: 100%; |
| 56 | 62 |
word-break: break-word; |
| 57 | 63 |
} |
| 58 | 64 |
|
| 65 |
+ &__header {
|
|
| 66 |
+ display: flex; |
|
| 67 |
+ flex-direction: column; |
|
| 68 |
+ align-items: flex-start; |
|
| 69 |
+ gap: fox.gap(2); |
|
| 70 |
+ inline-size: 100%; |
|
| 71 |
+ } |
|
| 72 |
+ |
|
| 73 |
+ &__body {
|
|
| 74 |
+ inline-size: 100%; |
|
| 75 |
+ } |
|
| 76 |
+ |
|
| 59 | 77 |
&__title {
|
| 60 | 78 |
inline-size: 100%; |
| 61 | 79 |
margin: 0; |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?