Skip to content

Instantly share code, notes, and snippets.

@fvilarino
Last active March 18, 2024 00:18
Show Gist options
  • Save fvilarino/abcaaeab78cc5b29d087d8287ff3d1e9 to your computer and use it in GitHub Desktop.
Save fvilarino/abcaaeab78cc5b29d087d8287ff3d1e9 to your computer and use it in GitHub Desktop.
Chip Selector - State Holder Impl
class ChipSelectorStateImpl(
// 1
override val chips: List<String>,
// 2
selectedChips: List<String> = emptyList(),
// 3
val mode: SelectionMode = SelectionMode.Single,
) : ChipSelectorState {
// 4
override var selectedChips by mutableStateOf(selectedChips)
// 5
override fun onChipClick(chip: String) {
if (mode == SelectionMode.Single) {
if (!selectedChips.contains(chip)) {
selectedChips = listOf(chip)
}
} else {
selectedChips = if (selectedChips.contains(chip)) {
selectedChips - chip
} else {
selectedChips + chip
}
}
}
// 6
override fun isSelected(chip: String): Boolean = selectedChips.contains(chip)
companion object {
// 7
val saver = Saver<ChipSelectorStateImpl, List<*>>(
save = { state ->
buildList {
add(state.chips.size)
addAll(state.chips)
add(state.selectedChips.size)
addAll(state.selectedChips)
add(state.mode.index)
}
},
restore = { items ->
var index = 0
val chipsSize = items[index++] as Int
val chips = List(chipsSize) {
items[index++] as String
}
val selectedSize = items[index++] as Int
val selectedChips = List(selectedSize) {
items[index++] as String
}
val mode = SelectionMode.fromIndex(items[index] as Int)
ChipSelectorStateImpl(
chips = chips,
selectedChips = selectedChips,
mode = mode,
)
}
)
}
}
// 8
@Composable
fun rememberChipSelectorState(
chips: List<String>,
selectedChips: List<String> = emptyList(),
mode: SelectionMode = SelectionMode.Single,
): ChipSelectorState {
if (chips.isEmpty()) error("No chips provided")
if (mode == SelectionMode.Single && selectedChips.size > 1) {
error("Single choice can only have 1 pre-selected chip")
}
return rememberSaveable(
saver = ChipSelectorStateImpl.saver
) {
ChipSelectorStateImpl(
chips,
selectedChips,
mode,
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment