new config, aside config

This commit is contained in:
Andrew
2015-03-31 11:35:45 -06:00
parent 0d49841a3c
commit 4ba305305f
5 changed files with 136 additions and 42 deletions

View File

@ -2,22 +2,7 @@ import {Component, Template, Inject, Parent, NgElement} from 'angular2/angular2'
import {ComponentConfig} from 'ionic2/config/component-config'
import * as types from 'ionic2/components/aside/extensions/types'
import * as gestures from 'ionic2/components/aside/extensions/gestures';
export let AsideConfig = new ComponentConfig('aside')
AsideConfig.classes('side', 'type')
AsideConfig.delegate('gesture')
.when({side: 'left'}, gestures.LeftAsideGesture)
.when({side: 'right'}, gestures.RightAsideGesture)
.when({side: 'top'}, gestures.TopAsideGesture)
.when({side: 'bottom'}, gestures.BottomAsideGesture)
AsideConfig.delegate('type')
.when({type: 'overlay'}, types.AsideTypeOverlay)
.when({type: 'push'}, types.AsideTypePush)
.when({type: 'reveal'}, types.AsideTypeReveal)
import {IonicComponent} from 'ionic2/config/component'
@Component({
selector: 'ion-aside',
@ -25,26 +10,23 @@ AsideConfig.delegate('type')
content: 'content',
side: 'side',
dragThreshold: 'dragThreshold'
},
services: [AsideConfig]
}
})
@Template({
inline: `<content></content>`
})
export class Aside {
constructor(
@NgElement() element: NgElement,
configFactory: AsideConfig
@NgElement() element: NgElement
) {
this.domElement = element.domElement
// TODO inject constant instead of using domElement.getAttribute
// TODO let config / platform handle defaults transparently
this.side = this.domElement.getAttribute('side') || 'left'
this.type = this.domElement.getAttribute('type') || 'overlay'
this.config = configFactory.create(this);
this.gestureDelegate = this.config.getDelegate('gesture');
this.typeDelegate = this.config.getDelegate('type');
// FIXME(ajoslin): have to wait for setTimeout for bindings to apply.
setTimeout(() => {
this.config = Aside.config.invoke(this)
this.gestureDelegate = this.config.getDelegate('gesture');
this.typeDelegate = this.config.getDelegate('type');
})
this.domElement.addEventListener('transitionend', ev => {
this.setChanging(false)
@ -75,3 +57,33 @@ export class Aside {
}
}
}
new IonicComponent(Aside, {
bind: {
side: {
default: 'left'
},
type: {
ios: 'reveal',
android: 'overlay',
default: 'overlay',
},
dragThreshold: {},
content: {},
},
delegates: {
gesture: [
[instance => instance.side == 'top', gestures.TopAsideGesture],
[instance => instance.side == 'bottom', gestures.BottomAsideGesture],
[instance => instance.side == 'right', gestures.RightAsideGesture],
[instance => instance.side == 'left', gestures.LeftAsideGesture]
],
type: [
[instance => instance.type == 'overlay', types.AsideTypeOverlay],
[instance => instance.type == 'reveal', types.AsideTypeReveal],
[instance => instance.type == 'push', types.AsideTypePush],
]
}
})

View File

@ -17,7 +17,7 @@ $aside-transition: 0.3s linear transform;
display: none;
}
&.aside-left {
&[side=left] {
width: $aside-width;
left: -$aside-width;
top: 0;
@ -25,11 +25,11 @@ $aside-transition: 0.3s linear transform;
transform: translate3d(0, 0, 0);
&.open,
&.aside-reveal {
&[type=reveal] {
transform: translate3d($aside-width,0,0);
}
}
&.aside-right {
&[side=right] {
width: $aside-width;
left: 100%;
top: 0;
@ -37,11 +37,11 @@ $aside-transition: 0.3s linear transform;
transform: translate3d(0,0,0);
&.open,
&.aside-reveal {
&[type=reveal] {
transform: translate3d(-$aside-width,0,0);
}
}
&.aside-top {
&[side=top] {
height: $aside-width;
top: -$aside-width;
left: 0;
@ -49,11 +49,11 @@ $aside-transition: 0.3s linear transform;
transform: translate3d(0,0,0);
&.open,
&.aside-reveal {
&[type=reveal] {
transform: translate3d(0,$aside-width,0);
}
}
&.aside-bottom {
&[side=bottom] {
height: $aside-width;
top: 100%;
left: 0;

78
src/config/component.js Normal file
View File

@ -0,0 +1,78 @@
import * as util from 'ionic2/util'
import {platform} from 'ionic2/platform/platform'
let platforms = Object.keys(platform.registry)
let platformName = platform.getName()
export class IonicComponent {
constructor(ComponentClass, {
bind,
delegates
}) {
// TODO give errors if not providing valid delegates
ComponentClass.config = this
this.componentCssName = util.pascalCaseToDashCase(ComponentClass.name)
this.bind = bind || (bind = {})
for (let attrName in bind) {
let binding = bind[attrName]
if (util.isObject(binding)) {
binding.property || (binding.property = attrName)
// TODO recompute defaultValue when user possibly adds a binding
binding._defaultValue = binding[platformName] || binding.default;
}
}
this.delegates = delegates || (delegates = {})
// for (let delegateName of delegates) {
// let delegate = delegates[delegateName]
// }
}
_computeDefaultValue(binding = {}) {
}
invoke(instance) {
let config = this
instance.domElement.classList.add(this.componentCssName)
instance.domElement.classList.add(`${this.componentCssName}-${platformName}`)
for (let attrName in this.bind) {
let binding = this.bind[attrName]
let defaultValue = binding._defaultValue
if (!instance[binding.property] && defaultValue) {
instance[binding.property] = defaultValue
instance.domElement.setAttribute(attrName, defaultValue)
}
}
return {
getDelegate(delegateName) {
let cases = (config.delegates || {})[delegateName] || []
for (let i = 0; i < cases.length; i++) {
let delegateCase = cases[i]
try {
if (util.isArray(delegateCase)) {
if (delegateCase[0](instance)) return new delegateCase[1](instance)
} else {
return new delegateCase(instance)
}
}catch(e){debugger;}
}
}
}
}
}
/*
@IonicComponent({
selector: 'ion-back-button',
bind: {
icon: {
ios: 'ion-back-ios',
android: 'ion-back-android',
default: 'ion-back'
}
}
})
*/

View File

@ -11,7 +11,7 @@ class Platform {
class PlatformController {
current: Platform;
constructor() {
this.registry = []
this.registry = {}
}
set(platform) {
@ -21,10 +21,13 @@ class PlatformController {
get() {
return this.current
}
getName() {
return this.current && this.current.name
}
register(platform) {
if (!platform instanceof Platform) platform = new Platform(platform)
this.registry.push(platform)
this.registry[platform.name] = platform
}
setDefaultPlatform(platform) {
@ -39,8 +42,8 @@ class PlatformController {
}
detect() {
for (let platform of this.registry) {
if (platform.matcher()) {
for (let name in this.registry) {
if (this.registry[name].matcher()) {
return platform
}
}

View File

@ -28,10 +28,11 @@ export function defaults(dest) {
return dest;
}
export let isString = val => typeof val === 'string'
export let isFunction = val => typeof val === 'function'
export let isDefined = val => typeof val === 'undefined'
export let isObject = val => typeof val === 'object'
export const isString = val => typeof val === 'string'
export const isFunction = val => typeof val === 'function'
export const isDefined = val => typeof val === 'undefined'
export const isObject = val => typeof val === 'object'
export const isArray = Array.isArray
export function pascalCaseToDashCase(str = '') {
return str.charAt(0).toLowerCase() + str.substring(1).replace(/[A-Z]/g, match => {