Bixby Developer Center

Guides
References

구성 요소 및 레이아웃 패턴

이 주제에서는 시각적 디자인 팁을 소개하고, 상황에 따라 특정한 구성 요소 및 레이아웃 패턴을 사용하는 것이 적합한 이유를 자세히 설명합니다.

Note

Thumbnail Card의 이미지용 image-object-fit 키(key)와 같이, 코드 샘플 내에서 사용되는 다양한 자식 키(key)에 대한 자세한 내용은 이 문서에 안내된 여러 구성 요소의 참조 페이지에서 확인할 수 있습니다. 특히 디자인 측면에서 구성 요소 사양에 대한 자세한 내용은 디자인 리소스 아래에 있는 구성 요소 사양 다운로드에서 확인하세요.

다중 결과

다중 결과는 카드 목록으로 표시해야 합니다. Bixby 구성 요소 라이브러리에는 5가지 유형의 카드가 있습니다. 해당 캡슐의 정보 계층에 가장 적합한 카드를 사용하도록 합니다.

image-card v1image-card v2thumbnail-cardtitle-cardcell-card
image-cardimage-cardthumbnail-cardtitle-cardcell-card

image-card v1은 text-positionBelow로 설정되어 있고 v2는 Overlay로 설정되어 있습니다.

Image Card

Image card는 이미지에 사용자가 결정을 내리는 데 있어 반드시 고려해야 하는 중요 정보가 포함되어 있을 때 사용합니다. 동적인 고해상도 이미지를 사용하면 시각적 효과를 얻을 수 있습니다.

예를 들어, 다음과 같은 이미지를 사용할 수 있습니다.

  • 아티스트 포스터
  • 음식 사진
  • 제품 클로즈업
  • 아름다운 자연 경관

텍스트 위치 - Below텍스트 위치 - Overlay
image-card v1image-card v2

예제 1: Below

image-card v1

image-card {
text-position (Below)
image-background-color (White)
image-object-fit (Contain)
aspect-ratio (16:9)
image-url {
template ("[#{value (spaceResort.images[0].url)}]")
}
title-area {
halign (Start)
slot1 {
text {
value {
template ("Venus Space Spa")
}
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa")
}
}
}
}
}
예제 2: Overlay

image-card v2

image-card {
text-position (Overlay)
image-background-color (White)
image-object-fit (Contain)
aspect-ratio (1:1)
image-url {
template ("[#{value(spaceResort.images[0].url)}]")
}
title-area {
slot1 {
text {
value ("#{value(spaceResort.name)}")
style (Title_L)
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa")
}
}
}
}
}

Thumbnail Card

Thumbnail card는 추가하는 이미지가 부수 정보인 경우에 유용합니다. 뉴스 헤드라인과 같이 이미지가 그다지 중요하지 않은 목록에도 적합합니다. 썸네일 영역에는 그림이나 아이콘을 사용할 수 있고 사용자가 제공하는 저해상도 이미지를 사용해도 괜찮습니다.

예를 들면 뉴스 아이콘, 인물 사진, 저해상도 이미지 등을 모두 사용할 수 있습니다.

오른쪽 썸네일왼쪽 썸네일
thumbnail-card v1thumbnail-card v2

예제 1: 이미지를 오른쪽에 배치

thumbnail-card v1

thumbnail-card {
image-aspect-ratio (1:1)
image-object-fit (Cover)
image-position (End)
image-url {
template ("images/planet.png")
}
title-area {
halign (Start)
slot1 {
text {
value {
template ("Venus Space Spa")
}
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa")
}
}
}
}
}
예제 2: 이미지를 왼쪽에 배치

thumbnail-card v2

thumbnail-card {
image-aspect-ratio (3:4)
image-object-fit (Cover)
image-position (Start)
image-url {
template ("images/planet.png")
}
title-area {
halign (Start)
slot1 {
text {
value {
template ("Venus Space Spa")
}
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa")
}
}
}
}
}

Title Card

인상적인 디자인을 위해 반드시 이미지를 사용할 필요는 없습니다. 관련 이미지가 없다면 title-card와 큼지막한 텍스트를 사용해 강렬한 인상을 줄 수 있습니다. 단, 정보 계층을 유지하기 위해서는 표시되는 텍스트 정보를 일정 수준으로 제한해야 합니다.

왼쪽 맞춤가운데 맞춤
title-card v1title-card v2

예제 1: 왼쪽 맞춤

title-card v1

title-card {
title-area {
halign (Start)
slot1 {
text {
value {
template ("Venus Space Spa")
}
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa")
}
}
}
}
}
예제 2: 가운데 맞춤

title-card v2

 title-card {
title-area {
halign (Center)
slot1 {
text {
value {
template ("Venus Space Spa")
}
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa")
}
}
}
}
}

Cell Card

Cell-card에는 아바타 이미지와 간단한 정보를 담은 한 줄 텍스트를 사용하는 것이 가장 좋습니다.

cell-card

cell-card {
slot1 {
image {
url {
template ("images/planet.png")
}
shape (Circle)
}
slot2 {
content {
order (SecondaryPrimary)
primary {
template ("Venus Space Spa")
}
secondary {
template ("Venus • 0.904g")
}
}
}
}

Compound Card

요구 사항에 꼭 맞는 카드 유형이 없다면 compound-card를 사용해 커스터마이즈된 카드를 생성할 수 있습니다.

예제 1: Compound Card

compound-card

compound-card {
content {
single-line {
image {
background-color (Transparent)
shape (Circle)
style (Title_XXL)
url {
template ("images/planet.png")
}
}
}
single-line {
text {
value {
template ("Venus Space Spa")
}
}
}
paragraph {
value {
template ("It's no wonder the most romantic resort is on the planet named after the Roman goddess of love and beauty.")
}
}
}
}
예제 2: 비교 Compound Card

이 레이아웃도 compound-card를 사용하고 있습니다. 예를 들어 스포츠 토너먼트에 이 카드를 사용해 점수를 표시할 수 있습니다.

compound-card

compound-card {
content {
hbox {
content {
vbox {
halign (Center)
content {
single-line {
image {
background-color (Transparent)
shape (Circle)
style (Title_XXL)
url {
template ("images/Earth.png")
}
}
}
single-line {
text {
value {
template ("Earth")
}
style (Title_XS)
}
}
single-line {
text {
value {
template ("Depart")
}
style (Detail_M)
}
}
}
}
vbox {
halign (Center)
valign (Bottom)
content {
single-line {
image {
background-color (Transparent)
shape (Square)
url {
template ("images/spaceShip.png")
}
}
}
}
}
vbox {
halign (Center)
content {
single-line {
image {
background-color (Transparent)
shape (Circle)
style (Title_XXL)
url {
template ("images/Venus.png")
}
}
}
single-line {
text {
value {
template ("Venus")
}
style (Title_XS)
}
}
single-line {
text {
value {
template ("Arrive")
}
style (Detail_M)
}
}
}
}
}
}
}
}

단일 결과

이 섹션에서는 다양한 유형의 단일 결과 레이아웃을 설명합니다.

세부 정보 레이아웃

세부 정보 레이아웃에는 특정 항목에 대한 세부 정보가 표시됩니다. 예를 들어 우주 리조트(Space Resorts) 캡슐에서는 이 레이아웃에 특정 우주 리조트에 대한 세부 정보를 표시할 수 있습니다.

이미지가 중요한 정보인 경우 맨 위에 image-carousel을 사용하도록 하세요.

Detail 레이아웃 with Image Carousel

이미지는 사용자가 결정하는 데 참고할 수 있도록 제품의 세부 사항을 표시하려고 할 때 유용합니다. 호텔 객실이나 식당 인테리어 등을 보여주는 데에도 좋습니다. 또한 아티스트 포스터, 먹음직스러운 음식 사진, 제품 클로즈업, 자연 경관 등의 고해상도 이미지를 사용하면 역동적인 인상을 심어줄 수 있습니다.

우주 리조트(Space Resorts) 캡슐에 다음과 같은 완전한 예제가 있습니다.

Detail 레이아웃 with Image Carousel

이 레이아웃에는 다음과 같은 구성 요소가 사용되었습니다.

  1. image-carousel
  2. title-area
  3. single-line(아이콘과 텍스트를 한 줄에 함께 사용)
  4. paragraph
  5. 별도 section으로 이루어진 thumbnail-card(객실 목록 표시)

해당 코드는 다음과 같습니다.

//header
section {
content{
image-card {
text-position (Below)
image-background-color (White)
image-object-fit (Contain)
aspect-ratio (16:9)
image-url {
template ("images/planet.jpg")
}
title-area {
halign (Start)
slot1 {
text {
value {
template ("Venus Space Spa")
}
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa | Swimming Pool")
}
}
}
}
}
single-line {
image {
url {
template ("images/starRating.png")
}
}
text {
value {
template ("(280 reviews)")
}
}
}
}
}

// Rooms list
section {
title{
template("Rooms")
}
content {
for-each (roomList) {
as (room){
thumbnail-card {
image-aspect-ratio (9:16)
image-object-fit (Cover)
image-position (End)
image-url {
template ("images/planet.png")
}
title-area {
halign (Start)
slot1 {
text {
value {
template ("#{value (room.price)}")
}
}
}
slot2 {
paragraph {
value {
template ("Room #{i}")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa | Swimming Pool")
}
}
}
}
}
}
}
}
}

이미지가 그다지 중요하지 않은 경우에는 텍스트만으로도 인상적인 디자인을 만들 수 있습니다.

인상적인 디자인을 위해 반드시 큰 이미지를 사용할 필요는 없습니다. slot1title-area에 큼지막한 텍스트를 사용하면 강렬한 인상을 줄 수 있습니다. 레이아웃에서 적절하고 효과적인 제목 아래에 image-list를 추가하는 것도 좋은 방법입니다. 이미지 목록은 세 개의 이미지를 마스킹하고 표시할 수 있습니다. 이 레이아웃에 compound-card를 사용하면 커스터마이즈된 카드를 생성할 수 있습니다.

Detail Layout with Image Carousel

우주 리조트(Space Resorts) 캡슐에 다음과 같은 완전한 예제가 있습니다.

Detail Layout with Image List

이 레이아웃에는 다음과 같은 구성 요소가 사용되었습니다.

  1. title-area(slot1의 텍스트 스타일은 Title_L로, slot2의 텍스트 스타일은 Detail_L로 각각 설정되어 있음)
  2. single-line(스타일을 Detail_L로 설정하여 아이콘과 텍스트를 한 줄에 함께 사용)
  3. image-list
  4. partitioned(객실 편의 시설 목록 표시)
  5. 별도 section으로 이루어진 paragraph(객실 목록 표시)

해당 코드는 다음과 같습니다.

section {
content{
title-area {
halign (Start)
slot1 {
text {
value {
template ("Venus Space Spa")
}
style (Title_L)
}
}
slot2 {
paragraph {
value {
t emplate ("Venus • 0.904g")
}
style (Detail_L)
}
}
slot3 {
single-line {
image {
url {
template ("images/starRating.png")
}
style (Detail_L)
}
text {
value {
template ("(280 reviews)")
}
style (Detail_L)
}
}
}
}
image-list {
images (resort.images)
}
partitioned {
content {
for-each (resort.features) {
as (feature) {
paragraph {
value {
template ("#{value (feature.description)}")
}
}
}
}
}
}
}
}
section {
title{
template("About our resort")
}
content {
paragraph {
value {
template ("#{value (resort.description)}")
}
}
}
}

완료 Moment 레이아웃

특정 액션이 완료되었음을 확인하려는 경우에 receipt가 필요 없는 상황이라면 단순한 레이아웃을 생성하여 사용자에게 완료(Done) moment를 표시할 수 있습니다. 이 레이아웃은 만들 수 있는 결과 view 중에서 가장 단순합니다.

Detail Layout with Image List

이 레이아웃에는 다음과 같은 구성 요소가 사용되었습니다.

  1. single-line(Title_XXL에 이미지만 사용)
  2. paragraph(Title_M 텍스트 스타일 사용)
  3. attribution-link(사용자가 추가 정보를 원할 경우 외부로 이동(punch out)하는 데 필요)

해당 코드는 다음과 같습니다.

single-line {
image {
url {
template ("images/planet.png")
}
}
}
paragraph {
value {
template ("It is currently....")
}
style (Title_M)
}
attribution-link {
label {
template ("More on CP name")
}
url ("https://bixbydevelopers.com/dev/docs/sample-capsules/walkthroughs/space-resorts")
}

Receipt 레이아웃

이 레이아웃은 구매와 같은 트랜잭션 워크플로우를 완료한 후에 표시하는 "완료(done)" moment에 사용하기 좋습니다.

Receipt 1 Receipt 2

Code TBD

Input 받기

사용자에게 정보를 받아야 할 경우 picker를 사용할 수 있습니다. 항목 목록을 제공하여 사용자가 간단히 선택하는 방식으로 정보를 받으려면 선택 레이아웃을 적절히 구성하여 사용하면 됩니다.

선택 레이아웃

선택 레이아웃은 Input view에서 selection-of 키(key)를 사용하여 만듭니다. 이 목록 내에서는 카드를 사용해야 합니다.

Cell CardTitle CardCompound Card
Cell CardTitle CardCompound Card
Cell Card 예제
//cell-card
selection-of (roomList){
where-each (room) {
cell-card {
slot1 {
image {
url {
template ("#{value (room.image)}")
}
shape (Circle)
}
}
slot2 {
content {
order (SecondaryPrimary)
primary {
template ("#{value (room.name)}")
}
secondary {
template ("#{value (room.gravity)}")
}
}
}
}
}
}
Title Card 예제
//title-card
selection-of (roomList){
where-each (room) {
title-card {
title-area {
halign (Start)
slot1 {
text {
value {
template ("#{value (room.price)}")
}
}
}
slot2 {
paragraph {
value {
template ("#{value (room.gravity)}")
}
}
}
slot3 {
paragraph {
value {
template ("#{value (room.window)}")
}
}
}
}
}
}
}
Compound Card 예제
//compound-card
selection-of (roomList){
where-each (room) {
compound-card {
content {
title-area {
halign (Start)
slot1 {
text {
value {
template ("#{value (room.price)}")
}
}
}
slot2 {
paragraph {
value {
template ("#{value (room.gravity)}")
}
}
}
slot3 {
paragraph {
value {
template ("#{value (room.window)}")
}
}
}
}
image-list {
images (room.images)
}
}
}
}
}

확인하기(Confirming)

확인(confirmation) moment에서는 다양한 옵션을 사용할 수 있는데, 핵심 포인트만 간단히 요약하면 다음과 같습니다.

우주 리조트(Space Resorts) 캡슐에 다음과 같은 완전한 예제가 있습니다.

Confirmation 레이아웃

이 레이아웃에는 다음과 같은 구성 요소가 사용되었습니다.

  1. image-card
  2. split-input-cellinput-cell
  3. payment-selection
  4. 여러 vbox가 포함된 hbox 구성 요소(대부분의 항목에는 Detail_M_Soft 텍스트 스타일 사용, 눈에 띄게 만들 줄(예: "지금 결제할 총액")에는 Detail_L 텍스트 스타일 사용)
  5. single-line
  6. paragraph(Legal 텍스트 스타일 사용)

해당 코드는 다음과 같습니다.

section {
content{
image-card {
text-position (Below)
image-background-color (White)
image-object-fit (Contain)
aspect-ratio (16:9)
image-url {
template ("images/planet.jpg")
}
title-area {
halign (Start)
slot1 {
text {
value {
template ("Venus Space Spa")
}
}
}
slot2 {
paragraph {
value {
template ("Venus • 0.904g")
}
}
}
slot3 {
paragraph {
value {
template ("Cryo Spa | Swimming Pool")
}
}
}
}
}
split-input-cell {
left {
input-cell {
label {
template ("Room")
}
value {
template ("Room 1")
}
}
}
right {
input-cell {
label {
template ("Guests")
}
value {
template ("2")
}
}
}
}
input-cell {
label {
template ("Stay Dates")
}
value {
template ("September 11 - 16")
}
}
}
}

section {
title {
template ("Contact Information")
}
content {
input-cell {
label {
template ("Name")
}
value {
template ("[#{value(cart.event.boxOffice.recipient.firstName)}][ #{value(cart.event.boxOffice.recipient.lastName)}]")
}
}
input-cell {
label {
template ("Phone number")
}
value {
template ("[#{value(cart.event.boxOffice.recipient.phoneNumber)}]")
}
}
input-cell {
label {
template ("Email")
}
value {
template ("[#{value(cart.event.boxOffice.recipient.emailAddress)}]")
}
}
}
}

section {
content{
payment-selection
}
}

section {
content{
hbox {
content {
vbox {
halign (Start)
content {
text {
value {
template ("Room")
}
style (Detail_M_Soft)
}
text {
value {
template ("Taxes and Fees")
}
style (Detail_M_Soft)
}
text {
value {
template ("Booking Fee")
}
style (Detail_M_Soft)
}
text {
value {
template ("Total to pay now:")
}
style (Detail_L)
}
text {
value {
template ("Mandatory fees collected at hotel")
}
style (Detail_M_Soft)
}
}
}
vbox {
halign (End)
content {
text {
value {
template ("[#{value (cost.room)}]")
}
style (Detail_M_Soft)
}
text {
value {
template ("[#{value (cost.fee)}]")
}
style (Detail_M_Soft)
}
text {
value {
template ("[#{value (cost.booking)}]")
}
style (Detail_M_Soft)
}
text {
value {
template ("[#{value (cost.grandTotal)}]")
}
style (Detail_L)
}
text {
value {
template ("[#{value (cost.feeAtHotel)}]")
}
style (Detail_M_Soft)
}
}
}
}
}
}
}

section {
title{
template("Reservation Terms")
}
content{
paragraph{
value {
template ("#{value (terms)}")
}
style (Legal)
}
}
}