Библиотека для форматирования вводимых пользователем значений с поддержкой Compose Multiplatform.
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("io.github.skeptick.inputmask:inputmask-core:0.0.7")
implementation("io.github.skeptick.inputmask:inputmask-compose:0.0.7")
}
}
}
}core поддерживает все таргеты Kotlin, compose все таргеты Compose Multiplatform.
Синтаксис масок вдохновлён небезызвестной библиотекой от RedMadRobot ( Android, iOS ), но реализация гораздо более примитивная. В частности, не поддерживаются «родственные» маски.
Детальнее в документации RedMadRobot.
Верхнеуровнево:
- в
[]описываем то, что ожидаем от пользователя - в
{}любые символы, которые хотим получить в извлекаемом значении - все символы за пределами
[]и{}будут вставлены в процессе форматирования, но не попадут в извлекаемое значение
В [] поддерживаются следующие символы:
0- обязательная цифра9- опциональная цифраA- обязательная букваa- опциональная буква_- обязательная буква или цифра-- опциональная буква или цифра…- неограниченное количество цифр или букв- если перед
…стоит0или9, то будут ожидаться цифровые символы - если перед
…стоитAилиa, то будут ожидаться буквенные символы - если перед
…стоит_или-, или не стоит ничего, то будут ожидаться буквы или цифры
- если перед
val inputMask = InputMasks.getOrCreate("+{7} ([000]) [000]-[0000]")Поддерживается создание с помощью простого DSL:
val inputMask = InputMasks.build {
fixedChar('+', extracted = false)
fixedChar('7', extracted = true)
fixedChar(' ', extracted = false)
fixedChar('(', extracted = false)
repeat(3) { singleDigit(required = true) }
fixedChar(')', extracted = false)
fixedChar(' ', extracted = false)
repeat(3) { singleDigit(required = true) }
fixedChar('-', extracted = false)
repeat(4) { singleDigit(required = true) }
}
val result = inputMask.format("9001234567")
result.isComplete // -> true
result.formattedValue // -> +7 (900) 123-4567
result.extractedValue // -> 79001234567Обратите внимание на параметр replacePrefix:
inputMask.format("79001234567", replacePrefix = true) // => "+7 (900) 123-4567"
inputMask.format("79001234567", replacePrefix = false) // => "+7 (790) 012-3456"Артефакт compose поставляет имлементации VisualTransformation для TextField принимающих String или TextFieldValue:
var text by remember { mutableStateOf("") }
val visualTransformation = rememberInputMaskVisualTransformation("[000]-[000]")
BasicTextField(
value = text,
onValueChange = { text = visualTransformation.sanitize(it) },
visualTransformation = visualTransformation,
)Специальная вариация для форматирования телефона, обрабатывающая вставку в поле ввода номера как с кодом страны, так и без:
var text by remember { mutableStateOf("") }
val mask = "+{7} ([000]) [000]-[0000]"
val visualTransformation = rememberPhoneInputMaskVisualTransformation(mask)
BasicTextField(
value = value,
onValueChange = { text = visualTransformation.sanitize(it) },
visualTransformation = visualTransformation,
)Обратите внимание, что если маска может измениться в процессе ввода (например, пользователю предоставляется возможность выбрать страну во время авторизации), то нужно также обновить значение:
BasicTextField(
value = remember(text, mask) { visualTransformation.sanitize(value) },
// ...
)Для полей ввода, построенных вокруг TextFieldState есть имплементации InputTransformation и OutputTransformation:
val textFieldState = remember { TextFieldState() }
val mask = "[000]-[000]"
BasicTextField(
state = textFieldState,
inputTransformation = rememberInputMaskInputTransformation(mask),
outputTransformation = rememberInputMaskOutputTransformation(mask),
)И специальная вариация InputTransformation для телефонных номеров:
BasicTextField(
// ...
inputTransformation = rememberPhoneInputMaskInputTransformation(mask),
// ...
)