mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 03:32:21 +08:00
aside(): initial types work
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"esnext": true,
|
"esnext": true,
|
||||||
"expr": true
|
"expr": true,
|
||||||
|
"asi": true
|
||||||
}
|
}
|
||||||
|
11
gulpfile.js
11
gulpfile.js
@ -55,7 +55,7 @@ gulp.task('clean', function(done) {
|
|||||||
del([buildConfig.dist], done);
|
del([buildConfig.dist], done);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('e2e', function() {
|
gulp.task('e2e', ['sass'], function() {
|
||||||
var e2eSrc = path.join(__dirname, 'src/components/**/test/**/*');
|
var e2eSrc = path.join(__dirname, 'src/components/**/test/**/*');
|
||||||
var templateSrc = path.join(__dirname, 'scripts/e2e/index.template.html');
|
var templateSrc = path.join(__dirname, 'scripts/e2e/index.template.html');
|
||||||
var e2eDest = path.join(__dirname, 'dist/e2e/');
|
var e2eDest = path.join(__dirname, 'dist/e2e/');
|
||||||
@ -93,15 +93,8 @@ gulp.task('ng2-rename', function(done) {
|
|||||||
gulp.task('ng2', ['ng2-rename'], function() {
|
gulp.task('ng2', ['ng2-rename'], function() {
|
||||||
var builder = new SystemJsBuilder();
|
var builder = new SystemJsBuilder();
|
||||||
builder.config({
|
builder.config({
|
||||||
traceurOptions: {
|
|
||||||
'sourceMaps': true,
|
|
||||||
'annotations': true,
|
|
||||||
'types': true,
|
|
||||||
'script': false,
|
|
||||||
'memberVariables': true,
|
|
||||||
'modules': 'instantiate'
|
|
||||||
},
|
|
||||||
baseURL: 'dist/lib',
|
baseURL: 'dist/lib',
|
||||||
|
traceurOptions: buildConfig.traceurOptions,
|
||||||
map: {
|
map: {
|
||||||
rx: __dirname + '/node_modules/rx'
|
rx: __dirname + '/node_modules/rx'
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,13 @@ module.exports = {
|
|||||||
html: 'src/**/*.html',
|
html: 'src/**/*.html',
|
||||||
scss: 'src/components/**/*.scss',
|
scss: 'src/components/**/*.scss',
|
||||||
},
|
},
|
||||||
|
traceurOptions: {
|
||||||
|
'sourceMaps': true,
|
||||||
|
'annotations': true,
|
||||||
|
'types': true,
|
||||||
|
'script': false,
|
||||||
|
'memberVariables': true,
|
||||||
|
'modules': 'instantiate'
|
||||||
|
},
|
||||||
protractorPort: 8876
|
protractorPort: 8876
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,7 @@ html {
|
|||||||
|
|
||||||
.pane {
|
.pane {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@include flex-display();
|
@include flex-display();
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
|
||||||
|
.notransition {
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.hide.hide.hide {
|
.hide.hide.hide {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,14 @@
|
|||||||
@import
|
@import
|
||||||
"../aside/aside",
|
"../aside/aside",
|
||||||
"../button/button",
|
"../button/button",
|
||||||
|
"../content/content",
|
||||||
"../item/item",
|
"../item/item",
|
||||||
"../list/list",
|
"../list/list",
|
||||||
"../modal/modal",
|
"../modal/modal",
|
||||||
"../switch/switch",
|
"../switch/switch",
|
||||||
"../tabs/tabs",
|
"../tabs/tabs",
|
||||||
"../toolbar/toolbar";
|
"../toolbar/toolbar",
|
||||||
|
"../view/view";
|
||||||
|
|
||||||
|
|
||||||
// Android Components
|
// Android Components
|
||||||
|
88
src/components/aside/aside-gestures.js
Normal file
88
src/components/aside/aside-gestures.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import {AsideConfig, Aside} from './aside';
|
||||||
|
import {SlideEdgeGesture} from '../../core/gestures/slide-edge-gesture';
|
||||||
|
|
||||||
|
class AsideGesture extends SlideEdgeGesture {
|
||||||
|
constructor(aside: Aside) {
|
||||||
|
this.aside = aside;
|
||||||
|
this.slideElement = aside.domElement.parentNode;
|
||||||
|
super(this.slideElement, {
|
||||||
|
direction: (aside.side === 'left' || aside.side === 'right') ? 'x' : 'y',
|
||||||
|
edge: aside.side,
|
||||||
|
threshold: 75
|
||||||
|
});
|
||||||
|
this.listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
canStart(ev) {
|
||||||
|
// Only restrict edges if the aside is closed
|
||||||
|
return this.aside.isOpen ? true : super.canStart(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSlideBeforeStart(slide, ev) {
|
||||||
|
console.log('beforestart');
|
||||||
|
this.aside.setSliding(true);
|
||||||
|
this.aside.setChanging(true);
|
||||||
|
return new Promise(resolve => {
|
||||||
|
requestAnimationFrame(resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onSlide(slide, ev) {
|
||||||
|
this.aside.setTransform('translate3d(' + slide.distance + 'px,0,0)');
|
||||||
|
}
|
||||||
|
onSlideEnd(slide, ev) {
|
||||||
|
this.aside.setTransform('');
|
||||||
|
this.aside.setSliding(false);
|
||||||
|
if (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5) {
|
||||||
|
this.aside.setOpen(!this.aside.isOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getElementStartPos(slide, ev) {
|
||||||
|
return this.aside.isOpen ? slide.max : slide.min;
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: 0,
|
||||||
|
max: this.aside.domElement.offsetWidth
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LeftAsideGesture extends AsideGesture {}
|
||||||
|
|
||||||
|
export class RightAsideGesture extends LeftAsideGesture {
|
||||||
|
getElementStartPos(slide, ev) {
|
||||||
|
return this.aside.isOpen ? slide.min : slide.max;
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: -this.aside.domElement.offsetWidth,
|
||||||
|
max: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TopAsideGesture extends AsideGesture {
|
||||||
|
onSlide(slide, ev) {
|
||||||
|
this.aside.setTransform('translate3d(0,' + slide.distance + 'px,0)');
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: 0,
|
||||||
|
max: this.aside.domElement.offsetHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BottomAsideGesture extends TopAsideGesture {
|
||||||
|
getElementStartPos(slide, ev) {
|
||||||
|
return this.aside.isOpen ? slide.min : slide.max;
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: -this.aside.domElement.offsetHeight,
|
||||||
|
max: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,158 +1,81 @@
|
|||||||
import {Component, Template, Inject, Parent, NgElement} from 'angular2/angular2';
|
import {Component, Template, Inject, Parent, NgElement, PropertySetter} from 'angular2/angular2'
|
||||||
import {Ion} from '../ion';
|
import {ComponentConfig} from '../../core/config/config'
|
||||||
import {Config} from '../../core/config/config';
|
import * as types from './extensions/types/types'
|
||||||
import {SlideEdgeGesture} from '../../core/gestures/slide-edge-gesture';
|
import * as gestures from './extensions/gestures/gestures';
|
||||||
import * as util from '../../util';
|
|
||||||
|
|
||||||
// AsideParent is just a temporary directive
|
export let AsideConfig = new ComponentConfig()
|
||||||
@Component({
|
|
||||||
selector: 'ion-aside-parent'
|
AsideConfig.property('side')
|
||||||
})
|
.when('left', gestures.LeftAsideGesture)
|
||||||
@Template({
|
.when('right', gestures.RightAsideGesture)
|
||||||
inline: '<content></content>'
|
.when('top', gestures.TopAsideGesture)
|
||||||
})
|
.when('bottom', gestures.BottomAsideGesture)
|
||||||
export class AsideParent {
|
|
||||||
constructor(@NgElement() element: NgElement) {
|
AsideConfig.property('type')
|
||||||
this.domElement = element.domElement;
|
.when('overlay', types.AsideOverlayType)
|
||||||
super();
|
.when('push', types.AsidePushType)
|
||||||
}
|
.when('reveal', types.AsideRevealType)
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-aside',
|
selector: 'ion-aside',
|
||||||
bind: {
|
bind: {
|
||||||
|
content: 'content',
|
||||||
side: 'side',
|
side: 'side',
|
||||||
dragThreshold: 'dragThreshold'
|
dragThreshold: 'dragThreshold'
|
||||||
}
|
},
|
||||||
|
services: [AsideConfig]
|
||||||
})
|
})
|
||||||
@Template({
|
@Template({
|
||||||
inline: `<content></content>`
|
inline: `<content></content>`
|
||||||
})
|
})
|
||||||
export class Aside {
|
export class Aside {
|
||||||
constructor(
|
constructor(
|
||||||
@Parent() asideParent: AsideParent,
|
@NgElement() element: NgElement,
|
||||||
@NgElement() element: NgElement
|
@PropertySetter('style.transform') transformSetter: Function,
|
||||||
|
@PropertySetter('class.notransition') noTransitionSetter: Function,
|
||||||
|
config: AsideConfig
|
||||||
) {
|
) {
|
||||||
this.domElement = element.domElement;
|
this.domElement = element.domElement
|
||||||
|
this.transformSetter = transformSetter
|
||||||
|
|
||||||
|
// this.noTransitionSetter = noTransitionSetter
|
||||||
|
this.noTransitionSetter = is => { this.domElement.classList[is?'add':'remove']('notransition') }
|
||||||
|
|
||||||
|
this.openSetter = is => { this.domElement.classList[is?'add':'remove']('open') }
|
||||||
|
|
||||||
|
// TODO inject constant instead of using domElement.getAttribute
|
||||||
|
// TODO let config / platform handle defaults transparently
|
||||||
|
let side = this.side = this.domElement.getAttribute('side') || 'left'
|
||||||
|
let type = this.type = this.domElement.getAttribute('type') || 'overlay'
|
||||||
|
this.delegates = config.invoke(this, { side, type })
|
||||||
|
|
||||||
|
this.domElement.classList.add(side)
|
||||||
this.domElement.addEventListener('transitionend', ev => {
|
this.domElement.addEventListener('transitionend', ev => {
|
||||||
this.setChanging(false);
|
this.setChanging(false)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: remove this. setTimeout has to be done so the bindings can be applied
|
setTransform(transform) {
|
||||||
setTimeout(() => {
|
this.delegates.type.setTransform(transform)
|
||||||
let GestureConstructor = {
|
|
||||||
left: LeftAsideSlideGesture,
|
|
||||||
top: TopAsideSlideGesture,
|
|
||||||
bottom: BottomAsideSlideGesture,
|
|
||||||
right: RightAsideSlideGesture
|
|
||||||
}[this.side];
|
|
||||||
this.domElement.classList.add(this.side);
|
|
||||||
this.gesture = new GestureConstructor(this, asideParent.domElement);
|
|
||||||
this.gesture.listen();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
setSliding(isSliding) {
|
setSliding(isSliding) {
|
||||||
if (isSliding !== this.isSliding) {
|
if (isSliding !== this.isSliding) {
|
||||||
this.domElement.classList[isSliding ? 'add' : 'remove']('sliding');
|
this.delegates.type.setSliding(isSliding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setChanging(isChanging) {
|
setChanging(isChanging) {
|
||||||
if (isChanging !== this.isChanging) {
|
if (isChanging !== this.isChanging) {
|
||||||
this.isChanging = isChanging;
|
this.isChanging = isChanging
|
||||||
this.domElement.classList[isChanging ? 'add' : 'remove']('changing');
|
this.domElement.classList[isChanging ? 'add' : 'remove']('changing')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOpen(isOpen) {
|
setOpen(isOpen) {
|
||||||
if (isOpen !== this.isOpen) {
|
if (isOpen !== this.isOpen) {
|
||||||
this.isOpen = isOpen;
|
this.isOpen = isOpen
|
||||||
this.setChanging(true);
|
this.setChanging(true)
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
this.domElement.classList[isOpen ? 'add' : 'remove']('open');
|
this.delegates.type.setOpen(isOpen)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsideSlideGesture extends SlideEdgeGesture {
|
|
||||||
constructor(aside: Aside, slideElement: Element) {
|
|
||||||
this.aside = aside;
|
|
||||||
super(slideElement, {
|
|
||||||
direction: (aside.side === 'left' || aside.side === 'right') ? 'x' : 'y',
|
|
||||||
edge: aside.side || 'left',
|
|
||||||
threshold: /*aside.dragThreshold || */150
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canStart(ev) {
|
|
||||||
// Only restrict edges if the aside is closed
|
|
||||||
return this.aside.isOpen ? true : super.canStart(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSlideBeforeStart(slide, ev) {
|
|
||||||
this.aside.setSliding(true);
|
|
||||||
this.aside.setChanging(true);
|
|
||||||
return new Promise(resolve => {
|
|
||||||
requestAnimationFrame(resolve);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
onSlide(slide, ev) {
|
|
||||||
this.aside.domElement.style.transform = 'translate3d(' + slide.distance + 'px,0,0)';
|
|
||||||
}
|
|
||||||
onSlideEnd(slide, ev) {
|
|
||||||
this.aside.domElement.style.transform = '';
|
|
||||||
this.aside.setSliding(false);
|
|
||||||
if (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5) {
|
|
||||||
this.aside.setOpen(!this.aside.isOpen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getElementStartPos(slide, ev) {
|
|
||||||
return this.aside.isOpen ? slide.max : slide.min;
|
|
||||||
}
|
|
||||||
getSlideBoundaries() {
|
|
||||||
return {
|
|
||||||
min: 0,
|
|
||||||
max: this.aside.domElement.offsetWidth
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LeftAsideSlideGesture extends AsideSlideGesture {}
|
|
||||||
|
|
||||||
class RightAsideSlideGesture extends LeftAsideSlideGesture {
|
|
||||||
getElementStartPos(slide, ev) {
|
|
||||||
return this.aside.isOpen ? slide.min : slide.max;
|
|
||||||
}
|
|
||||||
getSlideBoundaries() {
|
|
||||||
return {
|
|
||||||
min: -this.aside.domElement.offsetWidth,
|
|
||||||
max: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopAsideSlideGesture extends AsideSlideGesture {
|
|
||||||
onSlide(slide, ev) {
|
|
||||||
this.aside.domElement.style.transform = 'translate3d(0,' + slide.distance + 'px,0)';
|
|
||||||
}
|
|
||||||
getSlideBoundaries() {
|
|
||||||
return {
|
|
||||||
min: 0,
|
|
||||||
max: this.aside.domElement.offsetHeight
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BottomAsideSlideGesture extends TopAsideSlideGesture {
|
|
||||||
getElementStartPos(slide, ev) {
|
|
||||||
return this.aside.isOpen ? slide.min : slide.max;
|
|
||||||
}
|
|
||||||
getSlideBoundaries() {
|
|
||||||
return {
|
|
||||||
min: -this.aside.domElement.offsetHeight,
|
|
||||||
max: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
$aside-width: 304px;
|
$aside-width: 304px;
|
||||||
$aside-height: 304px;
|
$aside-height: 304px;
|
||||||
|
$aside-transition: 0.3s linear transform;
|
||||||
|
|
||||||
ion-aside {
|
ion-aside {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
background: rgba(255,0,0,0.5);
|
background: #eee;
|
||||||
border-right: 1px solid black;
|
|
||||||
|
|
||||||
transition: transform 0.3s;
|
&.type-overlay {
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
transition: $aside-transition;
|
||||||
&:not(.open):not(.changing) {
|
&:not(.open):not(.changing) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
&.sliding {
|
|
||||||
transition-duration: 0s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.left {
|
&.left {
|
||||||
width: $aside-width;
|
width: $aside-width;
|
||||||
left: -$aside-width;
|
left: -$aside-width;
|
||||||
@ -23,7 +24,8 @@ ion-aside {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
&.open {
|
&.open,
|
||||||
|
&.type-reveal {
|
||||||
transform: translate3d($aside-width,0,0);
|
transform: translate3d($aside-width,0,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +36,8 @@ ion-aside {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
transform: translate3d(0,0,0);
|
transform: translate3d(0,0,0);
|
||||||
&.open {
|
&.open,
|
||||||
|
&.type-reveal {
|
||||||
transform: translate3d(-$aside-width,0,0);
|
transform: translate3d(-$aside-width,0,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,7 +48,8 @@ ion-aside {
|
|||||||
right: 0;
|
right: 0;
|
||||||
|
|
||||||
transform: translate3d(0,0,0);
|
transform: translate3d(0,0,0);
|
||||||
&.open {
|
&.open,
|
||||||
|
&.type-reveal {
|
||||||
transform: translate3d(0,$aside-width,0);
|
transform: translate3d(0,$aside-width,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,13 +60,25 @@ ion-aside {
|
|||||||
right: 0;
|
right: 0;
|
||||||
|
|
||||||
transform: translate3d(0,0,0);
|
transform: translate3d(0,0,0);
|
||||||
&.open {
|
&.open,
|
||||||
|
&.type-reveal {
|
||||||
transform: translate3d(0,-$aside-width,0);
|
transform: translate3d(0,-$aside-width,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aside-content {
|
||||||
|
transition: $aside-transition;
|
||||||
|
transform: translate3d(0,0,0);
|
||||||
|
&.aside-open-left {
|
||||||
|
transform: translate3d($aside-width,0,0);
|
||||||
|
}
|
||||||
|
&.aside-open-right {
|
||||||
|
transform: translate3d(-$aside-width,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ion-aside-parent {
|
ion-aside-parent {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
88
src/components/aside/extensions/gestures/gestures.js
Normal file
88
src/components/aside/extensions/gestures/gestures.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import {Aside} from '../../aside';
|
||||||
|
import {SlideEdgeGesture} from '../../../../core/gestures/slide-edge-gesture';
|
||||||
|
|
||||||
|
class AsideGesture extends SlideEdgeGesture {
|
||||||
|
constructor(aside: Aside) {
|
||||||
|
this.aside = aside;
|
||||||
|
this.slideElement = aside.domElement.parentNode;
|
||||||
|
super(this.slideElement, {
|
||||||
|
direction: (aside.side === 'left' || aside.side === 'right') ? 'x' : 'y',
|
||||||
|
edge: aside.side,
|
||||||
|
threshold: 75
|
||||||
|
});
|
||||||
|
this.listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
canStart(ev) {
|
||||||
|
// Only restrict edges if the aside is closed
|
||||||
|
return this.aside.isOpen ? true : super.canStart(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSlideBeforeStart(slide, ev) {
|
||||||
|
console.log('beforestart');
|
||||||
|
this.aside.setSliding(true);
|
||||||
|
this.aside.setChanging(true);
|
||||||
|
return new Promise(resolve => {
|
||||||
|
requestAnimationFrame(resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onSlide(slide, ev) {
|
||||||
|
this.aside.setTransform('translate3d(' + slide.distance + 'px,0,0)');
|
||||||
|
}
|
||||||
|
onSlideEnd(slide, ev) {
|
||||||
|
this.aside.setTransform('');
|
||||||
|
this.aside.setSliding(false);
|
||||||
|
if (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5) {
|
||||||
|
this.aside.setOpen(!this.aside.isOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getElementStartPos(slide, ev) {
|
||||||
|
return this.aside.isOpen ? slide.max : slide.min;
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: 0,
|
||||||
|
max: this.aside.domElement.offsetWidth
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LeftAsideGesture extends AsideGesture {}
|
||||||
|
|
||||||
|
export class RightAsideGesture extends LeftAsideGesture {
|
||||||
|
getElementStartPos(slide, ev) {
|
||||||
|
return this.aside.isOpen ? slide.min : slide.max;
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: -this.aside.domElement.offsetWidth,
|
||||||
|
max: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TopAsideGesture extends AsideGesture {
|
||||||
|
onSlide(slide, ev) {
|
||||||
|
this.aside.setTransform('translate3d(0,' + slide.distance + 'px,0)');
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: 0,
|
||||||
|
max: this.aside.domElement.offsetHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BottomAsideGesture extends TopAsideGesture {
|
||||||
|
getElementStartPos(slide, ev) {
|
||||||
|
return this.aside.isOpen ? slide.min : slide.max;
|
||||||
|
}
|
||||||
|
getSlideBoundaries() {
|
||||||
|
return {
|
||||||
|
min: -this.aside.domElement.offsetHeight,
|
||||||
|
max: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
56
src/components/aside/extensions/types/types.js
Normal file
56
src/components/aside/extensions/types/types.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import {Aside} from '../../aside';
|
||||||
|
|
||||||
|
// TODO figure out if we can make all of these bindings (eg content's transform is bound to
|
||||||
|
// aside component's `transform` propety
|
||||||
|
class AsideBaseType {
|
||||||
|
constructor(aside: Aside) {
|
||||||
|
this.aside = aside;
|
||||||
|
|
||||||
|
// TODO make this a setter
|
||||||
|
aside.domElement.classList.add(`type-${aside.type}`);
|
||||||
|
|
||||||
|
//FIXME(ajoslin): have to wait for for bindings to apply in a component
|
||||||
|
setTimeout(() => {
|
||||||
|
this.aside.content.setIsAside(true);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setSliding(isSliding) {
|
||||||
|
this.aside.noTransitionSetter(isSliding);
|
||||||
|
}
|
||||||
|
setOpen(isOpen) {
|
||||||
|
this.aside.openSetter(isOpen);
|
||||||
|
}
|
||||||
|
setTransform(transform) {
|
||||||
|
this.aside.transformSetter(transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AsideOverlayType extends AsideBaseType {}
|
||||||
|
|
||||||
|
export class AsidePushType extends AsideBaseType {
|
||||||
|
setSliding(isSliding) {
|
||||||
|
super.setSliding(isSliding);
|
||||||
|
this.aside.content.noTransitionSetter(isSliding);
|
||||||
|
}
|
||||||
|
setOpen(isOpen) {
|
||||||
|
super.setOpen(isOpen);
|
||||||
|
this.aside.content.asideOpenSetter(isOpen, this.aside.side);
|
||||||
|
}
|
||||||
|
setTransform(transform) {
|
||||||
|
super.setTransform(transform);
|
||||||
|
this.aside.content.transformSetter(transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AsideRevealType extends AsideBaseType {
|
||||||
|
setSliding(isSliding) {
|
||||||
|
this.aside.content.noTransitionSetter(isSliding);
|
||||||
|
}
|
||||||
|
setOpen(isOpen) {
|
||||||
|
super.setOpen(isOpen);
|
||||||
|
this.aside.content.asideOpenSetter(isOpen, this.aside.side);
|
||||||
|
}
|
||||||
|
setTransform(transform) {
|
||||||
|
this.aside.content.transformSetter(transform);
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1 @@
|
|||||||
<aside-app>
|
<aside-app style="position:absolute; left:0;top:0;right:0;bottom:0;"></aside-app>
|
||||||
</aside-app>
|
|
||||||
|
21
src/components/aside/test/basic/main.html
Normal file
21
src/components/aside/test/basic/main.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<ion-view>
|
||||||
|
<ion-aside side="left" [content]="content" type="overlay" style="text-align:center;">
|
||||||
|
Overlay!
|
||||||
|
<p>...</p>
|
||||||
|
<p>...</p>
|
||||||
|
<p>...</p>
|
||||||
|
This is android-ey.
|
||||||
|
</ion-aside>
|
||||||
|
|
||||||
|
<ion-content #content>
|
||||||
|
HELLO, content!
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
|
<ion-aside side="right" [content]="content" type="reveal" style="text-align:center;">
|
||||||
|
Reveal!
|
||||||
|
<p>...</p>
|
||||||
|
<p>...</p>
|
||||||
|
<p>...</p>
|
||||||
|
This is iOS-ey.
|
||||||
|
</ion-aside>
|
||||||
|
</ion-view>
|
@ -1,50 +1,16 @@
|
|||||||
import {ionicComponents} from 'ionic2/components';
|
import {Aside} from 'ionic2/components/aside/aside';
|
||||||
|
import {Content} from 'ionic2/components/content/content';
|
||||||
|
import {View} from 'ionic2/components/view/view';
|
||||||
import {Template, Component, bootstrap} from 'angular2/angular2';
|
import {Template, Component, bootstrap} from 'angular2/angular2';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'aside-app'
|
selector: 'aside-app'
|
||||||
})
|
})
|
||||||
@Template({
|
@Template({
|
||||||
directives: ionicComponents,
|
directives: [Aside, Content, View],
|
||||||
inline: `<ion-aside-parent>
|
url: 'main.html'
|
||||||
<ion-aside side="left">
|
|
||||||
LEFT
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
Side menu!
|
|
||||||
</ion-aside>
|
|
||||||
<ion-aside side="right">
|
|
||||||
RIGHT
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
Side menu!
|
|
||||||
</ion-aside>
|
|
||||||
<ion-aside side="top">
|
|
||||||
TOP
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
Side menu!
|
|
||||||
</ion-aside>
|
|
||||||
<ion-aside side="bottom">
|
|
||||||
BOTTOM
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
<p>...</p>
|
|
||||||
Side menu!
|
|
||||||
</ion-aside>
|
|
||||||
</ion-aside-parent>
|
|
||||||
<div class="content">
|
|
||||||
<button class="button" (click)="openLeft()">
|
|
||||||
Open Left Menu
|
|
||||||
</button>
|
|
||||||
</div>`
|
|
||||||
})
|
})
|
||||||
class AsideApp {
|
class AsideApp {
|
||||||
openLeft() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap(AsideApp);
|
bootstrap(AsideApp);
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import {NgElement, Component, Template} from 'angular2/angular2';
|
import {NgElement, Component, Template, PropertySetter} from 'angular2/angular2';
|
||||||
import {Ion} from '../ion';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-content'
|
selector: 'ion-content'
|
||||||
@ -11,8 +9,23 @@ import {Ion} from '../ion';
|
|||||||
<content></content>
|
<content></content>
|
||||||
</div>`
|
</div>`
|
||||||
})
|
})
|
||||||
export class Content extends Ion {
|
export class Content {
|
||||||
constructor(@NgElement() ele:NgElement) {
|
constructor(
|
||||||
ele.domElement.classList.add('content');
|
@NgElement() ele:NgElement,
|
||||||
|
@PropertySetter('style.transform') transformSetter: Function,
|
||||||
|
@PropertySetter('class.notransition') noTransitionSetter: Function
|
||||||
|
) {
|
||||||
|
this.domElement = ele.domElement;
|
||||||
|
this.domElement.classList.add('content');
|
||||||
|
|
||||||
|
this.noTransitionSetter = is => { this.domElement.classList[is?'add':'remove']('notransition'); }
|
||||||
|
// this.noTransitionSetter = noTransitionSetter;
|
||||||
|
|
||||||
|
this.transformSetter = transformSetter;
|
||||||
|
this.setIsAside = is => { this.domElement.classList.add('aside-content'); };
|
||||||
|
|
||||||
|
this.asideOpenSetter = (is, side) => {
|
||||||
|
this.domElement.classList[is?'add':'remove'](`aside-open-${side}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
src/components/content/content.scss
Normal file
5
src/components/content/content.scss
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
background-color: white;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import {NgElement, Component, Template} from 'angular2/angular2'
|
import {NgElement, Component, Template} from 'angular2/angular2'
|
||||||
import {Ion} from '../ion'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-toolbar',
|
selector: 'ion-toolbar',
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import {NgElement, Component, Template} from 'angular2/angular2'
|
import {NgElement, Component, Template} from 'angular2/angular2'
|
||||||
import {Toolbar} from '../toolbar/toolbar'
|
import {Toolbar} from '../toolbar/toolbar'
|
||||||
import {Ion} from '../ion'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-view',
|
selector: 'ion-view',
|
||||||
|
3
src/components/view/view.scss
Normal file
3
src/components/view/view.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.pane-container {
|
||||||
|
flex: 1;
|
||||||
|
}
|
@ -1,7 +1,47 @@
|
|||||||
import {platform} from '../platform/platform';
|
import {platform} from '../platform/platform';
|
||||||
import {ConfigCase} from './config-case';
|
// import {ConfigCase} from './config-case';
|
||||||
import * as util from '../../util';
|
import * as util from '../../util';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
let MyConfig = new ComponentConfig();
|
||||||
|
MyConfig.property('side')
|
||||||
|
.when('left', LeftSlideGesture)
|
||||||
|
.when('right', RightSlideGesture)
|
||||||
|
.when('top', TopSlideGesture)
|
||||||
|
.when('bottom', BottomSlideGesture)
|
||||||
|
*/
|
||||||
|
export function ComponentConfig() {
|
||||||
|
return class Config {
|
||||||
|
static property(propertyName) {
|
||||||
|
let self;
|
||||||
|
return (self = {
|
||||||
|
when(propertyValue, Class) {
|
||||||
|
Config.addCase(propertyName, propertyValue, Class);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static addCase(property, value, Class) {
|
||||||
|
Config.registry || (Config.registry = {});
|
||||||
|
(Config.registry[property] || (Config.registry[property] = {}))[value] = Class;
|
||||||
|
}
|
||||||
|
invoke(instance, properties = {}) {
|
||||||
|
let delegates = {};
|
||||||
|
for (let property in properties) {
|
||||||
|
let value = properties[property];
|
||||||
|
let propertyRegistry = Config.registry && Config.registry[property] || {};
|
||||||
|
if (propertyRegistry[value]) {
|
||||||
|
delegates[property] = new propertyRegistry[value](instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return delegates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO stop hardcoding platforms and media sizes
|
// TODO stop hardcoding platforms and media sizes
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -23,86 +63,86 @@ class AsideReveal {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class Config extends ConfigCase {
|
// export class Config extends ConfigCase {
|
||||||
constructor() {
|
// constructor() {
|
||||||
this._root = this;
|
// this._root = this;
|
||||||
this._cases = {};
|
// this._cases = {};
|
||||||
super({
|
// super({
|
||||||
root: this,
|
// root: this,
|
||||||
parent: null,
|
// parent: null,
|
||||||
path: ''
|
// path: ''
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
invoke(instance) {
|
// invoke(instance) {
|
||||||
return invokeConfig(this, instance);
|
// return invokeConfig(this, instance);
|
||||||
}
|
// }
|
||||||
_addCase(key, baseCase) {
|
// _addCase(key, baseCase) {
|
||||||
let path = baseCase._path.slice();
|
// let path = baseCase._path.slice();
|
||||||
path.push(key);
|
// path.push(key);
|
||||||
|
|
||||||
// Remove empties & duplicates
|
// // Remove empties & duplicates
|
||||||
path = path
|
// path = path
|
||||||
.filter((value, index) => {
|
// .filter((value, index) => {
|
||||||
return value && path.indexOf(value) === index;
|
// return value && path.indexOf(value) === index;
|
||||||
})
|
// })
|
||||||
.sort();
|
// .sort();
|
||||||
|
|
||||||
if (path.join(' ') === baseCase._path.join(' ')) {
|
// if (path.join(' ') === baseCase._path.join(' ')) {
|
||||||
return baseCase;
|
// return baseCase;
|
||||||
}
|
// }
|
||||||
return this._createCase(path);
|
// return this._createCase(path);
|
||||||
}
|
// }
|
||||||
_createCase(path) {
|
// _createCase(path) {
|
||||||
if (!path.length) return this;
|
// if (!path.length) return this;
|
||||||
let pathStr = path.join(' ');
|
// let pathStr = path.join(' ');
|
||||||
let configCase = this._cases[pathStr];
|
// let configCase = this._cases[pathStr];
|
||||||
if (!configCase) {
|
// if (!configCase) {
|
||||||
let parentPath = path.slice(0, path.length - 1);
|
// let parentPath = path.slice(0, path.length - 1);
|
||||||
configCase = this._cases[pathStr] = new ConfigCase({
|
// configCase = this._cases[pathStr] = new ConfigCase({
|
||||||
root: this,
|
// root: this,
|
||||||
parent: this._createCase(parentPath),
|
// parent: this._createCase(parentPath),
|
||||||
path: path
|
// path: path
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
return configCase;
|
// return configCase;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function invokeConfig(config, object) {
|
// export function invokeConfig(config, object) {
|
||||||
let platformName = platform.get().name;
|
// let platformName = platform.get().name;
|
||||||
|
|
||||||
let passedCases = [config].concat(
|
// let passedCases = [config].concat(
|
||||||
Object.keys(config._cases)
|
// Object.keys(config._cases)
|
||||||
.map(name => config._cases[name])
|
// .map(name => config._cases[name])
|
||||||
.filter(configCasePasses)
|
// .filter(configCasePasses)
|
||||||
.sort(function(a,b) {
|
// .sort(function(a,b) {
|
||||||
return a._path.length < b._path.length ? -1 : 1;
|
// return a._path.length < b._path.length ? -1 : 1;
|
||||||
})
|
// })
|
||||||
);
|
// );
|
||||||
|
|
||||||
// Extend the given object with the values of all the passed cases, starting with the
|
// // Extend the given object with the values of all the passed cases, starting with the
|
||||||
// most specific.
|
// // most specific.
|
||||||
let defaults = [object];
|
// let defaults = [object];
|
||||||
// Also find the most specific case with a component that we should use.
|
// // Also find the most specific case with a component that we should use.
|
||||||
let ComponentToUse;
|
// let ComponentToUse;
|
||||||
for (let i = 0, ii = passedCases.length; i < ii; i++) {
|
// for (let i = 0, ii = passedCases.length; i < ii; i++) {
|
||||||
defaults.push(passedCases[i]._values);
|
// defaults.push(passedCases[i]._values);
|
||||||
if (passedCases[i]._component) {
|
// if (passedCases[i]._component) {
|
||||||
ComponentToUse = passedCases[i]._component;
|
// ComponentToUse = passedCases[i]._component;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
util.defaults.apply(null, defaults);
|
// util.defaults.apply(null, defaults);
|
||||||
|
|
||||||
return ComponentToUse;
|
// return ComponentToUse;
|
||||||
|
|
||||||
function configCasePasses(configCase) {
|
// function configCasePasses(configCase) {
|
||||||
let path = configCase._path;
|
// let path = configCase._path;
|
||||||
let key;
|
// let key;
|
||||||
for (let i = 0, ii = path.length; i < ii; i++) {
|
// for (let i = 0, ii = path.length; i < ii; i++) {
|
||||||
if (platformName !== path[i]) return false;
|
// if (platformName !== path[i]) return false;
|
||||||
}
|
// }
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
Reference in New Issue
Block a user