CarouselBanner
캐러셀의 배너 슬라이드 — 썸네일 옆에 제목과 보조 문구가 붙는 가로 띠
목차
썸네일 하나와 제목·보조 문구가 가로로 붙는 얇은 홍보 띠입니다. Carousel(variant: .banner) 의 슬라이드로 들어갑니다.
기본 사용법#
Flutter#
Carousel(
variant: CoreCarouselVariant.banner,
items: [
CarouselBanner(
thumbnail: Image.asset('promo.png'),
title: Text('여름 세일'),
description: Text('전 품목 30% 할인'),
onTap: openSale,
),
],
)
Web#
Carousel(
variant: CoreCarouselVariant.banner,
items: [
CarouselBanner(
thumbnail: img(src: 'promo.png'),
title: Text('여름 세일'),
description: Text('전 품목 30% 할인'),
onTap: openSale,
),
],
)
Live Preview#
코드 보기
class CarouselBannerDefaultExample extends StatelessComponent {
const CarouselBannerDefaultExample({super.key});
@override
Component build(BuildContext context) {
return CarouselBanner(
thumbnail: const Icon(LucideIcons.image),
title: Text('New this week'),
description: Text('Three titles just landed'),
);
}
}
class CarouselBannerDefaultExample extends StatelessWidget {
const CarouselBannerDefaultExample({super.key});
@override
Widget build(BuildContext context) {
return CarouselBanner(
thumbnail: const Icon(LucideIcons.image),
title: Text('New this week'),
description: Text('Three titles just landed'),
);
}
}
사용 시기 (When to Use)#
이 컴포넌트를 사용하세요:
- 본문 위에 얇게 얹는 홍보 띠가 필요할 때 — 콘텐츠를 가리지 않는 높이(sm 88 / md 112)입니다.
-
여러 개를 순환시킬 때 —
Carousel(variant: .banner, items: [...])에 넣으면 점이 띠 아래에 놓이고 좌우 버튼은 기본으로 꺼집니다.
다른 것을 쓰세요:
- 미디어가 위에 오는 세로 카드가 필요하면
Card. 이 컴포넌트는 가로 띠이고, 그 둘은 값으로 서로의 모양이 되지 않습니다. - 순환 없이 한 번만 알리는 공지라면
Banner— 그쪽은 심각도 variant 와 닫기 버튼을 갖습니다.
왜 별도 컴포넌트인가#
띠의 내용은 슬라이드마다 다릅니다. 배너 세 장은 이것 세 개이고 각각 자기 그림과 문구를 갖습니다 — Carousel 의 필드로는 한 벌밖에 담을 수 없습니다. 그래서 캐러셀은 점이 어디 놓이는지를 말하고, 이 컴포넌트는 한 슬라이드가 무엇을 담는지 말합니다.
크기#
두 가지뿐입니다. 폼 안에서 커지고 작아지는 컨트롤이 아니라 화면 폭을 차지하는 띠라서, 선택은 "어느 화면인가" 이고 그 안의 모든 수치가 함께 움직입니다.
sm | md | |
|---|---|---|
| 안쪽 여백 | 16 | 20 |
| 썸네일 | 56 | 72 |
| 썸네일↔텍스트 | 12 | 16 |
| 제목 | titleSmall | titleMedium |
| 보조 문구 | bodySmall | bodyMedium |
| 띠 높이 | 88 | 112 |
높이는 썸네일이 정합니다 — 여백 + 썸네일 + 여백. 보조 문구를 끄거나 제목이 길어져도 높이는 그대로입니다.
띠의 모서리는 12(panel 역할)이고 그 안의 썸네일 상자는 8입니다. 같은 모서리를 두 번 쓰지 않는 이유는, 띠 안에 들어앉은 그림이 두 번째 띠로 읽히기 때문입니다.
썸네일 슬롯의 규칙#
슬롯에 무엇이 들어오는지에 따라 그리는 방식이 갈립니다.
-
아이콘(
Icon) 은 그림이 아니라 표시이므로 정사각 안에서 가운데에, 행이 정한 크기(sm24 /md28)와onSurfaceVariant색으로 그립니다. 상자를 채우지 않습니다.Icon이 자기 크기나 색을 직접 말하면 그것이 이깁니다. 획 두께는 필드가 아니라 크기가 정합니다(CoreIconStroke— 24 는 1.5). -
그림(이미지) 은 정사각을 채웁니다(Flutter). 넘치는 부분은 모서리에서 잘립니다. Web 은 호출자가 넣은
img를 가운데에 두고 넘치는 부분만 자르므로, 정사각을 채우려면img에 크기를 줍니다.
크기와 색은 thumbnailIconStyle 필드가 정하고, 행(defaultsBySize)마다 다른 값을 갖습니다.
Props / Parameters#
W 는 Flutter의 Widget, Web의 Jaspr Component 입니다. W?
는 선택 슬롯입니다.
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
size |
CoreCarouselBannerSize |
.sm |
두 크기 중 하나 |
thumbnail |
W? |
null |
앞머리 그림. null 이면 그리지 않고 텍스트가 폭을 다 씁니다 |
title | W? | null | 제목 |
description |
W? |
null |
보조 문구. null 이면 줄이 빠집니다 |
onTap |
void Function()? |
null |
탭 콜백. 주면 Clickable 이 감싸 키보드 활성화와 포커스 링을 얻습니다 |
carouselBannerStyle |
CoreCarouselBannerStyle? |
null |
chrome 단일 진입점 |
스타일 시스템 (Style System)#
- 시맨틱 식별자:
size— 위젯 파라미터로 남습니다. - chrome / dimensional / 슬롯 스타일:
CoreCarouselBannerStyle한 곳으로.
withStyle 체인도 양 플랫폼 동일하게 씁니다.
CarouselBanner(title: Text('여름 세일')).withStyle(
CoreCarouselBannerStyle(
backgroundColor: CoreColor.token(CoreColors.secondaryContainer),
),
)
Resolve chain: CoreCarouselBannerStyle.defaultsBySize[size] → theme.carouselBanner.style
→ 인스턴스 carouselBannerStyle.
CoreCarouselBannerStyle 필드#
| 필드 | 타입 | 설명 |
|---|---|---|
backgroundColor |
CoreColor? |
Strip fill override. null → [defaultBackgroundColor]. |
borderRadius |
CoreBorderRadius? |
Strip corner override. null → [defaultBorderRadius]. |
padding |
CoreEdgeInsets? |
Strip inset override. null → [defaultsBySize] for the active size. |
thumbnailSize |
double? |
Thumbnail side length override (logical px).
null
→ [defaultsBySize] for the active size. The thumbnail is square, and it is what sets the strip's height: inset + this + inset.
|
thumbnailBorderRadius |
CoreBorderRadius? |
Thumbnail corner override. null → [defaultThumbnailBorderRadius]. |
thumbnailBackgroundColor |
CoreColor? |
Thumbnail placeholder fill override. null → [defaultThumbnailBackgroundColor]. |
thumbnailIconStyle |
CoreIconStyle? |
How an
Icon
handed to the thumbnail slot is drawn — its size and its colour.
null
→ [defaultsBySize] for the active size. The slot's rule has two halves, and this field is the first: an icon is centred in the square at this size, in this colour, and an image fills the square. An
Icon
that states its own size or colour keeps it. The stroke is not a field here — it is a function of the size (
CoreIconStroke
).
|
thumbnailTextGapStyle |
CoreGapStyle? |
Thumbnail → text column spacer. null → [defaultsBySize] for the active size. |
titleDescriptionGapStyle |
CoreGapStyle? |
Title → description spacer. null → [defaultsBySize] for the active size. |
titleStyle |
CoreTextStyle? |
Title typography override. null → [defaultsBySize] for the active size. |
descriptionStyle |
CoreTextStyle? |
Description typography override. null → [defaultsBySize] for the active size. |
동작 스펙 (Behavior)#
- 썸네일이 있으면 정사각 썸네일 → 간격 → 제목·설명 열을 배치합니다. 없으면 썸네일과 그 간격을 생략합니다. 제목·설명 중 빠진 슬롯도 그리지 않습니다.
-
onTap이 있으면Clickable을 합성해 탭 · Enter · Space에서 콜백을 실행합니다. 없으면 표시용 띠이며 별도enabled값은 없습니다. -
순환 타이머·이전/다음·점 인디케이터는 이 컴포넌트에 없습니다. 순환이 필요하면 Carousel
의
items로 넣습니다. 심각도 공지와 닫기 액션이 필요하면 Banner 입니다. - 크기는 썸네일·패딩·텍스트로 결정됩니다. 썸네일을 생략한 띠가 썸네일이 있을 때의 88 / 112 논리 px 높이를 자동으로 유지하는 것은 아닙니다.
사용 가이드라인 (Usage Guidelines)#
- 문구는 짧게. 제목은 한 줄, 보조 문구도 한 줄입니다 — 띠 높이는 썸네일이 정하고 텍스트가 두 줄이 되면 줄이 잘립니다.
- 썸네일은 정사각 그림. 박스가 정사각이고 넘치는 부분은 잘립니다. 세로 사진을 넣으면 가운데만 보입니다.
-
순환은 자동 재생과 스와이프로.
banner는 좌우 버튼이 기본으로 꺼져 있습니다. 버튼이 필요하면showNavigation: true로 명시하되, 88 높이에서는 원판이 띠를 덮습니다. -
본문 흐름을 가리지 않는 자리에. 이 컴포넌트가 얇은 이유가 그것입니다 — 화면을 채우는 홍보에는
Carousel(variant: .slide)를 쓰세요.
접근성 (Accessibility)#
역할#
-
onTap을 주면Clickable이role="button"과 탭 순서를 붙이고 키보드 활성화를 받습니다. 마우스로만 되는 띠가 되지 않습니다. Flutter 에서는 같은 합성 컴포넌트의 버튼 시맨틱을 씁니다.onTap이 없으면 표시 전용 띠이며 버튼 역할이 없습니다.
키보드#
탭 가능한 띠는 Tab 으로 도달하고 Enter / Space 로 onTap 을 실행합니다.
슬라이드 전환·자동 재생·점 이동은 부모 Carousel 이 소유합니다.
스크린 리더#
이름은 title / description 슬롯의 텍스트에서 옵니다. 썸네일의 대체 텍스트는
호출자가 넣은 이미지가 제공하며, 띠 자체에는 별도 상태 통보 리전이 없습니다.
포커스 관리#
띠는 포커스를 자동으로 옮기거나 가두지 않습니다. onTap 이 있으면 Clickable
이 포커스 링을 그리고, 캐러셀의 활성 슬라이드 정책은 부모가 관리합니다.
알려진 제약#
이미지 대체 텍스트나 이름 없는 슬롯을 자동으로 보완하지 않습니다. 제목·보조 문구는 한 줄로 그려지므로 긴 텍스트와 큰 글자 배율에서 잘림을 확인하세요.
-
제목과 보조 문구는 같은
onPrimaryContainer토큰을 씁니다 — 색이 있는 배경에서 회색은 두 번째 단계로 읽히지 않고 읽히지 않는 것으로 읽히므로, 위계는 굵기가 담당합니다.
크로스 플랫폼 차이점 (Platform Differences)#
| 항목 | Flutter | Web |
|---|---|---|
| 띠 배치 | Row + Expanded 텍스트 열 | flex 루트 · 텍스트 래퍼 |
| 썸네일 클립 | SizedBox.square + ClipRRect |
썸네일 <div> 의 크기·overflow |
썸네일 안의 Icon |
Icon
이면
Center
로 감싸 행의 아이콘 크기·색(
IconTheme
)으로 그림. 그 밖의 위젯은 정사각의 tight 제약으로 채움
|
썸네일
<div>
가 flex 가운데 정렬이라 행의 크기·색(
IconTheme
)으로 가운데에 놓임.
img
는 채우지 않고 가운데에 놓임
|
| 눌리는 띠 의미 | Clickable 의 button 시맨틱 |
Clickable 의 role / tabindex |
| 호스트 속성 | 호출부 래퍼·key |
인터랙티브이면 id / 속성 / 이벤트가 Clickable 루트로 이동 |