Библиотека для форматирования вводимых пользователем значений с поддержкой Compose Multiplatform.
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("io.github.skeptick.inputmask:core:0.0.4")
implementation("io.github.skeptick.inputmask:compose:0.0.4")
}
}
}
}
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 mask = "[000]-[000]"
val visualTransformation = remember { InputMaskVisualTransformation(mask) }
BasicTextField(
value = text,
onValueChange = { text = visualTransformation.sanitize(it) },
visualTransformation = visualTransformation,
)
Специальная вариация для форматирования телефона, обрабатывающая вставку в поле ввода номера как с кодом страны, так и без:
var text by remember { mutableStateOf("") }
var mask = "+{7} ([000]) [000]-[00]-[00]"
val visualTransformation = remember(mask) { PhoneInputMaskVisualTransformation(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 = remember(mask) { InputMaskInputTransformation(mask) },
outputTransformation = remember(mask) { InputMaskOutputTransformation(mask) },
)
И специальная вариация InputTransformation
для телефонных номеров:
BasicTextField(
// ...
inputTransformation = remember(mask) { PhoneInputTransformation(mask) },
// ...
)