Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add icon toggle button #644

Merged
merged 32 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2186a8c
init: icon toggle button
Aug 22, 2023
33db052
Merge branch 'main' into icon_toggle_button
Aug 22, 2023
f0ca4d5
Add icon toggle button styles
Aug 22, 2023
88c52f3
Merge branch 'main' into icon_toggle_button
Aug 22, 2023
de05c88
Merge branch 'main' into icon_toggle_button
Aug 23, 2023
1f7aad7
Add icon toggle button configurator
Aug 23, 2023
c045f47
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 23, 2023
972ff37
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 23, 2023
226637f
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 23, 2023
2067712
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 23, 2023
fdc9183
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 23, 2023
6fa1e1a
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 23, 2023
b154301
Add @deprecated to old IconToggleButton
Aug 24, 2023
d7bc35d
Merge remote-tracking branch 'origin/icon_toggle_button' into icon_to…
Aug 24, 2023
4d9b2cf
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 25, 2023
4033cfc
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 25, 2023
110c9f6
Update spark/src/main/kotlin/com/adevinta/spark/components/icontoggle…
kazaky Aug 25, 2023
6a2c33e
Add Icon toggle button examples
Aug 25, 2023
5da7e02
Merge remote-tracking branch 'origin/icon_toggle_button' into icon_to…
Aug 25, 2023
1471881
Add KDoc on icon toggle buttons components
Aug 25, 2023
73e33fa
Fix readme file
Aug 25, 2023
b7658ab
Merge branch 'main' into icon_toggle_button
Aug 25, 2023
eda62ad
Fix spotless
Aug 25, 2023
4ce568a
Add intent to icon toggle button Kdoc
Aug 25, 2023
dc2cb51
Add unit tests
Aug 25, 2023
2cfd791
Merge branch 'main' into icon_toggle_button
Aug 25, 2023
0730eb3
Fix spotless
Aug 25, 2023
4dabe67
Update package
Aug 25, 2023
cd1d3d8
Opt in spark experimental API
Aug 25, 2023
d9c0916
Merge branch 'main' into icon_toggle_button
soulcramer Aug 30, 2023
a7e4b7e
Fix screenshot tests
soulcramer Aug 30, 2023
31a2c31
Merge branch 'main' into icon_toggle_button
soulcramer Aug 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
/*
* Copyright (c) 2023 Adevinta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.adevinta.spark.catalog.configurator.samples.buttons

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.adevinta.spark.SparkTheme
import com.adevinta.spark.catalog.model.Configurator
import com.adevinta.spark.catalog.themes.SegmentedButton
import com.adevinta.spark.catalog.util.SampleSourceUrl
import com.adevinta.spark.components.iconbuttons.IconButtonIntent
import com.adevinta.spark.components.iconbuttons.IconButtonShape
import com.adevinta.spark.components.iconbuttons.IconButtonSize
import com.adevinta.spark.components.iconbuttons.toggle.IconToggleButtonContrast
import com.adevinta.spark.components.iconbuttons.toggle.IconToggleButtonFilled
import com.adevinta.spark.components.iconbuttons.toggle.IconToggleButtonGhost
import com.adevinta.spark.components.iconbuttons.toggle.IconToggleButtonIcons
import com.adevinta.spark.components.iconbuttons.toggle.IconToggleButtonOutlined
import com.adevinta.spark.components.iconbuttons.toggle.IconToggleButtonTinted
import com.adevinta.spark.components.menu.DropdownMenuItem
import com.adevinta.spark.components.text.Text
import com.adevinta.spark.components.textfields.SelectTextField
import com.adevinta.spark.components.textfields.TextField
import com.adevinta.spark.components.toggles.SwitchLabelled
import com.adevinta.spark.icons.CarFill
import com.adevinta.spark.icons.CarOutline
import com.adevinta.spark.icons.SparkIcons

public val IconToggleButtonsConfigurator: Configurator = Configurator(
name = "IconToggleButton",
description = "IconToggleButton configuration",
sourceUrl = "$SampleSourceUrl/IconToggleButtonSamples.kt",
) {
IconToggleButtonSample()
}

@Preview(
showBackground = true,
)
@Composable
private fun IconToggleButtonSample() {
val scrollState = rememberScrollState()
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.verticalScroll(scrollState),
) {
var style by remember { mutableStateOf(IconToggleButtonStyle.Filled) }
var isEnabled by remember { mutableStateOf(true) }
var isChecked by remember { mutableStateOf(true) }
var shape by remember { mutableStateOf(IconButtonShape.Large) }
var size by remember { mutableStateOf(IconButtonSize.Medium) }
var intent by remember { mutableStateOf(IconButtonIntent.Main) }
var icons by remember { mutableStateOf(IconToggleButtonIcons(SparkIcons.CarOutline, SparkIcons.CarFill)) }
var contentDescription by remember { mutableStateOf("Content Description") }

ConfigedIconToggleButton(
style = style,
shape = shape,
contentDescription = contentDescription,
onCheckedChange = { isChecked = !isChecked },
size = size,
intent = intent,
isChecked = isChecked,
isEnabled = isEnabled,
icons = icons,
)

SwitchLabelled(
checked = isEnabled,
onCheckedChange = { isEnabled = it },
) {
Text(
text = "Enabled",
modifier = Modifier.fillMaxWidth(),
)
}

Column {
Text(
text = "Style",
modifier = Modifier.padding(bottom = 8.dp),
style = SparkTheme.typography.body2.copy(fontWeight = FontWeight.Bold),
)
val buttonStyles = IconToggleButtonStyle.values()
val buttonStylesLabel = buttonStyles.map { it.name }
SegmentedButton(
options = buttonStylesLabel,
selectedOption = style.name,
onOptionSelect = { style = IconToggleButtonStyle.valueOf(it) },
modifier = Modifier
.fillMaxWidth()
.height(48.dp),
)
}

val intents = IconButtonIntent.values()
var expanded by remember { mutableStateOf(false) }
SelectTextField(
modifier = Modifier.fillMaxWidth(),
value = intent.name,
onValueChange = {},
readOnly = true,
label = "Intent",
expanded = expanded,
onExpandedChange = {
expanded = !expanded
},
onDismissRequest = {
expanded = false
},
dropdownContent = {
intents.forEach {
DropdownMenuItem(
text = { Text(it.name) },
onClick = {
intent = it
expanded = false
},
)
}
},
)

Column {
Text(
text = "Shape",
modifier = Modifier.padding(bottom = 8.dp),
style = SparkTheme.typography.body2.copy(fontWeight = FontWeight.Bold),
)
val buttonShapes = IconButtonShape.values()
val buttonShapesLabel = buttonShapes.map { it.name }
SegmentedButton(
options = buttonShapesLabel,
selectedOption = shape.name,
onOptionSelect = { shape = IconButtonShape.valueOf(it) },
modifier = Modifier
.fillMaxWidth()
.height(48.dp),
)
}
Column {
Text(
text = "Size",
modifier = Modifier.padding(bottom = 8.dp),
style = SparkTheme.typography.body2.copy(fontWeight = FontWeight.Bold),
)
val buttonSizes = IconButtonSize.values()
val buttonSizesLabel = buttonSizes.map { it.name }
SegmentedButton(
options = buttonSizesLabel,
selectedOption = size.name,
onOptionSelect = { size = IconButtonSize.valueOf(it) },
modifier = Modifier
.fillMaxWidth()
.height(48.dp),
)
}

TextField(
modifier = Modifier.fillMaxWidth(),
value = contentDescription,
onValueChange = {
contentDescription = it
},
label = "Content Description",
placeholder = "Content Description",
)
}
}

@Composable
private fun ConfigedIconToggleButton(
modifier: Modifier = Modifier,
style: IconToggleButtonStyle,
shape: IconButtonShape,
contentDescription: String?,
onCheckedChange: (Boolean) -> Unit = {},
size: IconButtonSize,
intent: IconButtonIntent,
isChecked: Boolean,
isEnabled: Boolean,
icons: IconToggleButtonIcons,
) {
when (style) {
IconToggleButtonStyle.Filled -> IconToggleButtonFilled(
modifier = modifier,
contentDescription = contentDescription,
onCheckedChange = onCheckedChange,
size = size,
shape = shape,
intent = intent,
checked = isChecked,
enabled = isEnabled,
icons = icons,
)

IconToggleButtonStyle.Outlined -> IconToggleButtonOutlined(
modifier = modifier,
contentDescription = contentDescription,
onCheckedChange = onCheckedChange,
size = size,
shape = shape,
intent = intent,
checked = isChecked,
enabled = isEnabled,
icons = icons,
)

IconToggleButtonStyle.Tinted -> IconToggleButtonTinted(
modifier = modifier,
contentDescription = contentDescription,
onCheckedChange = onCheckedChange,
size = size,
shape = shape,
intent = intent,
checked = isChecked,
enabled = isEnabled,
icons = icons,
)

IconToggleButtonStyle.Ghost -> IconToggleButtonGhost(
modifier = modifier,
contentDescription = contentDescription,
onCheckedChange = onCheckedChange,
size = size,
shape = shape,
intent = intent,
checked = isChecked,
enabled = isEnabled,
icons = icons,
)

IconToggleButtonStyle.Contrast -> IconToggleButtonContrast(
modifier = modifier,
contentDescription = contentDescription,
onCheckedChange = onCheckedChange,
size = size,
shape = shape,
intent = intent,
checked = isChecked,
enabled = isEnabled,
icons = icons,
)
}
}

private enum class IconToggleButtonStyle {
Filled,
Outlined,
Tinted,
Contrast,
Ghost,
}
Loading
Loading