refactor(): IonicForm/IonicKeyboard

Closes #224
This commit is contained in:
Adam Bradley
2015-10-09 11:29:57 -05:00
parent 8eb3e61e58
commit 03cb1a7a5b
15 changed files with 136 additions and 140 deletions

View File

@ -6,7 +6,6 @@ export * from 'ionic/components/blur/blur'
export * from 'ionic/components/button/button' export * from 'ionic/components/button/button'
export * from 'ionic/components/checkbox/checkbox' export * from 'ionic/components/checkbox/checkbox'
export * from 'ionic/components/content/content' export * from 'ionic/components/content/content'
export * from 'ionic/components/form/form'
export * from 'ionic/components/icon/icon' export * from 'ionic/components/icon/icon'
export * from 'ionic/components/item/item' export * from 'ionic/components/item/item'
export * from 'ionic/components/item/item-group' export * from 'ionic/components/item/item-group'

View File

@ -1,7 +1,7 @@
import {Component, Directive, Optional, NgControl, ElementRef, Renderer} from 'angular2/angular2'; import {Component, Directive, Optional, NgControl, ElementRef, Renderer} from 'angular2/angular2';
import {Ion} from '../ion'; import {Ion} from '../ion';
import {IonicForm} from '../form/form'; import {IonicForm} from '../../util/form';
/** /**
* The checkbox is no different than the HTML checkbox input, except it's styled differently * The checkbox is no different than the HTML checkbox input, except it's styled differently

View File

@ -2,7 +2,7 @@ import {Component, ElementRef, Optional} from 'angular2/angular2';
import {Ion} from '../ion'; import {Ion} from '../ion';
import {IonicConfig} from '../../config/config'; import {IonicConfig} from '../../config/config';
import {IonicPlatform} from '../../platform/platform'; import {IonicKeyboard} from '../../util/keyboard';
import {ViewController} from '../nav/view-controller'; import {ViewController} from '../nav/view-controller';
import {Tab} from '../tabs/tab'; import {Tab} from '../tabs/tab';
import {ScrollTo} from '../../animations/scroll-to'; import {ScrollTo} from '../../animations/scroll-to';
@ -33,10 +33,10 @@ export class Content extends Ion {
* @param {ElementRef} elementRef A reference to the component's DOM element. * @param {ElementRef} elementRef A reference to the component's DOM element.
* @param {IonicConfig} config The config object to change content's default settings. * @param {IonicConfig} config The config object to change content's default settings.
*/ */
constructor(elementRef: ElementRef, config: IonicConfig, platform: IonicPlatform, @Optional() viewCtrl: ViewController) { constructor(elementRef: ElementRef, config: IonicConfig, keyboard: IonicKeyboard, @Optional() viewCtrl: ViewController) {
super(elementRef, config); super(elementRef, config);
this.scrollPadding = 0; this.scrollPadding = 0;
this.platform = platform; this.keyboard = keyboard;
if(viewCtrl) { if(viewCtrl) {
viewCtrl.setContent(this); viewCtrl.setContent(this);
@ -168,7 +168,7 @@ export class Content extends Ion {
if (!this.keyboardPromise) { if (!this.keyboardPromise) {
this.keyboardPromise = this.platform.onKeyboardClose(() => { this.keyboardPromise = this.keyboard.onClose(() => {
if (this) { if (this) {
this.scrollPadding = 0; this.scrollPadding = 0;
if (this.scrollElement) this.scrollElement.style.paddingBottom = ''; if (this.scrollElement) this.scrollElement.style.paddingBottom = '';

View File

@ -1,98 +0,0 @@
// Forms
// --------------------------------------------------
ion-input {
// text inputs
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"] {
display: block;
background: transparent;
border: 0;
width: 100%;
}
}
textarea {
margin: 0;
padding: 0;
height: auto;
overflow: auto;
font: inherit;
color: inherit;
}
.platform-mobile textarea {
resize: none;
}
// Placeholder
// -------------------------------
input,
textarea {
@include placeholder();
}
// DISABLED STATE
// -------------------------------
// Disabled and read-only inputs
input[disabled],
select[disabled],
textarea[disabled],
select[readonly] {
cursor: not-allowed;
}
// Focus Utils
// -------------------------------
focus-ctrl {
position: fixed;
input,
button {
position: fixed;
top: 1px;
width: 9px;
left: -9999px;
z-index: 9999;
}
}
/*focus-ctrl input[tabindex="999"] {
left: 0px;
}
focus-ctrl input[tabindex="1001"] {
left: 20px;
}
focus-ctrl input[tabindex="1002"] {
left: auto;
right: 10px;
}
focus-ctrl input:focus {
background: red;
}*/

View File

@ -5,6 +5,7 @@ import {IonicApp} from '../app/app';
import {IonicConfig} from '../../config/config'; import {IonicConfig} from '../../config/config';
import {ConfigComponent} from '../../config/decorators'; import {ConfigComponent} from '../../config/decorators';
import {IonicPlatform} from '../../platform/platform'; import {IonicPlatform} from '../../platform/platform';
import {IonicKeyboard} from '../../util/keyboard';
import * as gestures from './menu-gestures'; import * as gestures from './menu-gestures';
@ -67,11 +68,13 @@ export class Menu extends Ion {
app: IonicApp, app: IonicApp,
elementRef: ElementRef, elementRef: ElementRef,
config: IonicConfig, config: IonicConfig,
platform: IonicPlatform platform: IonicPlatform,
keyboard: IonicKeyboard
) { ) {
super(elementRef, config); super(elementRef, config);
this.app = app; this.app = app;
this.platform = platform; this.platform = platform;
this.keyboard = keyboard;
this.opening = new EventEmitter('opening'); this.opening = new EventEmitter('opening');
this.isOpen = false; this.isOpen = false;
@ -188,6 +191,7 @@ export class Menu extends Ion {
this._disable(); this._disable();
this.app.setTransitioning(true); this.app.setTransitioning(true);
this.keyboard.close();
} }
_after(isOpen) { _after(isOpen) {

View File

@ -40,6 +40,11 @@
<button class="e2eContentToggleMenu" menu-toggle="rightMenu">Toggle Right Menu</button> <button class="e2eContentToggleMenu" menu-toggle="rightMenu">Toggle Right Menu</button>
</p> </p>
<f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f> <ion-card>
<ion-input>
<ion-label>Username:<ion-label>
<input type="text">
</ion-input>
</ion-card>
</ion-content> </ion-content>

View File

@ -1,6 +1,6 @@
import {Component, Directive, ElementRef, Renderer, Host, Optional, NgControl, Inject, forwardRef} from 'angular2/angular2'; import {Component, Directive, ElementRef, Renderer, Host, Optional, NgControl, Inject, forwardRef} from 'angular2/angular2';
import {IonicForm} from '../form/form'; import {IonicForm} from '../../util/form';
import {IonicConfig} from '../../config/config'; import {IonicConfig} from '../../config/config';
import {pointerCoord} from '../../util/dom'; import {pointerCoord} from '../../util/dom';

View File

@ -8,6 +8,31 @@ $input-focus-box-shadow: inset 0px 0px 8px 0px $input-focus-border-color
$text-input-background-color: $list-background-color !default; $text-input-background-color: $list-background-color !default;
ion-input {
// text inputs
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"] {
display: block;
background: transparent;
border: 0;
width: 100%;
}
}
ion-input.item { ion-input.item {
align-items: flex-start; align-items: flex-start;
} }
@ -37,3 +62,22 @@ ion-input.has-focus [text-input] {
ion-input textarea { ion-input textarea {
padding-top: 9px; padding-top: 9px;
} }
textarea {
margin: 0;
padding: 0;
height: auto;
overflow: auto;
font: inherit;
color: inherit;
}
.platform-mobile textarea {
resize: none;
}
input,
textarea {
@include placeholder();
}

View File

@ -1,7 +1,7 @@
import {Directive, Host, Optional, ElementRef, Renderer, Attribute, Query, QueryList, NgZone} from 'angular2/angular2'; import {Directive, Host, Optional, ElementRef, Renderer, Attribute, Query, QueryList, NgZone} from 'angular2/angular2';
import {IonicConfig} from '../../config/config'; import {IonicConfig} from '../../config/config';
import {IonicForm} from '../form/form'; import {IonicForm} from '../../util/form';
import {Label} from './label'; import {Label} from './label';
import {IonicApp} from '../app/app'; import {IonicApp} from '../app/app';
import {Content} from '../content/content'; import {Content} from '../content/content';

View File

@ -5,7 +5,8 @@ import {IonicApp} from '../components/app/app';
import {IonicConfig} from './config'; import {IonicConfig} from './config';
import {IonicPlatform} from '../platform/platform'; import {IonicPlatform} from '../platform/platform';
import {OverlayController} from '../components/overlay/overlay-controller'; import {OverlayController} from '../components/overlay/overlay-controller';
import {IonicForm} from '../components/form/form'; import {IonicForm} from '../util/form';
import {IonicKeyboard} from '../util/keyboard';
import {ActionSheet} from '../components/action-sheet/action-sheet'; import {ActionSheet} from '../components/action-sheet/action-sheet';
import {Modal} from '../components/modal/modal'; import {Modal} from '../components/modal/modal';
import {Popup} from '../components/popup/popup'; import {Popup} from '../components/popup/popup';
@ -47,6 +48,7 @@ export function ionicBindings(rootCmp, config) {
bind(TapClick).toValue(tapClick), bind(TapClick).toValue(tapClick),
bind(Events).toValue(events), bind(Events).toValue(events),
IonicForm, IonicForm,
IonicKeyboard,
OverlayController, OverlayController,
ActionSheet, ActionSheet,
Modal, Modal,

View File

@ -28,7 +28,6 @@
"components/icon/icon", "components/icon/icon",
"components/item/item", "components/item/item",
"components/item/item-media", "components/item/item-media",
"components/form/form",
"components/grid/grid", "components/grid/grid",
"components/text-input/text-input", "components/text-input/text-input",
"components/text-input/label", "components/text-input/label",

View File

@ -211,34 +211,6 @@ export class IonicPlatform {
return !this.isPortrait(); return !this.isPortrait();
} }
isKeyboardOpen() {
return dom.hasFocusedTextInput();
}
onKeyboardClose(callback) {
const self = this;
let promise = null;
if (!callback) {
// a callback wasn't provided, so let's return a promise instead
promise = new Promise(resolve => { callback = resolve; });
}
function checkKeyboard() {
if (!self.isKeyboardOpen()) {
callback();
} else {
setTimeout(checkKeyboard, 500);
}
}
setTimeout(checkKeyboard, 100);
return promise;
}
windowResize() { windowResize() {
let self = this; let self = this;
clearTimeout(self._resizeTimer); clearTimeout(self._resizeTimer);

View File

@ -1,7 +1,8 @@
import {Injectable, NgZone} from 'angular2/angular2'; import {Injectable, NgZone} from 'angular2/angular2';
import {IonicConfig} from '../../config/config'; import {IonicConfig} from '../config/config';
import {raf} from '../../util/dom'; import {raf} from './dom';
/** /**
* The Input component is used to focus text input elements. * The Input component is used to focus text input elements.

51
ionic/util/keyboard.ts Normal file
View File

@ -0,0 +1,51 @@
import {Injectable} from 'angular2/angular2';
import {IonicForm} from './form';
import * as dom from './dom';
@Injectable()
export class IonicKeyboard {
constructor(form: IonicForm) {
this.form = form;
}
isOpen() {
return dom.hasFocusedTextInput();
}
onClose(callback) {
const self = this;
let promise = null;
if (!callback) {
// a callback wasn't provided, so let's return a promise instead
promise = new Promise(resolve => { callback = resolve; });
}
function checkKeyboard() {
if (!self.isOpen()) {
callback();
} else {
setTimeout(checkKeyboard, 500);
}
}
setTimeout(checkKeyboard, 100);
return promise;
}
close() {
dom.raf(() => {
if (dom.hasFocusedTextInput()) {
// only focus out when a text input has focus
this.form.focusOut();
}
});
}
}

View File

@ -53,6 +53,23 @@
} }
// Focus Controls
// -------------------------------
focus-ctrl {
position: fixed;
input,
button {
position: fixed;
top: 1px;
width: 9px;
left: -9999px;
z-index: 9999;
}
}
// Backdrop // Backdrop
// -------------------------------------------------- // --------------------------------------------------