feat: 카드·모달에 그림이 들어가는 예시 추가
카드는 이미 그림 슬롯이 있어 예시만 넣었고, 모달은 contents에 들어온 그림이 폭을 채우도록 규칙을 더했다. 자리표시 그림은 인라인 SVG로 둬서 @fox가 앱 이미지 경로에 기대지 않게 했다. Co-Authored-By: Claude Opus 5
@c9417c608a35407c1d325225f1998415c3cd6844
--- @fox/dev-test/component-registry.tsx
+++ @fox/dev-test/component-registry.tsx
... | ... | @@ -607,17 +607,21 @@ |
| 607 | 607 |
withUtility = false, |
| 608 | 608 |
withActions = true, |
| 609 | 609 |
closable = true, |
| 610 |
+ withImage = false, |
|
| 611 |
+ openLabel, |
|
| 610 | 612 |
}: {
|
| 611 | 613 |
size: "sm" | "md" | "lg" | "full"; |
| 612 | 614 |
title?: string; |
| 613 | 615 |
withUtility?: boolean; |
| 614 | 616 |
withActions?: boolean; |
| 615 | 617 |
closable?: boolean; |
| 618 |
+ withImage?: boolean; |
|
| 619 |
+ openLabel?: string; |
|
| 616 | 620 |
}) {
|
| 617 | 621 |
const [open, setOpen] = useState(false); |
| 618 | 622 |
return ( |
| 619 | 623 |
<> |
| 620 |
- <FoxButton size="md" type="secondary" label={`${size} 열기`} onAction={() => setOpen(true)} />
|
|
| 624 |
+ <FoxButton size="md" type="secondary" label={openLabel ?? `${size} 열기`} onAction={() => setOpen(true)} />
|
|
| 621 | 625 |
<FoxModal |
| 622 | 626 |
open={open}
|
| 623 | 627 |
onClose={() => setOpen(false)}
|
... | ... | @@ -638,12 +642,33 @@ |
| 638 | 642 |
) : undefined |
| 639 | 643 |
} |
| 640 | 644 |
> |
| 645 |
+ {/* 시안의 contents 슬롯에는 그림이 들어간 예가 있다 — 슬롯이라 무엇이든 놓을 수 있다. */}
|
|
| 646 |
+ {withImage && <DemoThumb />}
|
|
| 641 | 647 |
<p> |
| 642 | 648 |
대화 상자는 사용자에게 작업에 대해 알리고 중요한 정보를 포함하거나 결정이 필요하거나 |
| 643 | 649 |
여러 작업을 포함할 수 있습니다. |
| 644 | 650 |
</p> |
| 645 | 651 |
</FoxModal> |
| 646 | 652 |
</> |
| 653 |
+ ); |
|
| 654 |
+} |
|
| 655 |
+ |
|
| 656 |
+/** |
|
| 657 |
+ * 그림 자리 확인용 도형. 실제 사진 대신 쓴다 — `@fox`는 앱의 이미지 경로를 참조하지 않고 |
|
| 658 |
+ * (다른 프로젝트로 통째로 복사되어야 한다), 카탈로그가 외부 파일에 기대지도 않게 한다. |
|
| 659 |
+ * 토큰 색을 그대로 쓰므로 라이트·다크에서 함께 바뀐다. |
|
| 660 |
+ */ |
|
| 661 |
+function DemoThumb() {
|
|
| 662 |
+ return ( |
|
| 663 |
+ <svg viewBox="0 0 320 180" preserveAspectRatio="xMidYMid slice" aria-hidden="true"> |
|
| 664 |
+ <rect width="320" height="180" fill="var(--fox-color-surface-neutral-gray-strong)" /> |
|
| 665 |
+ <circle cx="232" cy="52" r="26" fill="var(--fox-color-element-theme-primary)" opacity="0.35" /> |
|
| 666 |
+ <path |
|
| 667 |
+ d="M0 148l72-52 54 38 60-46 134 92v0H0z" |
|
| 668 |
+ fill="var(--fox-color-element-neutral-default)" |
|
| 669 |
+ opacity="0.45" |
|
| 670 |
+ /> |
|
| 671 |
+ </svg> |
|
| 647 | 672 |
); |
| 648 | 673 |
} |
| 649 | 674 |
|
... | ... | @@ -3365,6 +3390,15 @@ |
| 3365 | 3390 |
), |
| 3366 | 3391 |
}, |
| 3367 | 3392 |
{
|
| 3393 |
+ label: "그림이 들어갈 때 — contents는 슬롯이라 무엇이든 놓입니다", |
|
| 3394 |
+ node: ( |
|
| 3395 |
+ <div className={styles.demoRow}>
|
|
| 3396 |
+ <ModalDemo size="md" title="타이틀" withImage openLabel="그림 있는 모달 열기" /> |
|
| 3397 |
+ <ModalDemo size="lg" title="타이틀" withImage openLabel="lg 그림 모달 열기" /> |
|
| 3398 |
+ </div> |
|
| 3399 |
+ ), |
|
| 3400 |
+ }, |
|
| 3401 |
+ {
|
|
| 3368 | 3402 |
label: "아래쪽 왼편 (utility) — 시안의 체크박스 자리", |
| 3369 | 3403 |
node: ( |
| 3370 | 3404 |
<div className={styles.demoRow}>
|
... | ... | @@ -3436,6 +3470,24 @@ |
| 3436 | 3470 |
"Figma 시안(card 441:6006)을 옮겼습니다. 크기 넷은 여백과 모서리만 바꿉니다 — 폭은 놓이는 자리가 정합니다(시안은 320px 자리에 뒀습니다). 그림은 16:9로 잘리고 상자가 모서리를 넘지 않게 자릅니다.", |
| 3437 | 3471 |
variants: [ |
| 3438 | 3472 |
{
|
| 3473 |
+ label: "그림이 있을 때 — 16:9로 잘리고 위쪽 모서리를 넘지 않습니다", |
|
| 3474 |
+ node: ( |
|
| 3475 |
+ <div className={styles.demoRow}>
|
|
| 3476 |
+ {(["xlg", "md"] as const).map((size) => (
|
|
| 3477 |
+ <div key={size} style={{ inlineSize: 320 }}>
|
|
| 3478 |
+ <FoxCard |
|
| 3479 |
+ size={size}
|
|
| 3480 |
+ image={<DemoThumb />}
|
|
| 3481 |
+ title="타이틀 영역" |
|
| 3482 |
+ description="간단한 설명이 들어가는 영역입니다." |
|
| 3483 |
+ actions={<FoxTextButton size="md" label="액션1" />}
|
|
| 3484 |
+ /> |
|
| 3485 |
+ </div> |
|
| 3486 |
+ ))} |
|
| 3487 |
+ </div> |
|
| 3488 |
+ ), |
|
| 3489 |
+ }, |
|
| 3490 |
+ {
|
|
| 3439 | 3491 |
label: "크기 — xlg · lg · md · sm (여백과 모서리가 달라집니다)", |
| 3440 | 3492 |
node: ( |
| 3441 | 3493 |
<div className={styles.demoRow}>
|
--- @fox/styles/_fox-modal.scss
+++ @fox/styles/_fox-modal.scss
... | ... | @@ -132,6 +132,14 @@ |
| 132 | 132 |
font-weight: fox.font-weight(regular); |
| 133 | 133 |
line-height: 1.5; |
| 134 | 134 |
letter-spacing: -0.025em; |
| 135 |
+ |
|
| 136 |
+ // 그림이 들어오면 폭을 채운다 — 시안의 contents 슬롯에 든 것도 폭 100%다. |
|
| 137 |
+ > img, |
|
| 138 |
+ > svg, |
|
| 139 |
+ > picture {
|
|
| 140 |
+ inline-size: 100%; |
|
| 141 |
+ block-size: auto; |
|
| 142 |
+ } |
|
| 135 | 143 |
} |
| 136 | 144 |
|
| 137 | 145 |
// ── 아래쪽 ──────────────────────────────────────────────────────────────── |
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?