-
Notifications
You must be signed in to change notification settings - Fork 98
/
Checkbox.kt
126 lines (120 loc) · 4.98 KB
/
Checkbox.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package com.microsoft.fluentui.tokenized.controls
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.*
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.selection.triStateToggleable
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.unit.dp
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.ControlTokens.ControlType
import com.microsoft.fluentui.theme.token.Icon
import com.microsoft.fluentui.theme.token.controlTokens.CheckBoxInfo
import com.microsoft.fluentui.theme.token.controlTokens.CheckBoxTokens
/**
* API to create a checkbox. A checkbox is a type of button that lets the user choose between two opposite states,
* actions, or values. A selected checkbox is considered on when it contains a checkmark and off when
* it's empty. A checkbox is almost always followed by a title unless it appears in a checklist.
*
* @param onCheckedChanged Function to be invoked when checked state changes
* @param modifier Optional Modifier for CheckBox
* @param enabled Boolean for enabling/disabling CheckBox. Default: [true]
* @param checked Boolean for checked state of control. Default: [false]
* @param interactionSource Interaction source for User gesture Management.
* @param checkBoxToken Tokens for customizing CheckBox design.
*/
@Composable
fun CheckBox(
onCheckedChanged: ((Boolean) -> Unit),
modifier: Modifier = Modifier,
enabled: Boolean = true,
checked: Boolean = false,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
checkBoxToken: CheckBoxTokens? = null
) {
val themeID =
FluentTheme.themeID //Adding This only for recomposition in case of Token Updates. Unused otherwise.
val token = checkBoxToken
?: FluentTheme.controlTokens.tokens[ControlType.CheckBoxControlType] as CheckBoxTokens
val checkBoxInfo = CheckBoxInfo(checked)
val toggleModifier =
Modifier.triStateToggleable(
state = ToggleableState(checked),
enabled = enabled,
onClick = { onCheckedChanged(!checked) },
role = Role.Checkbox,
interactionSource = interactionSource,
indication = rememberRipple(
bounded = false,
radius = 24.dp
)
)
val backgroundColor: Brush =
token.backgroundBrush(checkBoxInfo = checkBoxInfo).getBrushByState(
enabled = enabled,
selected = checked,
interactionSource = interactionSource
)
val iconColor: Color =
token.iconColor(checkBoxInfo = checkBoxInfo).getColorByState(
enabled = enabled,
selected = checked,
interactionSource = interactionSource
)
val shape: Shape = RoundedCornerShape(token.borderRadius(checkBoxInfo))
val borders: List<BorderStroke> =
token.borderStroke(checkBoxInfo = checkBoxInfo)
.getBorderStrokeByState(
enabled = enabled,
selected = checked,
interactionSource = interactionSource
)
var borderModifier: Modifier = Modifier
var borderWidth = 0.dp
for (border in borders) {
borderWidth += border.width
borderModifier = borderModifier.border(borderWidth, border.brush, shape)
}
Box(
modifier = modifier.indication(interactionSource, null),
contentAlignment = Alignment.Center
) {
Spacer(
modifier = Modifier
.size(token.size(checkBoxInfo = checkBoxInfo))
.clip(shape)
.background(backgroundColor)
.then(borderModifier)
.then(toggleModifier)
)
AnimatedVisibility(checked, enter = fadeIn(), exit = fadeOut()) {
Icon(
Icons.Filled.Done,
null,
modifier = Modifier
.size(token.iconSize(checkBoxInfo = checkBoxInfo))
.focusable(false)
.clearAndSetSemantics {},
tint = iconColor
)
}
}
}