feat(): Added badge, card, gesture, slides, toggle

This commit is contained in:
Josh Thomas
2017-05-11 13:09:52 -05:00
parent 39e12b1c2e
commit ef0d9a89b6
20 changed files with 300 additions and 139 deletions

View File

@ -16,11 +16,9 @@ $badge-ios-text-color: color-contrast($colors-ios, $badge-ios-background
.badge-ios {
@include host-context() {
border-radius: $badge-ios-border-radius;
color: $badge-ios-text-color;
background-color: $badge-ios-background-color;
}
}
@ -30,10 +28,8 @@ $badge-ios-text-color: color-contrast($colors-ios, $badge-ios-background
@each $color-name, $color-base, $color-contrast in get-colors($colors-ios) {
.badge-ios-#{$color-name} {
@include host-context() {
color: $color-contrast;
background-color: $color-base;
}
}
}

View File

@ -16,20 +16,9 @@ $badge-md-text-color: color-contrast($colors-md, $badge-md-backgro
.badge-md {
@include host-context() {
border-radius: $badge-md-border-radius;
color: $badge-md-text-color;
background-color: $badge-md-background-color;
}
}
.badge-md {
@include host-context() {
border-radius: $badge-md-border-radius;
color: $badge-md-text-color;
background-color: $badge-md-background-color;
}
}
@ -39,10 +28,8 @@ $badge-md-text-color: color-contrast($colors-md, $badge-md-backgro
@each $color-name, $color-base, $color-contrast in get-colors($colors-md) {
.badge-md-#{$color-name} {
@include host-context() {
color: $color-contrast;
background-color: $color-base;
}
}
}

View File

@ -12,15 +12,12 @@ $badge-font-weight: bold !default;
ion-badge {
@include host() {
display: inline-block;
visibility: inherit !important;
contain: content;
}
}
.badge {
@include host() {
padding: 3px 8px;
min-width: 10px;
@ -32,11 +29,8 @@ ion-badge {
text-align: center;
white-space: nowrap;
vertical-align: baseline;
}
}
ion-badge:empty {
@include host(':empty') {
display: none;
}
}

View File

@ -7,12 +7,11 @@ import { Component, h, Ionic } from '../index';
ios: 'badge.ios.scss',
md: 'badge.md.scss',
wp: 'badge.wp.scss'
}
},
shadow: false
})
export class Badge {
render() {
return h(this, Ionic.theme(this, 'badge'),
h('slot')
);
return h(this, Ionic.theme(this, 'badge'));
}
}

View File

@ -16,11 +16,9 @@ $badge-wp-text-color: color-contrast($colors-wp, $badge-wp-backgro
.badge-wp {
@include host-context() {
border-radius: $badge-wp-border-radius;
color: $badge-wp-text-color;
background-color: $badge-wp-background-color;
}
}
@ -30,10 +28,8 @@ $badge-wp-text-color: color-contrast($colors-wp, $badge-wp-backgro
@each $color-name, $color-base, $color-contrast in get-colors($colors-wp) {
.badge-wp-#{$color-name} {
@include host-context() {
color: $color-contrast;
background-color: $color-base;
}
}
}

View File

@ -4,8 +4,7 @@
// Card Content
// --------------------------------------------------
ion-card-content,
:host {
ion-card-content {
display: block;
visibility: inherit !important;
}

View File

@ -7,12 +7,11 @@ import { Component, h, Ionic } from '../index';
ios: 'card-content.ios.scss',
md: 'card-content.md.scss',
wp: 'card-content.wp.scss'
}
},
shadow: false
})
export class CardContent {
render() {
return h(this, Ionic.theme(this, 'card-content'),
h('slot')
);
return h(this, Ionic.theme(this, 'card-content'));
}
}

View File

@ -5,8 +5,7 @@
// --------------------------------------------------
ion-card-header,
:host {
ion-card-header {
display: block;
overflow: hidden;
visibility: inherit !important;

View File

@ -7,12 +7,11 @@ import { Component, h, Ionic } from '../index';
ios: 'card-header.ios.scss',
md: 'card-header.md.scss',
wp: 'card-header.wp.scss'
}
},
shadow: false
})
export class CardHeader {
render() {
return h(this, Ionic.theme(this, 'card-header'),
h('slot')
);
return h(this, Ionic.theme(this, 'card-header'));
}
}

View File

@ -4,8 +4,7 @@
// Card Title
// --------------------------------------------------
ion-card-title,
:host {
ion-card-title {
display: block;
visibility: inherit !important;
}

View File

@ -7,12 +7,11 @@ import { Component, h, Ionic } from '../index';
ios: 'card-title.ios.scss',
md: 'card-title.md.scss',
wp: 'card-title.wp.scss'
}
},
shadow: false
})
export class CardTitle {
render() {
return h(this, Ionic.theme(this, 'card-title'),
h('slot')
);
return h(this, Ionic.theme(this, 'card-title'));
}
}

View File

@ -4,8 +4,7 @@
// --------------------------------------------------
ion-card,
:host {
ion-card {
display: block;
overflow: hidden;
visibility: inherit !important;

View File

@ -7,12 +7,11 @@ import { Component, h, Ionic } from '../index';
ios: 'card.ios.scss',
md: 'card.md.scss',
wp: 'card.wp.scss'
}
},
shadow: false
})
export class Card {
render() {
return h(this, Ionic.theme(this, 'card'),
h('slot')
);
return h(this, Ionic.theme(this, 'card'));
}
}

View File

@ -1,5 +1,5 @@
import { applyStyles, getElementReference, pointerCoordX, pointerCoordY } from '../../util/helpers';
import { Component, Listen, Ionic, Prop } from '../index';
import { Component, Ionic, Listen, Prop } from '../index';
import { GestureCallback, GestureDetail } from '../../util/interfaces';
import { GestureController, GestureDelegate } from './gesture-controller';
import { PanRecognizer } from './recognizers';
@ -25,7 +25,7 @@ export class Gesture {
@Prop() direction: string = 'x';
@Prop() gestureName: string = '';
@Prop() gesturePriority: number = 0;
@Prop() listenOn: string = 'child';
@Prop() attachTo: string = 'child';
@Prop() maxAngle: number = 40;
@Prop() threshold: number = 20;
@Prop() type: string = 'pan';
@ -52,11 +52,11 @@ export class Gesture {
this.hasPress = (types.indexOf('press') > -1);
if (this.pan || this.hasPress) {
Ionic.listener.enable(this, 'touchstart', true, this.listenOn);
Ionic.listener.enable(this, 'mousedown', true, this.listenOn);
Ionic.listener.enable(this, 'touchstart', true, this.attachTo);
Ionic.listener.enable(this, 'mousedown', true, this.attachTo);
Ionic.dom.write(() => {
applyStyles(getElementReference(this.$el, this.listenOn), GESTURE_INLINE_STYLES);
applyStyles(getElementReference(this.$el, this.attachTo), GESTURE_INLINE_STYLES);
});
}
}

View File

@ -10,6 +10,8 @@ export declare const Ionic: interfaces.Ionic;
export declare const Listen: interfaces.ListenDecorator;
export declare const Method: interfaces.MethodDecorator;
export declare const Prop: interfaces.PropDecorator;
export declare const Watch: interfaces.WatchDecorator;

View File

@ -529,7 +529,7 @@ export class Slides {
/**
* @hidden
*/
ngOnDestroy() {
ionViewWillUnload() {
this._init = false;
this.swiper.destroy(true, true);

View File

@ -1,5 +1,5 @@
import { BooleanInputComponent, GestureDetail } from '../../util/interfaces';
import { Component, h, Ionic, Listen, Prop, Watch } from '../index';
import { Component, h, Ionic, Listen, Method, Prop, Watch } from '../index';
@Component({
@ -28,18 +28,18 @@ export class Toggle implements BooleanInputComponent {
}
canStart() {
private canStart() {
return !this.disabled;
}
onDragStart(detail: GestureDetail) {
private onDragStart(detail: GestureDetail) {
this.startX = detail.startX;
this.fireFocus();
}
onDragMove(detail: GestureDetail) {
private onDragMove(detail: GestureDetail) {
if (this.checked) {
if (detail.currentX + 15 < this.startX) {
this.checked = false;
@ -55,7 +55,7 @@ export class Toggle implements BooleanInputComponent {
}
onDragEnd(detail: GestureDetail) {
private onDragEnd(detail: GestureDetail) {
if (this.checked) {
if (detail.startX + 4 > detail.currentX) {
this.checked = false;
@ -78,12 +78,13 @@ export class Toggle implements BooleanInputComponent {
ev.preventDefault();
}
@Method()
toggle() {
if (!this.disabled) {
this.checked = !this.checked;
this.fireFocus();
}
return this.checked;
}
@ -122,7 +123,7 @@ export class Toggle implements BooleanInputComponent {
'type': 'pan,press',
'direction': 'x',
'threshold': 20,
'listenOn': 'parent'
'attachTo': 'parent'
}
}),
[

View File

@ -160,7 +160,6 @@
// Based on a selector, apply the content to that selector and the :host
@mixin host($selector: null) {
@debug $selector;
@at-root {
@if ($selector) {
:host(#{$selector}),

View File

@ -108,3 +108,20 @@ export function applyStyles(elm: HTMLElement, styles: {[styleProp: string]: stri
(<any>elm.style)[styleProps[i]] = styles[styleProps[i]];
}
}
export function asyncFn(queue: Function[], cb: Function) {
if (queue === null) {
cb();
} else {
queue.push(cb);
}
}
export function drainAsyncFns(queue: Function[]): any {
if (queue) {
for (var i = 0; i < queue.length; i++) {
queue[i]();
}
}
return null;
}

View File

@ -3,6 +3,7 @@ export interface Ionic {
emit: EventEmit;
listener: {
enable: EventListenerEnable;
add: AddEventListenerApi;
};
theme: IonicTheme;
controllers: {
@ -10,6 +11,69 @@ export interface Ionic {
};
dom: DomControllerApi;
config: ConfigApi;
modal: ModalControllerApi;
Animation: Animation;
}
export interface IonicGlobal {
staticDir?: string;
components?: LoadComponents;
loadComponents?: (coreVersion: number, bundleId: string, modulesImporterFn: ModulesImporterFn, cmp0?: ComponentModeData, cmp1?: ComponentModeData, cmp2?: ComponentModeData) => void;
eventNameFn?: (eventName: string) => string;
config?: Object;
ConfigCtrl?: ConfigApi;
DomCtrl?: DomControllerApi;
NextTickCtrl?: NextTickApi;
Animation: any;
}
export interface ModalControllerApi {
create: (component: string, params?: any, opts?: ModalOptions) => Promise<Modal>;
}
export interface ModalControllerInternalApi extends ModalControllerApi {
_create?: any[];
}
export interface Modal {
component: string;
id: string;
style?: {
zIndex: number;
};
showBackdrop: boolean;
enableBackdropDismiss: boolean;
enterAnimation: AnimationBuilder;
exitAnimation: AnimationBuilder;
cssClass: string;
params: any;
present: (done?: Function) => void;
dismiss: (done?: Function) => void;
}
export interface ModalOptions {
showBackdrop?: boolean;
enableBackdropDismiss?: boolean;
enterAnimation?: AnimationBuilder;
exitAnimation?: AnimationBuilder;
cssClass?: string;
}
export interface ModalEvent extends Event {
detail: {
modal: Modal;
};
}
export interface AddEventListenerApi {
(elm: HTMLElement|HTMLDocument|Window, eventName: string, cb: (ev?: any) => void, opts?: ListenOptions): Function;
}
@ -27,7 +91,7 @@ export interface CustomEventOptions {
export interface EventListenerEnable {
(instance: any, eventName: string, enabled: boolean, listenOn?: string): void;
(instance: any, eventName: string, enabled: boolean, attachTo?: string): void;
}
@ -100,18 +164,6 @@ export interface ContentDimensions {
}
export interface IonicGlobal {
staticDir?: string;
components?: LoadComponents;
loadComponents?: {(bundleId: string, modulesImporterFn: ModulesImporterFn, cmp0?: ComponentModeData, cmp1?: ComponentModeData, cmp2?: ComponentModeData): void};
eventNameFn?: {(eventName: string): string};
config?: Object;
ConfigCtrl?: ConfigApi;
DomCtrl?: DomControllerApi;
NextTickCtrl?: NextTickApi;
}
export interface NextTickApi {
nextTick: NextTick;
}
@ -150,9 +202,9 @@ export interface ComponentModeData {
[0]: string;
/**
* component class name (Badge)
* methods
*/
[1]: string;
[1]: Methods;
/**
* listeners
@ -245,22 +297,29 @@ export interface PropOptions {
}
export interface Props {
[propName: string]: PropOptions;
export interface PropMeta {
propName?: string;
propType?: any;
}
export type Methods = string[];
export interface MethodDecorator {
(opts?: MethodOptions): any;
}
export interface MethodOptions {}
export interface ListenDecorator {
(eventName: string, opts?: ListenOpts): any;
(eventName: string, opts?: ListenOptions): any;
}
export interface ComponentMetaListeners {
[methodName: string]: ListenOpts;
}
export interface ListenOpts {
export interface ListenOptions {
eventName?: string;
capture?: boolean;
passive?: boolean;
@ -268,6 +327,11 @@ export interface ListenOpts {
}
export interface ListenMeta extends ListenOptions {
methodName?: string;
}
export interface WatchDecorator {
(propName: string): any;
}
@ -278,8 +342,8 @@ export interface WatchOpts {
}
export interface Watchers {
[propName: string]: WatchOpts;
export interface WatchMeta extends WatchOpts {
propName?: string;
}
@ -297,18 +361,21 @@ export interface ConfigApi {
export interface ComponentMeta {
tag?: string;
props?: Props;
listeners?: ComponentMetaListeners;
watchers?: Watchers;
methods?: Methods;
props?: PropMeta[];
listeners?: ListenMeta[];
watchers?: WatchMeta[];
modes: ModeMeta[];
shadow?: boolean;
namedSlots?: string[];
obsAttrs?: string[];
componentModule?: any;
modes: {[modeName: string]: ComponentMode};
priority?: 'high'|'low';
}
export interface ComponentMode {
export interface ModeMeta {
modeName?: string;
bundleId?: string;
styles?: string;
styleUrls?: string[];
@ -317,10 +384,10 @@ export interface ComponentMode {
export interface Component {
ionViewDidLoad?: {(): void};
ionViewWillUnload?: {(): void};
ionViewDidLoad?: () => void;
ionViewWillUnload?: () => void;
render?: {(): VNode};
render?: () => VNode;
mode?: string;
color?: string;
@ -328,8 +395,10 @@ export interface Component {
$el?: ProxyElement;
$meta?: ComponentMeta;
$listeners?: ComponentActiveListeners;
$watchers?: ComponentActiveWatchers;
$root?: HTMLElement | ShadowRoot;
$vnode?: VNode;
$values?: ComponentActiveValues;
[memberName: string]: any;
}
@ -340,19 +409,27 @@ export interface ComponentActiveListeners {
}
export type ComponentActiveWatchers = Function[];
export interface ComponentActiveValues {
[propName: string]: any;
}
export interface BaseInputComponent extends Component {
disabled: boolean;
hasFocus: boolean;
value: string;
fireFocus: {(): void};
fireBlur: {(): void};
fireFocus: () => void;
fireBlur: () => void;
}
export interface BooleanInputComponent extends BaseInputComponent {
checked: boolean;
toggle: {(ev: UIEvent): void};
toggle: (ev: UIEvent) => void;
}
@ -367,22 +444,28 @@ export interface ComponentRegistry {
export interface ProxyElement extends HTMLElement {
connectedCallback: {(): void};
attributeChangedCallback: {(attrName: string, oldVal: string, newVal: string, namespace: string): void};
disconnectedCallback: {(): void};
connectedCallback: () => void;
attributeChangedCallback: (attrName: string, oldVal: string, newVal: string, namespace: string) => void;
disconnectedCallback: () => void;
$queueUpdate: () => void;
$queued?: boolean;
$instance?: Component;
$hostContent?: HostContentNodes;
$tmpDisconnected?: boolean;
[memberName: string]: any;
}
export type QueueHandlerId = number;
export type Side = 'left' | 'right' | 'start' | 'end';
export interface RendererApi {
(oldVnode: VNode | Element, vnode: VNode, manualSlotProjection?: boolean): VNode;
(oldVnode: VNode | Element, vnode: VNode, hostContentNodes?: HostContentNodes): VNode;
}
@ -411,6 +494,12 @@ export interface VNode {
}
export interface HostContentNodes {
$defaultSlot: Node[];
$namedSlots?: {[slotName: string]: Node[]};
}
export interface VNodeData {
props?: any;
attrs?: any;
@ -418,7 +507,7 @@ export interface VNodeData {
style?: any;
dataset?: any;
on?: any;
attachData?: any;
ref?: (elm: any) => void;
vkey?: Key;
vns?: string; // for SVGs
[key: string]: any; // for any other 3rd party module
@ -428,7 +517,7 @@ export interface VNodeData {
export interface PlatformApi {
registerComponent: (tag: string, data: any[]) => ComponentMeta;
getComponentMeta: (tag: string) => ComponentMeta;
loadComponent: (bundleId: string, priority: string, cb: Function) => void;
loadBundle: (bundleId: string, priority: string, cb: Function) => void;
nextTick: NextTick;
isElement: (node: Node) => node is Element;
@ -463,3 +552,92 @@ export interface ServerInitConfig {
staticDir: string;
config?: Object;
}
export interface Animation {
new(elm?: Node|Node[]|NodeList): Animation;
addChildAnimation: (childAnimation: Animation) => Animation;
addElement: (elm: Node|Node[]|NodeList) => Animation;
afterAddClass: (className: string) => Animation;
afterClearStyles: (propertyNames: string[]) => Animation;
afterRemoveClass: (className: string) => Animation;
afterStyles: (styles: { [property: string]: any; }) => Animation;
beforeAddClass: (className: string) => Animation;
beforeClearStyles: (propertyNames: string[]) => Animation;
beforeRemoveClass: (className: string) => Animation;
beforeStyles: (styles: { [property: string]: any; }) => Animation;
destroy: () => void;
duration: (milliseconds: number) => Animation;
easing: (name: string) => Animation;
from: (prop: string, val: any) => Animation;
fromTo: (prop: string, fromVal: any, toVal: any, clearProperyAfterTransition?: boolean) => Animation;
hasCompleted: boolean;
isPlaying: boolean;
onFinish: (callback: (animation?: Animation) => void, opts?: {oneTimeCallback: boolean, clearExistingCallacks: boolean}) => Animation;
play: (opts?: PlayOptions) => void;
progressEnd: (shouldComplete: boolean, currentStepValue: number, dur: number) => void;
progressStep: (stepValue: number) => void;
progressStart: () => void;
reverse: (shouldReverse?: boolean) => Animation;
stop: (stepValue?: number) => void;
to: (prop: string, val: any, clearProperyAfterTransition?: boolean) => Animation;
}
export interface AnimationBuilder {
(elm?: HTMLElement): Animation;
}
export interface AnimationOptions {
animation?: string;
duration?: number;
easing?: string;
direction?: string;
isRTL?: boolean;
ev?: any;
}
export interface PlayOptions {
duration?: number;
promise?: boolean;
}
export interface EffectProperty {
effectName: string;
trans: boolean;
wc?: string;
to?: EffectState;
from?: EffectState;
[state: string]: any;
}
export interface EffectState {
val: any;
num: number;
effectUnit: string;
}
export interface RequestIdleCallback {
(callback: IdleCallback): number;
}
export interface IdleCallback {
(deadline: IdleDeadline, options?: IdleOptions): void;
}
export interface IdleDeadline {
didTimeout: boolean;
timeRemaining: () => number;
}
export interface IdleOptions {
timeout?: number;
}