Formatter#
TextField 의 inputFormatters 에 넘기는 입력 포매터 팩토리 모음입니다. 같은 변환 로직(CoreInputFormatters)을 양 플랫폼이 공유하며, 클래스 이름(TextInputFormatters)과 팩토리 표면(integerOnly·decimalOnly·toUpperCase·toLowerCase·time·mathExpression)이 동일합니다 — Flutter 는
TextInputFormatter 로, Web <input> 은 평문 문자열에 직접 적용합니다.
Live Preview#
class FormatterDefaultExample extends StatelessComponent {
const FormatterDefaultExample({super.key});
@override
Component build(BuildContext context) {
return div(
styles: Styles(raw: {'width': '280px'}),
[
TextField(
placeholder: Text('숫자만 입력 (0–100)'),
inputFormatters: [TextInputFormatters.integerOnly(min: 0, max: 100)],
),
],
);
}
}
class FormatterDefaultExample extends StatelessWidget {
const FormatterDefaultExample({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
width: 280,
child: TextField(
placeholder: const Text('숫자만 입력 (0–100)'),
inputFormatters: [TextInputFormatters.integerOnly(min: 0, max: 100)],
),
);
}
}
사용법#
// Flutter / Web 동일 — TextInputFormatters
TextField(
placeholder: const Text('숫자만 입력 (0–100)'),
inputFormatters: [TextInputFormatters.integerOnly(min: 0, max: 100)],
)
Props#
TextInputFormatters 는 위젯이 아니라 정적 팩토리 홀더라 생성자가 없습니다 (TextInputFormatters._()
는 private). 노출되는 표면은 아래 팩토리와 그 named 파라미터뿐이며, 각 팩토리가 돌려준 값을 TextField.inputFormatters 에 넘겨 씁니다.
| 팩토리 | 파라미터 | 기본값 | 설명 |
|---|---|---|---|
integerOnly |
int? min, int? max |
둘 다 null (무제한) |
정수만 허용하고 범위를 벗어난 입력을 되돌립니다 |
decimalOnly |
int? decimalDigits, double? min, double? max |
모두 null (자릿수·범위 무제한) |
소수를 허용하고 소수점 이하 자릿수와 범위를 제한합니다 |
toUpperCase | 없음 | — | 입력을 대문자로 강제합니다 |
toLowerCase | 없음 | — | 입력을 소문자로 강제합니다 |
time |
required int length |
필수 | 지정한 길이까지 앞을 0 으로 채우는 시간 형식 마스킹 |
mathExpression |
Map<String, Object?>? context |
null |
입력을 수식으로 평가합니다. context 는 식에서 참조할 변수 맵 |
allow (Flutter 전용) |
String pattern |
필수 | 정규식 소스 pattern 에 매칭되는 문자만 남깁니다 |
InputFormatter (Flutter 전용 어댑터)
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
formatter |
CoreInputFormatter |
필수 (positional) | 감쌀 플랫폼 무관 변환. Flutter TextInputFormatter 로 어댑트하며 재작성 후 캐럿 위치를 보존합니다 |
팩토리 시그니처는 양 플랫폼 동일하고 반환 타입만 framework idiom 으로 다릅니다 — Flutter
TextInputFormatter, WebCoreInputFormatter.
사용 가이드라인 (Usage Guidelines)#
✅ Do#
숫자 입력은 min/max로 범위를 clamp
TextField(
placeholder: const Text('나이 (0–120)'),
inputFormatters: [TextInputFormatters.integerOnly(min: 0, max: 120)],
)
min/max는 범위를 벗어난 값을 자동으로 경계값으로 보정합니다(예: 130 입력 시 120으로) — 범위가 있는 숫자 입력은 별도 검증 로직 없이 포매터만으로 값을 안전한 범위 안에 유지할 수 있습니다.
❌ Don't#
TextInputFormatters.allow가 Web에도 있다고 가정하지 않기
// ❌ Web 의 TextInputFormatters 에는 allow 가 없음 — 컴파일 에러
TextInputFormatters.allow(r'[0-9]')
// ✅ Web 은 공유 로직인 CoreInputFormatters.allow 를 직접 사용
CoreInputFormatters.allow(r'[0-9]')
allow 팩토리는 Flutter의 TextInputFormatters에만 있고 Web TextInputFormatters에는 없습니다 — 양 플랫폼에서 같은 코드를 쓰려면 Web에서는 공유 로직인 CoreInputFormatters.allow를 직접 호출해야 합니다.
접근성 (Accessibility)#
이 절은 Formatter 자신의 동작만 다룹니다. 전 컴포넌트에 공통으로 적용되는 축은 전역 접근성 축을 참고하세요.
렌더링 표면이 없습니다#
Formatter 는 아무것도 그리지 않습니다. Flutter 쪽은 TextInputFormatter 를 상속한 InputFormatter
와 팩토리 홀더 TextInputFormatters 이고, Web 쪽은 CoreInputFormatter 값을 돌려주는 팩토리 홀더
TextInputFormatters 입니다. 어느 파일도 Widget / Component 나 build 를 선언하지 않으므로 role 을 실을 엘리먼트도 시맨틱 노드도 존재하지 않습니다.
같은 이유로 키보드 처리도, 포커스 개념도 없습니다. Flutter 는 플랫폼이 키 입력을 이미 처리한 뒤 프레임워크가 호출하는 formatEditUpdate
에서 텍스트 변경에 반응할 뿐이고, Web 은 이벤트 배선이 전혀 없는 순수 format(old, new) 문자열 변환입니다.
스크린 리더#
이 클래스들이 직접 읽히는 것은 없습니다. 간접적으로는 사용자가 입력하는 동안 필드의 텍스트를 다시 쓰므로(Flutter 는 재작성된 문자열 길이에 맞춰 캐럿을 clamp 합니다), 리더가 다시 읽는 것은 호스트 필드의 값 변경입니다. 포매터 자신은 live region 도, status 도, "문자가 거부되었다 / 다시 포맷되었다"는 안내도 내보내지 않습니다.
알려진 제약#
- 거부·재작성이 조용히 일어납니다. 허용되지 않는 문자를 입력한 스크린 리더 사용자는 무언가 버려졌다는 피드백을 전혀 받지 못합니다(양 플랫폼 동일). 입력 규칙을 알려야 한다면 호스트 필드 쪽에서 안내 문구나 live region 을 직접 제공해야 합니다.
-
접근성과 직접 관련은 없지만 팩토리 표면이 실제로는 완전히 같지 않습니다 — Flutter 에는
TextInputFormatters.allow(pattern)이 있고 Web 의TextInputFormatters에는 없어, Web 호출자는CoreInputFormatters.allow를 직접 씁니다.