Checklists in the body, colour from tags, and commit-derived CalVer #4
@@ -14,9 +14,11 @@ import androidx.compose.material.icons.filled.Close
|
|||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.Checkbox
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
@@ -136,38 +138,54 @@ private fun TaskBlock(
|
|||||||
onEnter: () -> Unit,
|
onEnter: () -> Unit,
|
||||||
onDelete: () -> Unit,
|
onDelete: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
// Material sizes every interactive component to a 48dp touch target, and on a
|
||||||
Checkbox(
|
// checklist that IS the row height — which is why six items filled a phone screen
|
||||||
checked = block.checked == true,
|
// even after the field's own padding came off.
|
||||||
onCheckedChange = { onChange(block.copy(checked = it)) },
|
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides ROW_TOUCH) {
|
||||||
enabled = !readOnly,
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
)
|
Checkbox(
|
||||||
BlockField(
|
checked = block.checked == true,
|
||||||
value = block.value,
|
onCheckedChange = { onChange(block.copy(checked = it)) },
|
||||||
onValueChange = { onChange(block.copy(value = it)) },
|
enabled = !readOnly,
|
||||||
modifier = Modifier.weight(1f).focusRequester(requester),
|
)
|
||||||
enabled = !readOnly,
|
BlockField(
|
||||||
singleLine = true,
|
value = block.value,
|
||||||
textStyle =
|
onValueChange = { onChange(block.copy(value = it)) },
|
||||||
MaterialTheme.typography.bodyLarge.copy(
|
modifier = Modifier.weight(1f).focusRequester(requester),
|
||||||
// Struck through when done, matching the card and the web.
|
enabled = !readOnly,
|
||||||
textDecoration =
|
singleLine = true,
|
||||||
if (block.checked == true) TextDecoration.LineThrough else null,
|
textStyle =
|
||||||
),
|
MaterialTheme.typography.bodyLarge.copy(
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
// Struck through when done, matching the card and the web.
|
||||||
keyboardActions = KeyboardActions(onNext = { onEnter() }),
|
textDecoration =
|
||||||
)
|
if (block.checked == true) TextDecoration.LineThrough else null,
|
||||||
if (!readOnly) {
|
),
|
||||||
IconButton(onClick = onDelete) {
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
||||||
Icon(
|
keyboardActions = KeyboardActions(onNext = { onEnter() }),
|
||||||
Icons.Filled.Close,
|
)
|
||||||
contentDescription = stringResource(R.string.editor_remove_item),
|
if (!readOnly) {
|
||||||
)
|
IconButton(onClick = onDelete) {
|
||||||
|
Icon(
|
||||||
|
Icons.Filled.Close,
|
||||||
|
contentDescription = stringResource(R.string.editor_remove_item),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The touch target for a checklist row's controls.
|
||||||
|
*
|
||||||
|
* Material's floor is 48dp and this is deliberately under it. That floor is sized for
|
||||||
|
* a control somebody has to find; a checklist box sits in a predictable column with an
|
||||||
|
* identical box directly above and below, and the cost of a near miss is ticking the
|
||||||
|
* neighbouring item — visible, and undone by tapping again. Trading twelve of those
|
||||||
|
* dp for a list that fits on a screen is what was asked for, twice.
|
||||||
|
*/
|
||||||
|
private val ROW_TOUCH = 36.dp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The field a block is typed into.
|
* The field a block is typed into.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user