Carousel

fun Carousel(state: LazyListState, count: Int, dismissParams: DismissParams?, modifier: Modifier = Modifier, itemSpacing: Boolean = false, reverseScrollDirection: Boolean = false, isScrollEnabled: Boolean = true, variant: CarouselVariant = SlideShow, key: (page: Int) -> Any? = null, flingBehavior: FlingBehavior? = null, a11ySkipListing: A11ySkipListing? = null, navButtonParams: NavButtonParams? = null, content: @Composable (page: Int) -> Unit)

Carousel is a container used to horizontally slide or cycle through content placed inside of it. This Implementation does not have a counter badge on display.

Parameters

state

LazyListState to handle list of items.

count

number of total items in list.

dismissParams

action parameter for dismiss button in theatre variant.

modifier

Modifier to be applied to the Carousel layout.

itemSpacing

Boolean to add padding of space150 (24.dp) between items.

reverseScrollDirection

Boolean to reverse scroll direction.

isScrollEnabled

Boolean to handle if scrolling is enabled.

variant

CarouselVariant defines which variant of the carousel. The default value is CarouselVariant.SlideShow.

key

a factory of stable and unique keys representing the item.

flingBehavior

logic describing fling behavior, and animate the scroll state. Default animation for CarouselVariant.SlideShow and CarouselVariant.Theatre is snapping and for CarouselVariant.Overflow is free scrolling

a11ySkipListing

the A11ySkipListing class enable the accessibility functionality to skip all the items of the carousel when using talkback navigation. You will need to add A11ySkipListing.listTitle to your carousel, a localized label such as "Skip listing" using A11ySkipListing.actionLabel that will move the focus using to the desired item using A11ySkipListing.nextItemFocusRequester.

navButtonParams

NavButtonParams to add navigation button data to the component.

content

a block which describes the content. Inside this block you can use methods like LazyListScope.item to add a single item or LazyListScope.items to add a list of items.

See also

Samples

import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
val context = LocalContext.current
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    val a11ySkipListing = A11ySkipListing("Carousel", "Skip listing", remember { FocusRequester() })
    Column {
        Carousel(
            count = listItem.size,
            state = listState,
            variant = CarouselVariant.SlideShow,
            dismissParams = null,
            a11ySkipListing = a11ySkipListing
        ) { page ->
            Image(
                modifier = Modifier
                    .clickable { Toast.makeText(context, "Do something", Toast.LENGTH_LONG).show() },
                painter = listItem[page].image,
                contentDescription = listItem[page].contentDes,
                contentScale = ContentScale.FillWidth
            )
        }
        Text(
            text = "Next focusable element, lorem ipsum dolor sit amet, consectetur adipiscing elit, " +
                "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
            modifier = Modifier
                .focusRequester(a11ySkipListing.nextItemFocusRequester)
                .focusable(true)
        )
    }
} 
   //sampleEnd
}
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Carousel(
        count = listItem.size,
        state = listState,
        variant = CarouselVariant.Theatre,
        dismissParams = DismissParams(
            onDismissRequest = {
                // Pop backstack or dismiss sheet
            },
            dismissButtonContentDescription = "Close"
        )
    ) { page ->
        Image(
            painter = listItem[page].image,
            contentDescription = listItem[page].contentDes,
            contentScale = ContentScale.Fit
        )
    }
} 
   //sampleEnd
}
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem = listOf("section  1", "section  2", "section  3", "section  4", "section  5")
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Carousel(
        count = listItem.size,
        state = listState,
        variant = CarouselVariant.Overflow,
        itemSpacing = true,
        dismissParams = null
    ) { page ->
        val context = LocalContext.current
        Column(
            modifier = Modifier
                .width(250.dp)
                .semantics(true) { }
        ) {
            Box(
                modifier = Modifier
                    .height(150.dp)
                    .fillMaxWidth()
                    .background(Color(0x66CCCCCC))
            )
            Box(
                modifier = Modifier
                    .height(250.dp)
                    .fillMaxWidth()
                    .background(Color(0xFF56b8ff))
            ) {
                Column(
                    modifier = Modifier
                        .align(Alignment.BottomCenter)
                        .fillMaxWidth()
                        .padding(32.dp),
                    verticalArrangement = Arrangement.Center
                ) {
                    Text(text = listItem[page], style = SkapaTheme.typography2.bodyM.copy(color = SkapaTheme.colors.textAndIcon1))
                    Button(label = "Click me!", modifier = Modifier.fillMaxWidth()) {
                        Toast.makeText(context, "${listItem[page]} clicked", Toast.LENGTH_LONG).show()
                    }
                }
            }
        }
    }
} 
   //sampleEnd
}
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
val context = LocalContext.current
val a11ySkipListing = A11ySkipListing("Carousel", "Skip listing", remember { FocusRequester() })

SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Column(verticalArrangement = Arrangement.SpaceBetween) {
        Carousel(
            count = listItem.size,
            state = listState,
            variant = CarouselVariant.SlideShow,
            dismissParams = null,
            a11ySkipListing = a11ySkipListing
        ) { page ->
            Image(
                modifier = Modifier
                    .clickable { Toast.makeText(context, "Do something", Toast.LENGTH_LONG).show() },
                painter = listItem[page].image,
                contentDescription = listItem[page].contentDes,
                contentScale = ContentScale.FillWidth
            )
        }
        Text(
            text = "Next focusable element",
            modifier = Modifier
                .focusRequester(a11ySkipListing.nextItemFocusRequester)
                .focusable(true)
        )
    }
} 
   //sampleEnd
}

fun Carousel(state: LazyListState, count: Int, counterBadgeFormatter: (Int) -> String, dismissParams: DismissParams?, modifier: Modifier = Modifier, itemSpacing: Boolean = false, reverseScrollDirection: Boolean = false, isScrollEnabled: Boolean = true, variant: CarouselVariant = SlideShow, key: (page: Int) -> Any? = null, flingBehavior: FlingBehavior? = null, a11ySkipListing: A11ySkipListing? = null, navButtonParams: NavButtonParams? = null, content: @Composable (page: Int) -> Unit)

Carousel is a container used to horizontally slide or cycle through content placed inside of it. This Implementation has a counter badge on display and is accessed through the counterBadgeFormatter property, if you choose CarouselVariant.Overflow the counter will no be shown.

Parameters

state

LazyListState to handle list of items.

count

number of total items in list.

counterBadgeFormatter

function that returns the formatted counter text to display, given the current page

dismissParams

action parameter for dismiss button in theatre variant.

modifier

Modifier to be applied to the Carousel layout.

itemSpacing

Boolean to add padding of space150 (24.dp) between items.

reverseScrollDirection

Boolean to reverse scroll direction.

isScrollEnabled

Boolean to handle if scrolling is enabled.

variant

CarouselVariant defines which variant of the carousel. The default value is CarouselVariant.SlideShow.

key

a factory of stable and unique keys representing the item.

flingBehavior

logic describing fling behavior, and animate the scroll state. Default animation for CarouselVariant.SlideShow and CarouselVariant.Theatre is snapping and for CarouselVariant.Overflow is free scrolling

a11ySkipListing

the A11ySkipListing class enable the accessibility functionality to skip all the items of the carousel when using talkback navigation. You will need to add A11ySkipListing.listTitle to your carousel, a localized label such as "Skip listing" using A11ySkipListing.actionLabel that will move the focus using to the desired item using A11ySkipListing.nextItemFocusRequester.

navButtonParams

NavButtonParams to add navigation button data to the component.

content

a block which describes the content. Inside this block you can use methods like LazyListScope.item to add a single item or LazyListScope.items to add a list of items.

See also

Samples

import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
val context = LocalContext.current
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Carousel(
        count = listItem.size,
        state = listState,
        variant = CarouselVariant.SlideShow,
        dismissParams = null,
        counterBadgeFormatter = { count ->
            return@Carousel "$count of ${listItem.size}"
        }
    ) { page ->
        Image(
            modifier = Modifier
                .clickable { Toast.makeText(context, "Do something", Toast.LENGTH_LONG).show() },
            painter = listItem[page].image,
            contentDescription = listItem[page].contentDes,
            contentScale = ContentScale.FillWidth
        )
    }
} 
   //sampleEnd
}

fun Carousel(state: LazyListState, count: Int, dismissParams: DismissParams?, itemSpacing: CarouselItemSpacing, modifier: Modifier = Modifier, reverseScrollDirection: Boolean = false, isScrollEnabled: Boolean = true, variant: CarouselVariant = SlideShow, key: (page: Int) -> Any? = null, flingBehavior: FlingBehavior? = null, a11ySkipListing: A11ySkipListing? = null, navButtonParams: NavButtonParams? = null, content: @Composable (page: Int) -> Unit)

Carousel is a container used to horizontally slide or cycle through content placed inside of it. This Implementation does not have a counter badge on display.

Parameters

state

LazyListState to handle list of items.

count

number of total items in list.

dismissParams

action parameter for dismiss button in theatre variant.

itemSpacing

CarouselItemSpacing it modifies the space between item from CarouselItemSpacing.None to CarouselItemSpacing.XLarge.

modifier

Modifier to be applied to the Carousel layout.

reverseScrollDirection

Boolean to reverse scroll direction.

isScrollEnabled

Boolean to handle if scrolling is enabled.

variant

CarouselVariant defines which variant of the carousel. The default value is CarouselVariant.SlideShow.

key

a factory of stable and unique keys representing the item.

flingBehavior

logic describing fling behavior, and animate the scroll state. Default animation for CarouselVariant.SlideShow and CarouselVariant.Theatre is snapping and for CarouselVariant.Overflow is free scrolling

a11ySkipListing

the A11ySkipListing class enable the accessibility functionality to skip all the items of the carousel when using talkback navigation. You will need to add A11ySkipListing.listTitle to your carousel, a localized label such as "Skip listing" using A11ySkipListing.actionLabel that will move the focus using to the desired item using A11ySkipListing.nextItemFocusRequester.

navButtonParams

NavButtonParams to add navigation button data to the component.

content

a block which describes the content. Inside this block you can use methods like LazyListScope.item to add a single item or LazyListScope.items to add a list of items.

See also

Samples

import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
val context = LocalContext.current
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    val a11ySkipListing = A11ySkipListing("Carousel", "Skip listing", remember { FocusRequester() })
    Column {
        Carousel(
            count = listItem.size,
            state = listState,
            variant = CarouselVariant.SlideShow,
            dismissParams = null,
            a11ySkipListing = a11ySkipListing
        ) { page ->
            Image(
                modifier = Modifier
                    .clickable { Toast.makeText(context, "Do something", Toast.LENGTH_LONG).show() },
                painter = listItem[page].image,
                contentDescription = listItem[page].contentDes,
                contentScale = ContentScale.FillWidth
            )
        }
        Text(
            text = "Next focusable element, lorem ipsum dolor sit amet, consectetur adipiscing elit, " +
                "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
            modifier = Modifier
                .focusRequester(a11ySkipListing.nextItemFocusRequester)
                .focusable(true)
        )
    }
} 
   //sampleEnd
}
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Carousel(
        count = listItem.size,
        state = listState,
        variant = CarouselVariant.Theatre,
        dismissParams = DismissParams(
            onDismissRequest = {
                // Pop backstack or dismiss sheet
            },
            dismissButtonContentDescription = "Close"
        )
    ) { page ->
        Image(
            painter = listItem[page].image,
            contentDescription = listItem[page].contentDes,
            contentScale = ContentScale.Fit
        )
    }
} 
   //sampleEnd
}
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem = listOf("section  1", "section  2", "section  3", "section  4", "section  5")
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Carousel(
        count = listItem.size,
        state = listState,
        variant = CarouselVariant.Overflow,
        itemSpacing = true,
        dismissParams = null
    ) { page ->
        val context = LocalContext.current
        Column(
            modifier = Modifier
                .width(250.dp)
                .semantics(true) { }
        ) {
            Box(
                modifier = Modifier
                    .height(150.dp)
                    .fillMaxWidth()
                    .background(Color(0x66CCCCCC))
            )
            Box(
                modifier = Modifier
                    .height(250.dp)
                    .fillMaxWidth()
                    .background(Color(0xFF56b8ff))
            ) {
                Column(
                    modifier = Modifier
                        .align(Alignment.BottomCenter)
                        .fillMaxWidth()
                        .padding(32.dp),
                    verticalArrangement = Arrangement.Center
                ) {
                    Text(text = listItem[page], style = SkapaTheme.typography2.bodyM.copy(color = SkapaTheme.colors.textAndIcon1))
                    Button(label = "Click me!", modifier = Modifier.fillMaxWidth()) {
                        Toast.makeText(context, "${listItem[page]} clicked", Toast.LENGTH_LONG).show()
                    }
                }
            }
        }
    }
} 
   //sampleEnd
}
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
val context = LocalContext.current
val a11ySkipListing = A11ySkipListing("Carousel", "Skip listing", remember { FocusRequester() })

SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Column(verticalArrangement = Arrangement.SpaceBetween) {
        Carousel(
            count = listItem.size,
            state = listState,
            variant = CarouselVariant.SlideShow,
            dismissParams = null,
            a11ySkipListing = a11ySkipListing
        ) { page ->
            Image(
                modifier = Modifier
                    .clickable { Toast.makeText(context, "Do something", Toast.LENGTH_LONG).show() },
                painter = listItem[page].image,
                contentDescription = listItem[page].contentDes,
                contentScale = ContentScale.FillWidth
            )
        }
        Text(
            text = "Next focusable element",
            modifier = Modifier
                .focusRequester(a11ySkipListing.nextItemFocusRequester)
                .focusable(true)
        )
    }
} 
   //sampleEnd
}

fun Carousel(state: LazyListState, count: Int, counterBadgeFormatter: (Int) -> String, dismissParams: DismissParams?, itemSpacing: CarouselItemSpacing, modifier: Modifier = Modifier, reverseScrollDirection: Boolean = false, isScrollEnabled: Boolean = true, variant: CarouselVariant = SlideShow, key: (page: Int) -> Any? = null, flingBehavior: FlingBehavior? = null, a11ySkipListing: A11ySkipListing? = null, navButtonParams: NavButtonParams? = null, content: @Composable (page: Int) -> Unit)

Carousel is a container used to horizontally slide or cycle through content placed inside of it. This Implementation has a counter badge on display and is accessed through the counterBadgeFormatter property, if you choose CarouselVariant.Overflow the counter will no be shown.

Parameters

state

LazyListState to handle list of items.

count

number of total items in list.

counterBadgeFormatter

function that returns the formatted counter text to display, given the current page

dismissParams

action parameter for dismiss button in theatre variant.

itemSpacing

CarouselItemSpacing it modifies the space between item from CarouselItemSpacing.None to CarouselItemSpacing.XLarge.

modifier

Modifier to be applied to the Carousel layout.

reverseScrollDirection

Boolean to reverse scroll direction.

isScrollEnabled

Boolean to handle if scrolling is enabled.

variant

CarouselVariant defines which variant of the carousel. The default value is CarouselVariant.SlideShow.

key

a factory of stable and unique keys representing the item.

flingBehavior

logic describing fling behavior, and animate the scroll state. Default animation for CarouselVariant.SlideShow and CarouselVariant.Theatre is snapping and for CarouselVariant.Overflow is free scrolling

a11ySkipListing

the A11ySkipListing class enable the accessibility functionality to skip all the items of the carousel when using talkback navigation. You will need to add A11ySkipListing.listTitle to your carousel, a localized label such as "Skip listing" using A11ySkipListing.actionLabel that will move the focus using to the desired item using A11ySkipListing.nextItemFocusRequester.

navButtonParams

NavButtonParams to add navigation button data to the component.

content

a block which describes the content. Inside this block you can use methods like LazyListScope.item to add a single item or LazyListScope.items to add a list of items.

See also

Samples

import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.ikea.skapa.R
import net.ikea.skapa.foundation.*
import net.ikea.skapa.ui.components.Button
import net.ikea.skapa.ui.components.Carousel
import net.ikea.skapa.ui.components.CarouselVariant
import net.ikea.skapa.ui.components.DismissParams
import net.ikea.skapa.ui.util.A11ySkipListing

fun main() { 
   //sampleStart 
   val listState = rememberLazyListState()
val listItem: List<ImageItem> = listOf(
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 1"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 2"),
    ImageItem(painterResource(id = R.drawable.ic_button_danger), "image 3")
)
val context = LocalContext.current
SkapaTheme2(darkTheme = isSystemInDarkTheme()) {
    Carousel(
        count = listItem.size,
        state = listState,
        variant = CarouselVariant.SlideShow,
        dismissParams = null,
        counterBadgeFormatter = { count ->
            return@Carousel "$count of ${listItem.size}"
        }
    ) { page ->
        Image(
            modifier = Modifier
                .clickable { Toast.makeText(context, "Do something", Toast.LENGTH_LONG).show() },
            painter = listItem[page].image,
            contentDescription = listItem[page].contentDes,
            contentScale = ContentScale.FillWidth
        )
    }
} 
   //sampleEnd
}