scriptable-testlab
Version:
A lightweight, efficient tool designed to manage and update scripts for Scriptable.
298 lines (244 loc) • 7.72 kB
text/typescript
import {AbsTextField} from 'scriptable-abstract';
import {MockColor} from './color';
import {MockFont} from './font';
// Public enums for API compatibility
export enum TextFieldAlignment {
left = 'left',
center = 'center',
right = 'right',
}
export enum TextFieldKeyboardType {
default = 'default',
number = 'number',
decimal = 'decimal',
email = 'email',
phone = 'phone',
url = 'url',
}
export enum TextFieldAutocapitalizationType {
none = 'none',
words = 'words',
sentences = 'sentences',
all = 'all',
}
export enum TextFieldReturnKeyType {
default = 'default',
go = 'go',
next = 'next',
done = 'done',
search = 'search',
send = 'send',
}
interface TextFieldMockState {
text: string;
isSecure: boolean;
placeholder: string;
textColor: MockColor;
font: Font;
onReturn?: () => void;
onTextChange?: (text: string) => void;
onBeginEditing?: () => void;
onEndEditing?: () => void;
// Internal state for tracking and validation
_keyboardType: TextFieldKeyboardType;
_textAlignment: TextFieldAlignment;
_autocapitalizationType: TextFieldAutocapitalizationType;
_returnKeyType: TextFieldReturnKeyType;
_keyboardAppearance: 'light' | 'dark';
_spellCheckingType: 'default' | 'no' | 'yes';
_autocorrectionType: 'default' | 'no' | 'yes';
minimumContentHeight: number;
}
const DEFAULT_STATE: TextFieldMockState = {
text: '',
isSecure: false,
placeholder: '',
textColor: new MockColor('#000000'),
font: MockFont.systemFont(12),
_keyboardType: TextFieldKeyboardType.default,
_textAlignment: TextFieldAlignment.left,
_autocapitalizationType: TextFieldAutocapitalizationType.none,
_returnKeyType: TextFieldReturnKeyType.default,
_keyboardAppearance: 'light',
_spellCheckingType: 'default',
_autocorrectionType: 'default',
minimumContentHeight: 0,
};
export class MockTextField extends AbsTextField<TextFieldMockState> {
constructor(config: Partial<TextFieldMockState> = {}) {
super({...DEFAULT_STATE, ...config});
}
// Static properties for API compatibility
static readonly Alignment = TextFieldAlignment;
static readonly KeyboardType = TextFieldKeyboardType;
static readonly AutocapitalizationType = TextFieldAutocapitalizationType;
static readonly ReturnKeyType = TextFieldReturnKeyType;
get text(): string {
return this.state.text;
}
set text(value: string) {
// Apply keyboard type specific validation
let processedValue = value;
switch (this.state._keyboardType) {
case TextFieldKeyboardType.number:
processedValue = value.replace(/[^\d]/g, '');
break;
case TextFieldKeyboardType.decimal:
processedValue = value.replace(/[^\d.]/g, '');
break;
case TextFieldKeyboardType.email:
processedValue = value.toLowerCase();
break;
case TextFieldKeyboardType.phone:
processedValue = value.replace(/[^\d+\-()]/g, '');
break;
case TextFieldKeyboardType.url:
processedValue = value.toLowerCase();
break;
}
// Apply autocapitalization
switch (this.state._autocapitalizationType) {
case TextFieldAutocapitalizationType.words:
processedValue = processedValue.replace(/\b\w/g, c => c.toUpperCase());
break;
case TextFieldAutocapitalizationType.sentences:
processedValue = processedValue.replace(/(^\w|\.\s+\w)/g, c => c.toUpperCase());
break;
case TextFieldAutocapitalizationType.all:
processedValue = processedValue.toUpperCase();
break;
}
this.setState({text: processedValue});
this.state.onTextChange?.(processedValue);
}
get placeholder(): string {
return this.state.placeholder;
}
set placeholder(value: string) {
this.setState({placeholder: value});
}
get isSecure(): boolean {
return this.state.isSecure;
}
set isSecure(value: boolean) {
this.setState({isSecure: value});
}
get textColor(): Color {
return this.state.textColor;
}
set textColor(value: Color) {
this.setState({textColor: value as MockColor});
}
get font(): Font {
return this.state.font;
}
set font(value: Font) {
this.setState({font: value});
}
get minimumContentHeight(): number {
return this.state.minimumContentHeight;
}
set minimumContentHeight(value: number) {
this.setState({minimumContentHeight: value});
}
// Public properties for API compatibility
get keyboardType(): TextFieldKeyboardType {
return this.state._keyboardType;
}
set keyboardType(value: TextFieldKeyboardType) {
this.setState({_keyboardType: value});
}
get alignment(): TextFieldAlignment {
return this.state._textAlignment;
}
set alignment(value: TextFieldAlignment) {
this.setState({_textAlignment: value});
}
get autocapitalizationType(): TextFieldAutocapitalizationType {
return this.state._autocapitalizationType;
}
set autocapitalizationType(value: TextFieldAutocapitalizationType) {
this.setState({_autocapitalizationType: value});
}
get returnKeyType(): TextFieldReturnKeyType {
return this.state._returnKeyType;
}
set returnKeyType(value: TextFieldReturnKeyType) {
this.setState({_returnKeyType: value});
}
// Event handlers
onReturn(callback: () => void): void {
this.setState({onReturn: callback});
}
onTextChange(callback: (text: string) => void): void {
this.setState({onTextChange: callback});
}
onBeginEditing(callback: () => void): void {
this.setState({onBeginEditing: callback});
}
onEndEditing(callback: () => void): void {
this.setState({onEndEditing: callback});
}
// Keyboard type methods with validation
setDefaultKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.default;
}
setNumberPadKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.number;
this.text = this.state.text; // Clean existing text
}
setDecimalPadKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.decimal;
this.text = this.state.text; // Clean existing text
}
setEmailAddressKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.email;
this.text = this.state.text.toLowerCase();
}
setPhonePadKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.phone;
this.text = this.state.text; // Clean existing text
}
setURLKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.url;
this.text = this.state.text.toLowerCase();
}
setNumbersAndPunctuationKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.number;
}
setWebSearchKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.default;
}
setTwitterKeyboard(): void {
this.keyboardType = TextFieldKeyboardType.default;
}
// Text alignment methods
leftAlignText(): void {
this.alignment = TextFieldAlignment.left;
}
centerAlignText(): void {
this.alignment = TextFieldAlignment.center;
}
rightAlignText(): void {
this.alignment = TextFieldAlignment.right;
}
// Additional properties
get keyboardAppearance(): 'light' | 'dark' {
return this.state._keyboardAppearance;
}
set keyboardAppearance(value: 'light' | 'dark') {
this.setState({_keyboardAppearance: value});
}
get spellCheckingType(): 'default' | 'no' | 'yes' {
return this.state._spellCheckingType;
}
set spellCheckingType(value: 'default' | 'no' | 'yes') {
this.setState({_spellCheckingType: value});
}
get autocorrectionType(): 'default' | 'no' | 'yes' {
return this.state._autocorrectionType;
}
set autocorrectionType(value: 'default' | 'no' | 'yes') {
this.setState({_autocorrectionType: value});
}
}