feat:input add onSubmitEditing
This commit is contained in:
parent
ff641bf983
commit
5263731dd7
@ -23,10 +23,12 @@ import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JSValue;
|
||||
@ -221,6 +223,28 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "onSubmitEditing":
|
||||
if (!prop.isString()) {
|
||||
return;
|
||||
}
|
||||
final String functionId = prop.asString().value();
|
||||
view.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
switch (actionId) {
|
||||
case EditorInfo.IME_ACTION_UNSPECIFIED:
|
||||
case EditorInfo.IME_ACTION_NEXT:
|
||||
case EditorInfo.IME_ACTION_DONE:
|
||||
case EditorInfo.IME_ACTION_GO:
|
||||
case EditorInfo.IME_ACTION_SEARCH:
|
||||
case EditorInfo.IME_ACTION_SEND:
|
||||
callJSResponse(functionId, v.getText().toString());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
super.blend(view, name, prop);
|
||||
break;
|
||||
|
@ -6,14 +6,12 @@ import {
|
||||
layoutConfig,
|
||||
LayoutSpec,
|
||||
Input,
|
||||
Gravity,
|
||||
log,
|
||||
Color,
|
||||
input,
|
||||
text,
|
||||
InputType,
|
||||
} from "doric";
|
||||
import { title, colors } from "./utils";
|
||||
import { preferenceView } from "./components/PreferenceView";
|
||||
import { title } from "./utils";
|
||||
|
||||
function getInput(c: Partial<Input>) {
|
||||
const inputView = input(c);
|
||||
@ -37,56 +35,64 @@ function getInput(c: Partial<Input>) {
|
||||
inputView.onTextChange = (text) => {
|
||||
inputed.text = `Inputed:${text}`;
|
||||
};
|
||||
return [inputView, isFocused, inputed];
|
||||
inputView.onSubmitEditing = (text) => {
|
||||
inputed.text = `Submited: ${text}`
|
||||
};
|
||||
|
||||
|
||||
|
||||
return [
|
||||
inputView,
|
||||
isFocused,
|
||||
inputed,
|
||||
preferenceView().applyChild({
|
||||
title: {
|
||||
text: "Multiline"
|
||||
},
|
||||
switch: {
|
||||
state: true,
|
||||
onSwitch: (ret) => {
|
||||
inputView.multiline = ret
|
||||
}
|
||||
}
|
||||
}),
|
||||
preferenceView().applyChild({
|
||||
title: {
|
||||
text: "Editable"
|
||||
},
|
||||
switch: {
|
||||
state: true,
|
||||
onSwitch: (ret) => {
|
||||
inputView.editable = ret
|
||||
}
|
||||
}
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@Entry
|
||||
class InputDemo extends Panel {
|
||||
build(root: Group) {
|
||||
var [inputView, ...otherView] = getInput({
|
||||
layoutConfig: {
|
||||
widthSpec: LayoutSpec.FIT,
|
||||
heightSpec: LayoutSpec.FIT,
|
||||
},
|
||||
hintText: "Please input something in one line",
|
||||
border: {
|
||||
width: 1,
|
||||
color: Color.GRAY,
|
||||
},
|
||||
multiline: false,
|
||||
textSize: 20,
|
||||
maxLength: 20,
|
||||
padding: { top: 10, bottom: 11 },
|
||||
inputType: InputType.Decimal,
|
||||
password: true,
|
||||
});
|
||||
let inputView: Input
|
||||
scroller(
|
||||
vlayout(
|
||||
[
|
||||
title("Demo"),
|
||||
// ...getInput({
|
||||
// layoutConfig: {
|
||||
// widthSpec: LayoutSpec.JUST,
|
||||
// heightSpec: LayoutSpec.FIT,
|
||||
// },
|
||||
// width: 300,
|
||||
// hintText: "Please input something",
|
||||
// border: {
|
||||
// width: 1,
|
||||
// color: Color.GRAY,
|
||||
// },
|
||||
// textSize: 40,
|
||||
// maxLength: 20,
|
||||
// }),
|
||||
inputView,
|
||||
...otherView,
|
||||
...getInput({
|
||||
layoutConfig: {
|
||||
widthSpec: LayoutSpec.MOST,
|
||||
heightSpec: LayoutSpec.FIT,
|
||||
},
|
||||
hintText: "Please input something",
|
||||
border: {
|
||||
width: 1,
|
||||
color: Color.GRAY,
|
||||
},
|
||||
}),
|
||||
],
|
||||
{
|
||||
space: 10,
|
||||
layoutConfig: layoutConfig().most().configHeight(LayoutSpec.MOST),
|
||||
onClick: () => {
|
||||
(inputView as Input).releaseFocus(context);
|
||||
},
|
||||
}
|
||||
),
|
||||
{
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
typedef void (^onFocusChangeBlock)(BOOL focused, DoricInputNode *node);
|
||||
|
||||
typedef void (^onSubmitEditingBlock)(NSString *text, DoricInputNode *node);
|
||||
|
||||
@implementation DoricInputView
|
||||
|
||||
- (instancetype)init {
|
||||
@ -71,7 +73,8 @@ - (CGSize)sizeThatFits:(CGSize)size {
|
||||
|
||||
@interface DoricInputNode () <UITextViewDelegate>
|
||||
@property(nonatomic, copy) onTextChangeBlock onTextChange;
|
||||
@property(nonatomic, copy) onFocusChangeBlock onFocusShange;
|
||||
@property(nonatomic, copy) onFocusChangeBlock onFocusChange;
|
||||
@property(nonatomic, copy) onSubmitEditingBlock onSubmitEditing;
|
||||
@property(nonatomic, strong) NSNumber *maxLength;
|
||||
@end
|
||||
|
||||
@ -107,6 +110,9 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
|
||||
BOOL value = [(NSNumber *) prop boolValue];
|
||||
if (!value) {
|
||||
view.textContainer.maximumNumberOfLines = 1;
|
||||
if (view.text.length > 0) {
|
||||
view.text = [view.text stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
|
||||
}
|
||||
} else {
|
||||
view.textContainer.maximumNumberOfLines = 0;
|
||||
}
|
||||
@ -124,11 +130,11 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
|
||||
}
|
||||
} else if ([name isEqualToString:@"onFocusChange"]) {
|
||||
if ([prop isKindOfClass:[NSString class]]) {
|
||||
self.onFocusShange = ^(BOOL focused, DoricInputNode *node) {
|
||||
self.onFocusChange = ^(BOOL focused, DoricInputNode *node) {
|
||||
[node callJSResponse:prop, @(focused), nil];
|
||||
};
|
||||
} else {
|
||||
self.onFocusShange = nil;
|
||||
self.onFocusChange = nil;
|
||||
}
|
||||
|
||||
} else if ([name isEqualToString:@"maxLength"]) {
|
||||
@ -161,6 +167,9 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
|
||||
} else if ([name isEqualToString:@"editable"]) {
|
||||
view.editable = [(NSNumber *) prop boolValue];
|
||||
} else if ([name isEqualToString:@"returnKeyType"]) {
|
||||
if (view.textContainer.maximumNumberOfLines == 1) {
|
||||
return;
|
||||
}
|
||||
switch ([(NSNumber *) prop integerValue]) {
|
||||
case 1:
|
||||
view.returnKeyType = UIReturnKeyDone;
|
||||
@ -182,6 +191,14 @@ - (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:
|
||||
view.returnKeyType = UIReturnKeyDefault;
|
||||
break;
|
||||
}
|
||||
} else if ([name isEqualToString:@"onSubmitEditing"]) {
|
||||
if ([prop isKindOfClass:[NSString class]]) {
|
||||
self.onSubmitEditing = ^(NSString *text, DoricInputNode *node) {
|
||||
[node callJSResponse:prop, text, nil];
|
||||
};
|
||||
} else {
|
||||
self.onSubmitEditing = nil;
|
||||
}
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
@ -237,15 +254,27 @@ - (void)releaseFocus {
|
||||
#pragma mark - UITextViewDelegate
|
||||
|
||||
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
|
||||
if (self.onFocusShange) {
|
||||
self.onFocusShange(YES, self);
|
||||
if (self.onFocusChange) {
|
||||
self.onFocusChange(YES, self);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
|
||||
if (self.onFocusShange) {
|
||||
self.onFocusShange(NO, self);
|
||||
if (self.onFocusChange) {
|
||||
self.onFocusChange(NO, self);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
|
||||
if ([text isEqualToString:@"\n"]) {
|
||||
if (textView.textContainer.maximumNumberOfLines == 1) {
|
||||
if (self.onSubmitEditing) {
|
||||
self.onSubmitEditing(textView.text, self);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
@ -2767,6 +2767,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
|
||||
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") { return Reflect.metadata(k, v); }
|
||||
};
|
||||
exports.ReturnKeyType = void 0;
|
||||
(function (ReturnKeyType) {
|
||||
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
|
||||
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
|
||||
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
|
||||
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
|
||||
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
|
||||
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
|
||||
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
|
||||
var Input = /** @class */ (function (_super) {
|
||||
__extends$5(Input, _super);
|
||||
function Input() {
|
||||
@ -2836,6 +2845,18 @@ var Input = /** @class */ (function (_super) {
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "password", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "editable", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Number)
|
||||
], Input.prototype, "returnKeyType", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Function)
|
||||
], Input.prototype, "onSubmitEditing", void 0);
|
||||
return Input;
|
||||
}(View));
|
||||
exports.InputType = void 0;
|
||||
|
@ -2135,6 +2135,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
|
||||
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
exports.ReturnKeyType = void 0;
|
||||
(function (ReturnKeyType) {
|
||||
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
|
||||
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
|
||||
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
|
||||
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
|
||||
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
|
||||
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
|
||||
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
|
||||
class Input extends View {
|
||||
getText(context) {
|
||||
return this.nativeChannel(context, 'getText')();
|
||||
@ -2200,6 +2209,18 @@ __decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "password", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "editable", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Number)
|
||||
], Input.prototype, "returnKeyType", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Function)
|
||||
], Input.prototype, "onSubmitEditing", void 0);
|
||||
exports.InputType = void 0;
|
||||
(function (InputType) {
|
||||
InputType[InputType["Default"] = 0] = "Default";
|
||||
|
@ -3656,6 +3656,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
|
||||
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
exports.ReturnKeyType = void 0;
|
||||
(function (ReturnKeyType) {
|
||||
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
|
||||
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
|
||||
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
|
||||
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
|
||||
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
|
||||
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
|
||||
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
|
||||
class Input extends View {
|
||||
getText(context) {
|
||||
return this.nativeChannel(context, 'getText')();
|
||||
@ -3721,6 +3730,18 @@ __decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "password", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "editable", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Number)
|
||||
], Input.prototype, "returnKeyType", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Function)
|
||||
], Input.prototype, "onSubmitEditing", void 0);
|
||||
exports.InputType = void 0;
|
||||
(function (InputType) {
|
||||
InputType[InputType["Default"] = 0] = "Default";
|
||||
|
11
doric-js/index.d.ts
vendored
11
doric-js/index.d.ts
vendored
@ -760,6 +760,14 @@ declare module 'doric/lib/src/widget/input' {
|
||||
import { Color } from "doric/lib/src/util/color";
|
||||
import { Gravity } from "doric/lib/src/util/gravity";
|
||||
import { BridgeContext } from "doric/lib/src/runtime/global";
|
||||
export enum ReturnKeyType {
|
||||
Default = 0,
|
||||
Done = 1,
|
||||
Search = 2,
|
||||
Next = 3,
|
||||
Go = 4,
|
||||
Send = 5
|
||||
}
|
||||
export class Input extends View {
|
||||
text?: string;
|
||||
textColor?: Color;
|
||||
@ -773,6 +781,9 @@ declare module 'doric/lib/src/widget/input' {
|
||||
onFocusChange?: (focused: boolean) => void;
|
||||
maxLength?: number;
|
||||
password?: boolean;
|
||||
editable?: boolean;
|
||||
returnKeyType?: ReturnKeyType;
|
||||
onSubmitEditing?: (text: string) => void;
|
||||
getText(context: BridgeContext): Promise<string>;
|
||||
setSelection(context: BridgeContext, start: number, end?: number): Promise<string>;
|
||||
requestFocus(context: BridgeContext): Promise<any>;
|
||||
|
11
doric-js/lib/src/widget/input.d.ts
vendored
11
doric-js/lib/src/widget/input.d.ts
vendored
@ -2,6 +2,14 @@ import { View } from "../ui/view";
|
||||
import { Color } from "../util/color";
|
||||
import { Gravity } from "../util/gravity";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export declare enum ReturnKeyType {
|
||||
Default = 0,
|
||||
Done = 1,
|
||||
Search = 2,
|
||||
Next = 3,
|
||||
Go = 4,
|
||||
Send = 5
|
||||
}
|
||||
export declare class Input extends View {
|
||||
text?: string;
|
||||
textColor?: Color;
|
||||
@ -15,6 +23,9 @@ export declare class Input extends View {
|
||||
onFocusChange?: (focused: boolean) => void;
|
||||
maxLength?: number;
|
||||
password?: boolean;
|
||||
editable?: boolean;
|
||||
returnKeyType?: ReturnKeyType;
|
||||
onSubmitEditing?: (text: string) => void;
|
||||
getText(context: BridgeContext): Promise<string>;
|
||||
setSelection(context: BridgeContext, start: number, end?: number): Promise<string>;
|
||||
requestFocus(context: BridgeContext): Promise<any>;
|
||||
|
@ -26,6 +26,15 @@ import { View, Property, InconsistProperty } from "../ui/view";
|
||||
import { Color } from "../util/color";
|
||||
import { Gravity } from "../util/gravity";
|
||||
import { layoutConfig } from "../util/index.util";
|
||||
export var ReturnKeyType;
|
||||
(function (ReturnKeyType) {
|
||||
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
|
||||
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
|
||||
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
|
||||
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
|
||||
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
|
||||
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
|
||||
})(ReturnKeyType || (ReturnKeyType = {}));
|
||||
export class Input extends View {
|
||||
getText(context) {
|
||||
return this.nativeChannel(context, 'getText')();
|
||||
@ -91,6 +100,18 @@ __decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], Input.prototype, "password", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], Input.prototype, "editable", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], Input.prototype, "returnKeyType", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], Input.prototype, "onSubmitEditing", void 0);
|
||||
export var InputType;
|
||||
(function (InputType) {
|
||||
InputType[InputType["Default"] = 0] = "Default";
|
||||
|
@ -72,6 +72,10 @@ export class Input extends View {
|
||||
@Property
|
||||
returnKeyType?: ReturnKeyType
|
||||
|
||||
@Property
|
||||
onSubmitEditing?: (text: string) => void
|
||||
|
||||
|
||||
getText(context: BridgeContext) {
|
||||
return this.nativeChannel(context, 'getText')() as Promise<string>
|
||||
}
|
||||
|
21
doric-web/dist/index.js
vendored
21
doric-web/dist/index.js
vendored
@ -3710,6 +3710,15 @@ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators,
|
||||
var __metadata$3 = (undefined && undefined.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
exports.ReturnKeyType = void 0;
|
||||
(function (ReturnKeyType) {
|
||||
ReturnKeyType[ReturnKeyType["Default"] = 0] = "Default";
|
||||
ReturnKeyType[ReturnKeyType["Done"] = 1] = "Done";
|
||||
ReturnKeyType[ReturnKeyType["Search"] = 2] = "Search";
|
||||
ReturnKeyType[ReturnKeyType["Next"] = 3] = "Next";
|
||||
ReturnKeyType[ReturnKeyType["Go"] = 4] = "Go";
|
||||
ReturnKeyType[ReturnKeyType["Send"] = 5] = "Send";
|
||||
})(exports.ReturnKeyType || (exports.ReturnKeyType = {}));
|
||||
class Input extends View {
|
||||
getText(context) {
|
||||
return this.nativeChannel(context, 'getText')();
|
||||
@ -3775,6 +3784,18 @@ __decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "password", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Boolean)
|
||||
], Input.prototype, "editable", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Number)
|
||||
], Input.prototype, "returnKeyType", void 0);
|
||||
__decorate$3([
|
||||
Property,
|
||||
__metadata$3("design:type", Function)
|
||||
], Input.prototype, "onSubmitEditing", void 0);
|
||||
exports.InputType = void 0;
|
||||
(function (InputType) {
|
||||
InputType[InputType["Default"] = 0] = "Default";
|
||||
|
2
doric-web/dist/index.js.map
vendored
2
doric-web/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user