Cards

Cards contain content and actions about a single subject.


Page Summary


Specifications references

Accessibility

Please follow accessibility criteria for development

Images in cards are considered as decorative, so they are ignored by Voice Over.

Variants

Cards are a contained and independent element that can display content and actions on a single topic.

There are a few ways cards can be presented. Ranging from a single title on its own for a simple card view or with more information shown in a subtitle and supporting text and actions at the bottom of the card.

Vertical Image First Card

This is a full width card displayed with an image as first element.

This card is composed of two parts:

  • Media: (today an image)
  • Content: with a title, an optinal subtitle an optinal supporting text and optional buttons (zero up to two)

Implementation

Card is configured using ODSCardVerticalHeaderFirstModel like this:

let model = ODSCardVerticalImageFirstModel(
    title: "Title",
    subtitle: "Subtitle",
    image: Image("ods_empty", bundle: Bundle.ods),
    supportingText: "A supporting text to describe something")
    
ODSCardVerticalImageFirst(model: model) {
    ODSButton(text: "Button 1", emphasis: .medium) {
            // do something here
        }
    } buttonContent2: {
        ODSButton(text: "Button 1", emphasis: .medium) {
            // do something here
        } 
    }
}

Vertical Header First Card

This is a full width card displaying with a title and a thumbnail on top as first element.

This card is composed of three parts:

  • Header: with a title, an optinal subtitle and an optinal thmubnail
  • Media: (today an image)
  • Content: with an optinal supporting text and optional buttons (zero up to two)

Implementation

Card is configured using ODSCardVerticalHeaderFirstModel like this:

let model = ODSCardVerticalHeaderFirstModel(
    title: "Title",
    subtitle: "Subtitle",
    thumbnail: Image("ods_empty", bundle: Bundle.ods),
    image: Image("ods_empty", bundle: Bundle.ods),
    supportingText: "A supporting text to describe something")
    
ODSCardVerticalHeaderFirst(model: model) {
    ODSButton(text: "Button 1", emphasis: .medium) {
            // do something here
        }
    } buttonContent2: {
        ODSButton(text: "Button 1", emphasis: .medium) {
            // do something here
        } 
    }
}

Horizontal Card

This is a full width card displaying with image on left and content with texts on the right. Additonal action buttons can be added at the bottom of the card.

Thes content is composed by:

  • a title
  • an optional subtitle
  • an optional supporting text for larger description

Implementation

Card is configured using ODSCardHorizontalModel like this:

let model = ODSCardHorizontalModel(
    title: "Title",
    subtitle: "Subtitle",
    imageSource: .image(Image("ods_empty", bundle: Bundle.ods)),
    imagePosition: .leading,
    supportingText: "A supporting text to describe something")
    
ODSCardHorizontal(model: model) {
    ODSButton(text: "Button 1", emphasis: .medium) {
            // do something here
        }
    } buttonContent2: {
        ODSButton(text: "Button 1", emphasis: .medium) {
            // do something here
        } 
    }
}

Small Card

The small card if prefered for two-column portrait mobile screen display. As it is smaller than full-width cards, it contains only title and subtitle (optinal) in one line (Truncated tail).

Implementation

Card is configured using ODSCardSmallModel like this:

let model = ODSCardSmallModel(
    title: "Title",
    subtitle: "Subtitle",
    image: Image("ods_empty", bundle: Bundle.ods)) 

ODSCardSmall(model: model)

How to add Small Card in Grid

let models = [
    ODSCardSmallModel(
        title: "Title 1",
        subtitle: "Subtitle 1",
        image: Image("ods_empty", bundle: Bundle.ods)) { 
            Text("This card has a destination view")
        },
    ODSCardSmallModel(
        title: "Title 2",
        subtitle: "Subtitle 2",
        image: Image("ods_empty", bundle: Bundle.ods)) { 
            Text("This card has a destination view")
        },
    //...
    ]

/// /!\ Don't forget to put the grid into a scrollview
ScrollView {
    LazyVGrid(columns: columns, spacing: ODSSpacing.none) {
        ForEach(models) { model in
            ODSCardSmall(model: model)
        }
        .padding(.bottom, ODSSpacing.m)
    }
}