soil icon indicating copy to clipboard operation
soil copied to clipboard

[Form] Add Material Design Form Control Helper

Open TBSten opened this issue 8 months ago • 1 comments

Overview

Provide a helper for the material / material3 component to the Soil Form.

Problem

When I was trying to implement a form using Soil Form in my Android project, I noticed that there are many fields that need to be passed to the Composable in the Control.

    val control = rememberFieldRuleControl(
        name = "email",
        select = { this },
        update = { it },
    ) {
        notBlank { "not blank" }
    }

    Controller(control) { field ->
        TextField(
            value = field.value,
            onValueChange = field.onChange,
            placeholder = { Text(field.name) },
            modifier = Modifier
                .fillMaxWidth()
                .onFocusChanged(field),
            enabled = field.isEnabled,
            isError = field.hasError,
            singleLine = true,
            supportingText = {
                if (field.hasError) {
                    Text(text = field.errors.first(), color = MaterialTheme.colorScheme.error)
                }
            },
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Text,
                imeAction = ImeAction.Next,
            )
        )
    }

While we recognize that this is a great design from a flexibility standpoint, we think this may be too much work from a convenience standpoint.

Suggestion.

We think that the burden on implementors can be reduced by providing helpers for detailed implementation of the commonly used material / material3 libraries as follows.

// usage
val control = rememberFieldRuleControl(
  name = "email",
  select = { keyword },
  update = { copy(keyword = it) },
) {
  notBlank { "not blank" }
}

TextField(control)


// definition
fun TextField(
  control : FieldControl<String>,
  modifier: Modifier = Modifier,
  placeholder: @Composable (() -> Unit)? = { Text(field.name) }
  // ...
) {

    Controller(control) { field ->
        TextField(
            value = field.value,
            onValueChange = field.onChange,
            placeholder = placeholder,
            modifier = Modifier
                .onFocusChanged(field),
            // ...
        )
    }

}

I would like to discuss the pros and cons of this proposal first.

TBSten avatar May 25 '24 15:05 TBSten