From 4ea8881f335bdbb23ce00da3aff4cebe666c3760 Mon Sep 17 00:00:00 2001 From: "Manu Mtz.-Almeida" Date: Thu, 19 Apr 2018 18:48:38 +0200 Subject: [PATCH] refactor(all): enable strictPropertyInitialization --- angular/src/directives/proxies.ts | 162 ++++++------ .../components/app-preview/app-preview.tsx | 2 +- .../src/components/css-text/css-text.tsx | 2 +- .../demo-selection/demo-selection.tsx | 4 +- .../theme-selector/theme-selector.tsx | 8 +- .../variable-selector/variable-selector.tsx | 6 +- core/src/components.d.ts | 230 +++++++++-------- .../action-sheet-controller.tsx | 2 +- .../components/action-sheet/action-sheet.tsx | 42 +-- .../alert-controller/alert-controller.tsx | 2 +- core/src/components/alert/alert.tsx | 242 +++++++++--------- core/src/components/alert/readme.md | 10 - core/src/components/anchor/anchor.tsx | 6 +- .../animation-controller/animator.tsx | 36 +-- core/src/components/app/app.tsx | 10 +- .../components/back-button/back-button.tsx | 18 +- core/src/components/backdrop/backdrop.tsx | 4 +- core/src/components/badge/badge.tsx | 5 +- core/src/components/button/button.tsx | 33 ++- .../components/card-content/card-content.tsx | 5 +- .../components/card-header/card-header.tsx | 5 +- .../card-subtitle/card-subtitle.tsx | 5 +- core/src/components/card-title/card-title.tsx | 5 +- core/src/components/card/card.tsx | 5 +- core/src/components/checkbox/checkbox.tsx | 59 ++--- .../components/chip-button/chip-button.tsx | 14 +- core/src/components/chip/chip.tsx | 5 +- core/src/components/content/content.tsx | 17 +- core/src/components/datetime/datetime.tsx | 82 +++--- core/src/components/fab-button/fab-button.tsx | 10 +- core/src/components/fab-list/fab-list.tsx | 2 +- core/src/components/fab/fab.tsx | 6 +- core/src/components/footer/footer.tsx | 5 +- .../gesture-controller/gesture-controller.tsx | 2 +- core/src/components/gesture/gesture.tsx | 41 +-- core/src/components/gesture/recognizers.ts | 5 +- core/src/components/header/header.tsx | 5 +- core/src/components/hide-when/hide-when.tsx | 20 +- core/src/components/hide-when/readme.md | 10 - .../infinite-scroll-content.tsx | 6 +- .../infinite-scroll/infinite-scroll.tsx | 8 +- .../components/input-shims/input-shims.tsx | 4 +- core/src/components/input/input-base.tsx | 58 ++--- core/src/components/input/input.tsx | 94 ++++--- .../components/item-divider/item-divider.tsx | 7 +- .../components/item-option/item-option.tsx | 7 +- .../components/item-options/item-options.tsx | 6 +- .../components/item-sliding/item-sliding.tsx | 8 +- core/src/components/item/item.tsx | 16 +- core/src/components/label/label.tsx | 10 +- .../components/list-header/list-header.tsx | 5 +- core/src/components/list/list.tsx | 7 +- .../loading-controller/loading-controller.tsx | 2 +- core/src/components/loading/loading.tsx | 42 +-- .../components/menu-button/menu-button.tsx | 6 +- .../menu-controller/menu-controller.ts | 2 +- .../components/menu-toggle/menu-toggle.tsx | 4 +- core/src/components/menu/menu.tsx | 37 +-- .../modal-controller/modal-controller.tsx | 2 +- core/src/components/modal/modal.tsx | 40 +-- core/src/components/nav-pop/nav-pop.tsx | 2 +- core/src/components/nav-push/nav-push.tsx | 10 +- core/src/components/nav-push/readme.md | 10 - .../components/nav-set-root/nav-set-root.tsx | 11 +- core/src/components/nav-set-root/readme.md | 10 - core/src/components/nav/nav.tsx | 47 ++-- .../nav/test/nav-controller.spec.ts | 4 +- core/src/components/nav/view-controller.ts | 2 +- core/src/components/note/note.tsx | 5 +- .../picker-column/picker-column.tsx | 32 +-- .../picker-controller/picker-controller.tsx | 2 +- core/src/components/picker/picker.tsx | 40 +-- .../popover-controller/popover-controller.tsx | 2 +- core/src/components/popover/popover.tsx | 42 +-- .../components/radio-group/radio-group.tsx | 145 ++++------- core/src/components/radio/radio.tsx | 70 +++-- core/src/components/range-knob/range-knob.tsx | 22 +- core/src/components/range/range.tsx | 170 ++++++------ core/src/components/range/readme.md | 18 ++ .../refresher-content/refresher-content.tsx | 10 +- core/src/components/refresher/refresher.tsx | 10 +- .../reorder-group/reorder-group.tsx | 20 +- core/src/components/reorder/reorder.tsx | 2 +- .../ripple-effect/ripple-effect.tsx | 8 +- .../route-redirect/route-redirect.tsx | 2 +- core/src/components/route/route.tsx | 6 +- .../components/router-outlet/route-outlet.tsx | 25 +- core/src/components/router/router.tsx | 14 +- core/src/components/scroll/scroll.tsx | 20 +- core/src/components/searchbar/searchbar.tsx | 21 +- .../segment-button/segment-button.tsx | 15 +- core/src/components/segment/segment.tsx | 40 ++- .../select-option/select-option.tsx | 21 +- .../select-popover/select-popover.tsx | 9 +- core/src/components/select/select.tsx | 49 ++-- core/src/components/show-when/readme.md | 10 - core/src/components/show-when/show-when.tsx | 21 +- core/src/components/slides/slides.tsx | 53 ++-- core/src/components/spinner/spinner.tsx | 12 +- core/src/components/split-pane/split-pane.tsx | 10 +- core/src/components/status-tap/status-tap.tsx | 4 +- core/src/components/tab-button/tab-button.tsx | 13 +- core/src/components/tab/tab.tsx | 20 +- core/src/components/tabbar/tabbar.tsx | 50 ++-- core/src/components/tabs/tabs.tsx | 30 +-- .../test/translucent/translucent-page-tab.tsx | 2 +- core/src/components/tap-click/tap-click.tsx | 18 +- core/src/components/text/text.tsx | 5 +- core/src/components/textarea/textarea.tsx | 37 +-- core/src/components/title/title.tsx | 5 +- .../toast-controller/toast-controller.tsx | 2 +- core/src/components/toast/readme.md | 14 - core/src/components/toast/toast.tsx | 48 ++-- core/src/components/toggle/readme.md | 2 + core/src/components/toggle/toggle.tsx | 78 +++--- core/src/components/toolbar/toolbar.tsx | 8 +- .../virtual-scroll/virtual-scroll-utils.tsx | 8 +- .../virtual-scroll/virtual-scroll.tsx | 56 ++-- core/src/global/ionic-global.ts | 1 - .../src/global/test/config-controller.spec.ts | 76 +++++- core/src/global/test/dom-controller.spec.ts | 42 --- core/src/global/test/query-param.spec.ts | 26 -- core/src/index.d.ts | 10 +- core/src/utils/framework-delegate.ts | 2 +- core/src/utils/input-interfaces.ts | 64 +++-- core/src/utils/overlays.ts | 10 +- core/src/utils/show-hide-when-utils.ts | 12 +- core/src/utils/theme.ts | 8 +- core/tsconfig.json | 1 - 129 files changed, 1513 insertions(+), 1664 deletions(-) delete mode 100644 core/src/global/test/dom-controller.spec.ts delete mode 100644 core/src/global/test/query-param.spec.ts diff --git a/angular/src/directives/proxies.ts b/angular/src/directives/proxies.ts index ad2fa87668..69032eb022 100644 --- a/angular/src/directives/proxies.ts +++ b/angular/src/directives/proxies.ts @@ -59,8 +59,8 @@ export class Badge { export declare interface Button extends StencilComponents.IonButton {} @Directive({selector: 'ion-button', inputs: [color, mode, buttonType, disabled, expand, fill, routerDirection, href, round, size, strong, type], outputs: [ionFocus, ionBlur]}) export class Button { - ionFocus: EventEmitter; - ionBlur: EventEmitter; + ionFocus!: EventEmitter; + ionBlur!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [color, mode, buttonType, disabled, expand, fill, routerDirection, href, round, size, strong, type]); outputs(this, [ionFocus, ionBlur]); @@ -115,10 +115,10 @@ export class CardTitle { export declare interface Checkbox extends StencilComponents.IonCheckbox {} @Directive({selector: 'ion-checkbox', inputs: [color, mode, name, checked, disabled, value], outputs: [ionChange, ionFocus, ionBlur, ionStyle]}) export class Checkbox { - ionChange: EventEmitter; - ionFocus: EventEmitter; - ionBlur: EventEmitter; - ionStyle: EventEmitter; + ionChange!: EventEmitter; + ionFocus!: EventEmitter; + ionBlur!: EventEmitter; + ionStyle!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [color, mode, name, checked, disabled, value]); outputs(this, [ionChange, ionFocus, ionBlur, ionStyle]); @@ -158,8 +158,8 @@ export class Content { export declare interface Datetime extends StencilComponents.IonDatetime {} @Directive({selector: 'ion-datetime', inputs: [disabled, min, max, displayFormat, pickerFormat, cancelText, doneText, yearValues, monthValues, dayValues, hourValues, minuteValues, monthNames, monthShortNames, dayNames, dayShortNames, pickerOptions, placeholder, value], outputs: [ionCancel, ionStyle]}) export class Datetime { - ionCancel: EventEmitter; - ionStyle: EventEmitter; + ionCancel!: EventEmitter; + ionStyle!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [disabled, min, max, displayFormat, pickerFormat, cancelText, doneText, yearValues, monthValues, dayValues, hourValues, minuteValues, monthNames, monthShortNames, dayNames, dayShortNames, pickerOptions, placeholder, value]); outputs(this, [ionCancel, ionStyle]); @@ -223,7 +223,7 @@ export class HideWhen { export declare interface InfiniteScroll extends StencilComponents.IonInfiniteScroll {} @Directive({selector: 'ion-infinite-scroll', inputs: [threshold, disabled, position], outputs: [ionInfinite]}) export class InfiniteScroll { - ionInfinite: EventEmitter; + ionInfinite!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [complete, waitFor]); inputs(this, r, [threshold, disabled, position]); @@ -242,12 +242,12 @@ export class InfiniteScrollContent { export declare interface Input extends StencilComponents.IonInput {} @Directive({selector: 'ion-input', inputs: [accept, autocapitalize, autocomplete, autocorrect, autofocus, checked, clearInput, clearOnEdit, debounce, disabled, inputmode, max, maxlength, min, minlength, multiple, name, pattern, placeholder, readonly, required, results, spellcheck, step, size, type, value], outputs: [ionInput, ionStyle, ionBlur, ionFocus, ionInputDidLoad, ionInputDidUnload]}) export class Input { - ionInput: EventEmitter; - ionStyle: EventEmitter; - ionBlur: EventEmitter; - ionFocus: EventEmitter; - ionInputDidLoad: EventEmitter; - ionInputDidUnload: EventEmitter; + ionInput!: EventEmitter; + ionStyle!: EventEmitter; + ionBlur!: EventEmitter; + ionFocus!: EventEmitter; + ionInputDidLoad!: EventEmitter; + ionInputDidUnload!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [accept, autocapitalize, autocomplete, autocorrect, autofocus, checked, clearInput, clearOnEdit, debounce, disabled, inputmode, max, maxlength, min, minlength, multiple, name, pattern, placeholder, readonly, required, results, spellcheck, step, size, type, value]); outputs(this, [ionInput, ionStyle, ionBlur, ionFocus, ionInputDidLoad, ionInputDidUnload]); @@ -286,7 +286,7 @@ export class ItemOption { export declare interface ItemOptions extends StencilComponents.IonItemOptions {} @Directive({selector: 'ion-item-options', inputs: [side], outputs: [ionSwipe]}) export class ItemOptions { - ionSwipe: EventEmitter; + ionSwipe!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [isRightSide, width, fireSwipeEvent]); inputs(this, r, [side]); @@ -297,7 +297,7 @@ export class ItemOptions { export declare interface ItemSliding extends StencilComponents.IonItemSliding {} @Directive({selector: 'ion-item-sliding', outputs: [ionDrag]}) export class ItemSliding { - ionDrag: EventEmitter; + ionDrag!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [getOpenAmount, getSlidingRatio, close, closeOpened]); outputs(this, [ionDrag]); @@ -307,7 +307,7 @@ export class ItemSliding { export declare interface Label extends StencilComponents.IonLabel {} @Directive({selector: 'ion-label', inputs: [color, mode, position], outputs: [ionStyle]}) export class Label { - ionStyle: EventEmitter; + ionStyle!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [getText]); inputs(this, r, [color, mode, position]); @@ -334,9 +334,9 @@ export class ListHeader { export declare interface Menu extends StencilComponents.IonMenu {} @Directive({selector: 'ion-menu', inputs: [contentId, menuId, type, disabled, side, swipeEnabled, persistent, maxEdgeStart], outputs: [ionOpen, ionClose, ionMenuChange]}) export class Menu { - ionOpen: EventEmitter; - ionClose: EventEmitter; - ionMenuChange: EventEmitter; + ionOpen!: EventEmitter; + ionClose!: EventEmitter; + ionMenuChange!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [isOpen, open, close, toggle, setOpen, isActive]); inputs(this, r, [contentId, menuId, type, disabled, side, swipeEnabled, persistent, maxEdgeStart]); @@ -363,8 +363,8 @@ export class MenuToggle { export declare interface Nav extends StencilComponents.IonNav {} @Directive({selector: 'ion-nav', inputs: [swipeBackEnabled, animated, delegate, rootParams, root], outputs: [ionNavWillChange, ionNavDidChange]}) export class Nav { - ionNavWillChange: EventEmitter; - ionNavDidChange: EventEmitter; + ionNavWillChange!: EventEmitter; + ionNavDidChange!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [push, insert, insertPages, pop, popTo, popToRoot, removeIndex, setRoot, setPages, setRouteId, getRouteId, canGoBack, getActive, getByIndex, getPrevious, length]); inputs(this, r, [swipeBackEnabled, animated, delegate, rootParams, root]); @@ -404,12 +404,12 @@ export class Note { export declare interface Radio extends StencilComponents.IonRadio {} @Directive({selector: 'ion-radio', inputs: [color, mode, name, disabled, checked, value], outputs: [ionRadioDidLoad, ionRadioDidUnload, ionStyle, ionSelect, ionFocus, ionBlur]}) export class Radio { - ionRadioDidLoad: EventEmitter; - ionRadioDidUnload: EventEmitter; - ionStyle: EventEmitter; - ionSelect: EventEmitter; - ionFocus: EventEmitter; - ionBlur: EventEmitter; + ionRadioDidLoad!: EventEmitter; + ionRadioDidUnload!: EventEmitter; + ionStyle!: EventEmitter; + ionSelect!: EventEmitter; + ionFocus!: EventEmitter; + ionBlur!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [color, mode, name, disabled, checked, value]); outputs(this, [ionRadioDidLoad, ionRadioDidUnload, ionStyle, ionSelect, ionFocus, ionBlur]); @@ -419,7 +419,7 @@ export class Radio { export declare interface RadioGroup extends StencilComponents.IonRadioGroup {} @Directive({selector: 'ion-radio-group', inputs: [allowEmptySelection, disabled, name, value], outputs: [ionChange]}) export class RadioGroup { - ionChange: EventEmitter; + ionChange!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [allowEmptySelection, disabled, name, value]); outputs(this, [ionChange]); @@ -429,10 +429,10 @@ export class RadioGroup { export declare interface Range extends StencilComponents.IonRange {} @Directive({selector: 'ion-range', inputs: [color, mode, debounce, disabled, dualKnobs, max, min, pin, snaps, step, value], outputs: [ionChange, ionStyle, ionFocus, ionBlur]}) export class Range { - ionChange: EventEmitter; - ionStyle: EventEmitter; - ionFocus: EventEmitter; - ionBlur: EventEmitter; + ionChange!: EventEmitter; + ionStyle!: EventEmitter; + ionFocus!: EventEmitter; + ionBlur!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [ratio, ratioUpper]); inputs(this, r, [color, mode, debounce, disabled, dualKnobs, max, min, pin, snaps, step, value]); @@ -443,9 +443,9 @@ export class Range { export declare interface Refresher extends StencilComponents.IonRefresher {} @Directive({selector: 'ion-refresher', inputs: [pullMin, pullMax, closeDuration, snapbackDuration, disabled], outputs: [ionRefresh, ionPull, ionStart]}) export class Refresher { - ionRefresh: EventEmitter; - ionPull: EventEmitter; - ionStart: EventEmitter; + ionRefresh!: EventEmitter; + ionPull!: EventEmitter; + ionStart!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [complete, cancel, getProgress]); inputs(this, r, [pullMin, pullMax, closeDuration, snapbackDuration, disabled]); @@ -491,9 +491,9 @@ export class Row { export declare interface Scroll extends StencilComponents.IonScroll {} @Directive({selector: 'ion-scroll', inputs: [mode, forceOverscroll, scrollEvents], outputs: [ionScrollStart, ionScroll, ionScrollEnd]}) export class Scroll { - ionScrollStart: EventEmitter; - ionScroll: EventEmitter; - ionScrollEnd: EventEmitter; + ionScrollStart!: EventEmitter; + ionScroll!: EventEmitter; + ionScrollEnd!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [scrollToTop, scrollToBottom, scrollByPoint, scrollToPoint]); inputs(this, r, [mode, forceOverscroll, scrollEvents]); @@ -504,11 +504,11 @@ export class Scroll { export declare interface Searchbar extends StencilComponents.IonSearchbar {} @Directive({selector: 'ion-searchbar', inputs: [color, mode, animated, autocomplete, autocorrect, cancelButtonText, debounce, placeholder, showCancelButton, spellcheck, type, value], outputs: [ionInput, ionCancel, ionClear, ionBlur, ionFocus]}) export class Searchbar { - ionInput: EventEmitter; - ionCancel: EventEmitter; - ionClear: EventEmitter; - ionBlur: EventEmitter; - ionFocus: EventEmitter; + ionInput!: EventEmitter; + ionCancel!: EventEmitter; + ionClear!: EventEmitter; + ionBlur!: EventEmitter; + ionFocus!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [color, mode, animated, autocomplete, autocorrect, cancelButtonText, debounce, placeholder, showCancelButton, spellcheck, type, value]); outputs(this, [ionInput, ionCancel, ionClear, ionBlur, ionFocus]); @@ -518,7 +518,7 @@ export class Searchbar { export declare interface Segment extends StencilComponents.IonSegment {} @Directive({selector: 'ion-segment', inputs: [color, mode, disabled, value], outputs: [ionChange]}) export class Segment { - ionChange: EventEmitter; + ionChange!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [color, mode, disabled, value]); outputs(this, [ionChange]); @@ -528,7 +528,7 @@ export class Segment { export declare interface SegmentButton extends StencilComponents.IonSegmentButton {} @Directive({selector: 'ion-segment-button', inputs: [activated, color, mode, checked, disabled, href, value], outputs: [ionClick]}) export class SegmentButton { - ionClick: EventEmitter; + ionClick!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [activated, color, mode, checked, disabled, href, value]); outputs(this, [ionClick]); @@ -538,11 +538,11 @@ export class SegmentButton { export declare interface Select extends StencilComponents.IonSelect {} @Directive({selector: 'ion-select', inputs: [disabled, cancelText, okText, placeholder, name, selectedText, multiple, 'interface', interfaceOptions, value], outputs: [ionChange, ionCancel, ionFocus, ionBlur, ionStyle]}) export class Select { - ionChange: EventEmitter; - ionCancel: EventEmitter; - ionFocus: EventEmitter; - ionBlur: EventEmitter; - ionStyle: EventEmitter; + ionChange!: EventEmitter; + ionCancel!: EventEmitter; + ionFocus!: EventEmitter; + ionBlur!: EventEmitter; + ionStyle!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [disabled, cancelText, okText, placeholder, name, selectedText, multiple, 'interface', interfaceOptions, value]); outputs(this, [ionChange, ionCancel, ionFocus, ionBlur, ionStyle]); @@ -552,8 +552,8 @@ export class Select { export declare interface SelectOption extends StencilComponents.IonSelectOption {} @Directive({selector: 'ion-select-option', inputs: [disabled, selected, value], outputs: [ionSelectOptionDidLoad, ionSelectOptionDidUnload]}) export class SelectOption { - ionSelectOptionDidLoad: EventEmitter; - ionSelectOptionDidUnload: EventEmitter; + ionSelectOptionDidLoad!: EventEmitter; + ionSelectOptionDidUnload!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [disabled, selected, value]); outputs(this, [ionSelectOptionDidLoad, ionSelectOptionDidUnload]); @@ -592,19 +592,19 @@ export class Slide { export declare interface Slides extends StencilComponents.IonSlides {} @Directive({selector: 'ion-slides', inputs: [options, pager], outputs: [ionSlideWillChange, ionSlideDidChange, ionSlideNextStart, ionSlidePrevStart, ionSlideNextEnd, ionSlidePrevEnd, ionSlideTransitionStart, ionSlideTransitionEnd, ionSlideDrag, ionSlideReachStart, ionSlideReachEnd, ionSlideTouchStart, ionSlideTouchEnd]}) export class Slides { - ionSlideWillChange: EventEmitter; - ionSlideDidChange: EventEmitter; - ionSlideNextStart: EventEmitter; - ionSlidePrevStart: EventEmitter; - ionSlideNextEnd: EventEmitter; - ionSlidePrevEnd: EventEmitter; - ionSlideTransitionStart: EventEmitter; - ionSlideTransitionEnd: EventEmitter; - ionSlideDrag: EventEmitter; - ionSlideReachStart: EventEmitter; - ionSlideReachEnd: EventEmitter; - ionSlideTouchStart: EventEmitter; - ionSlideTouchEnd: EventEmitter; + ionSlideWillChange!: EventEmitter; + ionSlideDidChange!: EventEmitter; + ionSlideNextStart!: EventEmitter; + ionSlidePrevStart!: EventEmitter; + ionSlideNextEnd!: EventEmitter; + ionSlidePrevEnd!: EventEmitter; + ionSlideTransitionStart!: EventEmitter; + ionSlideTransitionEnd!: EventEmitter; + ionSlideDrag!: EventEmitter; + ionSlideReachStart!: EventEmitter; + ionSlideReachEnd!: EventEmitter; + ionSlideTouchStart!: EventEmitter; + ionSlideTouchEnd!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [update, slideTo, slideNext, slidePrev, getActiveIndex, getPreviousIndex, length, isEnd, isBeginning, startAutoplay, stopAutoplay, lockSwipeToNext, lockSwipeToPrev, lockSwipes]); inputs(this, r, [options, pager]); @@ -623,8 +623,8 @@ export class Spinner { export declare interface SplitPane extends StencilComponents.IonSplitPane {} @Directive({selector: 'ion-split-pane', inputs: [disabled, when], outputs: [ionChange, ionSplitPaneVisible]}) export class SplitPane { - ionChange: EventEmitter; - ionSplitPaneVisible: EventEmitter; + ionChange!: EventEmitter; + ionSplitPaneVisible!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [isVisible, isPane]); inputs(this, r, [disabled, when]); @@ -635,7 +635,7 @@ export class SplitPane { export declare interface Tab extends StencilComponents.IonTab {} @Directive({selector: 'ion-tab', inputs: [active, btnId, delegate, label, href, icon, badge, badgeStyle, component, name, disabled, selected, show, tabsHideOnSubPages], outputs: [ionSelect]}) export class Tab { - ionSelect: EventEmitter; + ionSelect!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [getTabId, setActive]); inputs(this, r, [active, btnId, delegate, label, href, icon, badge, badgeStyle, component, name, disabled, selected, show, tabsHideOnSubPages]); @@ -646,9 +646,9 @@ export class Tab { export declare interface Tabs extends StencilComponents.IonTabs {} @Directive({selector: 'ion-tabs', inputs: [color, name, tabbarHidden, tabbarLayout, tabbarPlacement, tabbarHighlight, translucent, scrollable, useRouter], outputs: [ionChange, ionNavWillChange, ionNavDidChange]}) export class Tabs { - ionChange: EventEmitter; - ionNavWillChange: EventEmitter; - ionNavDidChange: EventEmitter; + ionChange!: EventEmitter; + ionNavWillChange!: EventEmitter; + ionNavDidChange!: EventEmitter; constructor(r: ElementRef) { methods(this, r, [select, setRouteId, getRouteId, getTab, getSelected]); inputs(this, r, [color, name, tabbarHidden, tabbarLayout, tabbarPlacement, tabbarHighlight, translucent, scrollable, useRouter]); @@ -667,10 +667,10 @@ export class Text { export declare interface Textarea extends StencilComponents.IonTextarea {} @Directive({selector: 'ion-textarea', inputs: [autocapitalize, autocomplete, autofocus, clearOnEdit, debounce, disabled, maxlength, minlength, name, placeholder, readonly, required, spellcheck, cols, rows, wrap, value], outputs: [ionInput, ionStyle, ionBlur, ionFocus]}) export class Textarea { - ionInput: EventEmitter; - ionStyle: EventEmitter; - ionBlur: EventEmitter; - ionFocus: EventEmitter; + ionInput!: EventEmitter; + ionStyle!: EventEmitter; + ionBlur!: EventEmitter; + ionFocus!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [autocapitalize, autocomplete, autofocus, clearOnEdit, debounce, disabled, maxlength, minlength, name, placeholder, readonly, required, spellcheck, cols, rows, wrap, value]); outputs(this, [ionInput, ionStyle, ionBlur, ionFocus]); @@ -685,10 +685,10 @@ export class Thumbnail { export declare interface Toggle extends StencilComponents.IonToggle {} @Directive({selector: 'ion-toggle', inputs: [color, mode, name, checked, disabled, value], outputs: [ionChange, ionFocus, ionBlur, ionStyle]}) export class Toggle { - ionChange: EventEmitter; - ionFocus: EventEmitter; - ionBlur: EventEmitter; - ionStyle: EventEmitter; + ionChange!: EventEmitter; + ionFocus!: EventEmitter; + ionBlur!: EventEmitter; + ionStyle!: EventEmitter; constructor(r: ElementRef) { inputs(this, r, [color, mode, name, checked, disabled, value]); outputs(this, [ionChange, ionFocus, ionBlur, ionStyle]); diff --git a/core/scripts/theme-builder/src/components/app-preview/app-preview.tsx b/core/scripts/theme-builder/src/components/app-preview/app-preview.tsx index 21f49ef4fd..ededf09b13 100644 --- a/core/scripts/theme-builder/src/components/app-preview/app-preview.tsx +++ b/core/scripts/theme-builder/src/components/app-preview/app-preview.tsx @@ -15,7 +15,7 @@ export class AppPreview { hasIframeListener: boolean = false; @Prop() hoverProperty: string; iframe: HTMLIFrameElement; - @Event() propertiesUsed: EventEmitter; + @Event() propertiesUsed!: EventEmitter; applyStyles () { if (this.iframe && this.iframe.contentDocument && this.iframe.contentDocument.documentElement) { diff --git a/core/scripts/theme-builder/src/components/css-text/css-text.tsx b/core/scripts/theme-builder/src/components/css-text/css-text.tsx index 67f8de611a..073f4b3173 100644 --- a/core/scripts/theme-builder/src/components/css-text/css-text.tsx +++ b/core/scripts/theme-builder/src/components/css-text/css-text.tsx @@ -9,7 +9,7 @@ import { deleteCssUrl, getThemeUrl, saveCssUrl, STORED_THEME_KEY } from '../help export class CssText { @Prop() cssText: string; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; @Prop() themeName: string; createNew (ev: UIEvent) { diff --git a/core/scripts/theme-builder/src/components/demo-selection/demo-selection.tsx b/core/scripts/theme-builder/src/components/demo-selection/demo-selection.tsx index a32057920b..3910800d61 100644 --- a/core/scripts/theme-builder/src/components/demo-selection/demo-selection.tsx +++ b/core/scripts/theme-builder/src/components/demo-selection/demo-selection.tsx @@ -10,9 +10,9 @@ export class DemoSelection { @Prop() demoData: { name: string, url: string }[]; @Prop() demoMode: string; - @Event() demoModeChange: EventEmitter; + @Event() demoModeChange!: EventEmitter; @Prop() demoUrl: string; - @Event() demoUrlChange: EventEmitter; + @Event() demoUrlChange!: EventEmitter; onChangeMode (ev) { this.demoModeChange.emit(ev.currentTarget.value); diff --git a/core/scripts/theme-builder/src/components/theme-selector/theme-selector.tsx b/core/scripts/theme-builder/src/components/theme-selector/theme-selector.tsx index cf2296b663..e205e795f5 100644 --- a/core/scripts/theme-builder/src/components/theme-selector/theme-selector.tsx +++ b/core/scripts/theme-builder/src/components/theme-selector/theme-selector.tsx @@ -17,17 +17,17 @@ enum DefaultCSSDuplicateMode { }) export class ThemeSelector { - @Element() el: HTMLThemeSelectorElement; + @Element() el!: HTMLThemeSelectorElement; @State() generateContrast: boolean = false; @State() generateSteps: boolean = true; @State() generateVariations: boolean = true; @State() palettes: any[]; @Prop() propertiesUsed: string[] = []; - @Event() propertyHoverStart: EventEmitter; - @Event() propertyHoverStop: EventEmitter; + @Event() propertyHoverStart!: EventEmitter; + @Event() propertyHoverStop!: EventEmitter; @State() searchMode: boolean; @State() showSteps: boolean = true; - @Event() themeCssChange: EventEmitter; + @Event() themeCssChange!: EventEmitter; @Prop() themeData: { name: string }[]; @State() themeName: string; @State() themeVariables: ThemeVariable[] = []; diff --git a/core/scripts/theme-builder/src/components/variable-selector/variable-selector.tsx b/core/scripts/theme-builder/src/components/variable-selector/variable-selector.tsx index dea827039a..42cb348657 100644 --- a/core/scripts/theme-builder/src/components/variable-selector/variable-selector.tsx +++ b/core/scripts/theme-builder/src/components/variable-selector/variable-selector.tsx @@ -10,9 +10,9 @@ import { Color } from '. }) export class VariableSelector { - @Event() colorChange: EventEmitter; - @Element() el: HTMLElement; - @Event() generateColors: EventEmitter; + @Event() colorChange!: EventEmitter; + @Element() el!: HTMLElement; + @Event() generateColors!: EventEmitter; @Prop() isRgb: boolean; @Prop() property: string; @Prop() type: 'color' | 'percent'; diff --git a/core/src/components.d.ts b/core/src/components.d.ts index c071d71061..daa04bc25c 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -36,6 +36,7 @@ import { LoadingOptions, Menu, ModalOptions, + Mode, PickerColumn, PickerOptions, PopoverOptions, @@ -58,6 +59,13 @@ import { Animation, AnimationBuilder as AnimationBuilder2, } from './components/animation-controller/animation-interface'; +import { + AnimationBuilder as AnimationBuilder3, + ComponentProps as ComponentProps2, + ComponentRef as ComponentRef2, + FrameworkDelegate as FrameworkDelegate2, + Mode as Mode2, +} from '.'; import { BlurEvent, CheckedInputChangeEvent, @@ -91,12 +99,6 @@ import { TransitionDoneFn, TransitionInstruction, } from './components/nav/nav-util'; -import { - AnimationBuilder as AnimationBuilder3, - ComponentProps as ComponentProps2, - ComponentRef as ComponentRef2, - FrameworkDelegate as FrameworkDelegate2, -} from '.'; import { ViewController, } from './components/nav/view-controller'; @@ -389,7 +391,6 @@ declare global { * The main message to be displayed in the alert. */ 'message': string; - 'mode': string; /** * Returns a promise that resolves when the alert did dismiss. It also accepts a callback that is called in the same circustances. ``` const {data, role} = await alert.onDidDismiss(); ``` */ @@ -470,7 +471,6 @@ declare global { * The main message to be displayed in the alert. */ 'message'?: string; - 'mode'?: string; /** * Emitted after the alert has dismissed. */ @@ -678,11 +678,11 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * The text to display in the back button. */ - 'text': string | undefined; + 'text': string; } } @@ -720,11 +720,11 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * The text to display in the back button. */ - 'text'?: string | undefined; + 'text'?: string; } } } @@ -800,7 +800,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -830,7 +830,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -867,7 +867,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * If true, activates a button with rounded corners. */ @@ -937,7 +937,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * Emitted when the button loses focus. */ @@ -1015,7 +1015,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -1045,7 +1045,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -1062,7 +1062,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * If true, the card header will be translucent. Defaults to `false`. */ @@ -1096,7 +1096,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * If true, the card header will be translucent. Defaults to `false`. */ @@ -1117,7 +1117,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -1147,7 +1147,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -1164,7 +1164,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -1194,7 +1194,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -1211,7 +1211,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -1241,7 +1241,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -1266,7 +1266,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * The name of the control, which is submitted with the form data. */ @@ -1312,7 +1312,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * The name of the control, which is submitted with the form data. */ @@ -1365,7 +1365,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -1407,7 +1407,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -1424,7 +1424,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -1454,7 +1454,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -1565,15 +1565,15 @@ declare global { /** * Full day of the week names. This can be used to provide locale names for each day in the week. Defaults to English. */ - 'dayNames': string[] | string | undefined; + 'dayNames': string[] | string; /** * Short abbreviated day of the week names. This can be used to provide locale names for each day in the week. Defaults to English. */ - 'dayShortNames': string[] | string | undefined; + 'dayShortNames': string[] | string; /** * Values used to create the list of selectable days. By default every day is shown for the given month. However, to control exactly which days of the month to display, the `dayValues` input can take a number, an array of numbers, or a string of comma separated numbers. Note that even if the array days have an invalid number for the selected month, like `31` in February, it will correctly not show days which are not valid for the selected month. */ - 'dayValues': number[] | number | string | undefined; + 'dayValues': number[] | number | string; /** * If true, the user cannot interact with the datetime. Defaults to `false`. */ @@ -1589,7 +1589,7 @@ declare global { /** * Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers. */ - 'hourValues': number[] | number | string | undefined; + 'hourValues': number[] | number | string; /** * The maximum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the maximum could just be the year, such as `1994`. Defaults to the end of this year. */ @@ -1601,23 +1601,23 @@ declare global { /** * Values used to create the list of selectable minutes. By default the mintues range from `0` to `59`. However, to control exactly which minutes to display, the `minuteValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if the minute selections should only be every 15 minutes, then this input value would be `minuteValues="0,15,30,45"`. */ - 'minuteValues': number[] | number | string | undefined; + 'minuteValues': number[] | number | string; /** * Full names for each month name. This can be used to provide locale month names. Defaults to English. */ - 'monthNames': string[] | string | undefined; + 'monthNames': string[] | string; /** * Short abbreviated names for each month name. This can be used to provide locale month names. Defaults to English. */ - 'monthShortNames': string[] | string | undefined; + 'monthShortNames': string[] | string; /** * Values used to create the list of selectable months. By default the month values range from `1` to `12`. However, to control exactly which months to display, the `monthValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if only summer months should be shown, then this input value would be `monthValues="6,7,8"`. Note that month numbers do *not* have a zero-based index, meaning January's value is `1`, and December's is `12`. */ - 'monthValues': number[] | number | string | undefined; + 'monthValues': number[] | number | string; /** * The format of the date and time picker columns the user selects. A datetime input can have one or many datetime parts, each getting their own column which allow individual selection of that particular datetime part. For example, year and month columns are two individually selectable columns which help choose an exact date from the datetime picker. Each column follows the string parse format. Defaults to use `displayFormat`. */ - 'pickerFormat': string | undefined; + 'pickerFormat': string; /** * Any additional options that the picker interface can accept. See the [Picker API docs](../../picker/Picker) for the picker options. */ @@ -1625,7 +1625,7 @@ declare global { /** * The text to display when there's no date selected yet. Using lowercase to match the input attribute */ - 'placeholder': string | undefined; + 'placeholder': string; /** * the value of the datetime. */ @@ -1633,7 +1633,7 @@ declare global { /** * Values used to create the list of selectable years. By default the year values range between the `min` and `max` datetime inputs. However, to control exactly which years to display, the `yearValues` input can take a number, an array of numbers, or string of comma separated numbers. For example, to show upcoming and recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`. */ - 'yearValues': number[] | number | string | undefined; + 'yearValues': number[] | number | string; } } @@ -1663,15 +1663,15 @@ declare global { /** * Full day of the week names. This can be used to provide locale names for each day in the week. Defaults to English. */ - 'dayNames'?: string[] | string | undefined; + 'dayNames'?: string[] | string; /** * Short abbreviated day of the week names. This can be used to provide locale names for each day in the week. Defaults to English. */ - 'dayShortNames'?: string[] | string | undefined; + 'dayShortNames'?: string[] | string; /** * Values used to create the list of selectable days. By default every day is shown for the given month. However, to control exactly which days of the month to display, the `dayValues` input can take a number, an array of numbers, or a string of comma separated numbers. Note that even if the array days have an invalid number for the selected month, like `31` in February, it will correctly not show days which are not valid for the selected month. */ - 'dayValues'?: number[] | number | string | undefined; + 'dayValues'?: number[] | number | string; /** * If true, the user cannot interact with the datetime. Defaults to `false`. */ @@ -1687,7 +1687,7 @@ declare global { /** * Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers. */ - 'hourValues'?: number[] | number | string | undefined; + 'hourValues'?: number[] | number | string; /** * The maximum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the maximum could just be the year, such as `1994`. Defaults to the end of this year. */ @@ -1699,19 +1699,19 @@ declare global { /** * Values used to create the list of selectable minutes. By default the mintues range from `0` to `59`. However, to control exactly which minutes to display, the `minuteValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if the minute selections should only be every 15 minutes, then this input value would be `minuteValues="0,15,30,45"`. */ - 'minuteValues'?: number[] | number | string | undefined; + 'minuteValues'?: number[] | number | string; /** * Full names for each month name. This can be used to provide locale month names. Defaults to English. */ - 'monthNames'?: string[] | string | undefined; + 'monthNames'?: string[] | string; /** * Short abbreviated names for each month name. This can be used to provide locale month names. Defaults to English. */ - 'monthShortNames'?: string[] | string | undefined; + 'monthShortNames'?: string[] | string; /** * Values used to create the list of selectable months. By default the month values range from `1` to `12`. However, to control exactly which months to display, the `monthValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if only summer months should be shown, then this input value would be `monthValues="6,7,8"`. Note that month numbers do *not* have a zero-based index, meaning January's value is `1`, and December's is `12`. */ - 'monthValues'?: number[] | number | string | undefined; + 'monthValues'?: number[] | number | string; /** * Emitted when the datetime selection was cancelled. */ @@ -1723,7 +1723,7 @@ declare global { /** * The format of the date and time picker columns the user selects. A datetime input can have one or many datetime parts, each getting their own column which allow individual selection of that particular datetime part. For example, year and month columns are two individually selectable columns which help choose an exact date from the datetime picker. Each column follows the string parse format. Defaults to use `displayFormat`. */ - 'pickerFormat'?: string | undefined; + 'pickerFormat'?: string; /** * Any additional options that the picker interface can accept. See the [Picker API docs](../../picker/Picker) for the picker options. */ @@ -1731,7 +1731,7 @@ declare global { /** * The text to display when there's no date selected yet. Using lowercase to match the input attribute */ - 'placeholder'?: string | undefined; + 'placeholder'?: string; /** * the value of the datetime. */ @@ -1739,7 +1739,7 @@ declare global { /** * Values used to create the list of selectable years. By default the year values range between the `min` and `max` datetime inputs. However, to control exactly which years to display, the `yearValues` input can take a number, an array of numbers, or string of comma separated numbers. For example, to show upcoming and recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`. */ - 'yearValues'?: number[] | number | string | undefined; + 'yearValues'?: number[] | number | string; } } } @@ -1764,11 +1764,11 @@ declare global { /** * Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered. */ - 'href': string | undefined; + 'href': string; /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; 'show': boolean; /** * If true, the fab button will be translucent. Defaults to `false`. @@ -1811,11 +1811,11 @@ declare global { /** * Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered. */ - 'href'?: string | undefined; + 'href'?: string; /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; 'show'?: boolean; /** * If true, the fab button will be translucent. Defaults to `false`. @@ -2171,7 +2171,6 @@ declare global { namespace StencilComponents { interface IonHideWhen { 'mediaQuery': string; - 'mode': string; 'or': boolean; 'orientation': string; 'platform': string; @@ -2199,7 +2198,6 @@ declare global { namespace JSXElements { export interface IonHideWhenAttributes extends HTMLAttributes { 'mediaQuery'?: string; - 'mode'?: string; 'or'?: boolean; 'orientation'?: string; 'platform'?: string; @@ -2638,7 +2636,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -2668,7 +2666,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -2730,7 +2728,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -2772,7 +2770,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -2902,7 +2900,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ @@ -2952,7 +2950,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ @@ -2974,7 +2972,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * The position determines where and how the label behaves inside an item. Possible values are: 'inline' | 'fixed' | 'stacked' | 'floating' */ @@ -3008,7 +3006,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * Emitted when the styles change. */ @@ -3033,7 +3031,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -3063,7 +3061,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -3080,11 +3078,11 @@ declare global { /** * Get the [Item Sliding](../../item-sliding/ItemSliding) that is currently opene. */ - 'getOpenItem': () => ItemSliding | null; + 'getOpenItem': () => ItemSliding | undefined; /** * Set an [Item Sliding](../../item-sliding/ItemSliding) as the open item. */ - 'setOpenItem': (itemSliding: ItemSliding | null) => void; + 'setOpenItem': (itemSliding: ItemSliding | undefined) => void; } } @@ -3652,7 +3650,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * Returns a promise that resolves when the modal did dismiss. It also accepts a callback that is called in the same circustances. ``` const {data, role} = await modal.onDidDismiss(); ``` */ @@ -3729,7 +3727,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * Emitted after the modal has dismissed. */ @@ -3807,7 +3805,6 @@ declare global { interface IonNavPush { 'component': NavComponent; 'componentProps': ComponentProps; - 'url': string; } } @@ -3832,7 +3829,6 @@ declare global { export interface IonNavPushAttributes extends HTMLAttributes { 'component'?: NavComponent; 'componentProps'?: ComponentProps; - 'url'?: string; } } } @@ -3844,7 +3840,6 @@ declare global { interface IonNavSetRoot { 'component': NavComponent; 'componentProps': ComponentProps; - 'url': string; } } @@ -3869,7 +3864,6 @@ declare global { export interface IonNavSetRootAttributes extends HTMLAttributes { 'component'?: NavComponent; 'componentProps'?: ComponentProps; - 'url'?: string; } } } @@ -3945,7 +3939,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -3975,7 +3969,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -4280,7 +4274,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * Returns a promise that resolves when the popover did dismiss. It also accepts a callback that is called in the same circustances. ``` const {data, role} = await popover.onDidDismiss(); ``` */ @@ -4365,7 +4359,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * Emitted after the popover has dismissed. */ @@ -4488,7 +4482,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * The name of the control, which is submitted with the form data. */ @@ -4534,7 +4528,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * The name of the control, which is submitted with the form data. */ @@ -4635,6 +4629,9 @@ declare global { * How long, in milliseconds, to wait to trigger the `ionChange` event after each change in the range value. Default `0`. */ 'debounce': number; + /** + * Indicates that the user cannot interact with the control. + */ 'disabled': boolean; /** * Show two knobs. Defaults to `false`. @@ -4651,7 +4648,11 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; + /** + * The name of the control, which is submitted with the form data. + */ + 'name': string; /** * If true, a pin with integer value is shown when the knob is pressed. Defaults to `false`. */ @@ -4706,6 +4707,9 @@ declare global { * How long, in milliseconds, to wait to trigger the `ionChange` event after each change in the range value. Default `0`. */ 'debounce'?: number; + /** + * Indicates that the user cannot interact with the control. + */ 'disabled'?: boolean; /** * Show two knobs. Defaults to `false`. @@ -4722,7 +4726,11 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; + /** + * The name of the control, which is submitted with the form data. + */ + 'name'?: string; /** * Emitted when the range loses focus. */ @@ -5256,7 +5264,7 @@ declare global { * If true and the content does not cause an overflow scroll, the scroll interaction will cause a bounce. If the content exceeds the bounds of ionScroll, nothing will change. Note, the does not disable the system bounce on iOS. That is an OS level setting. */ 'forceOverscroll': boolean; - 'mode': string; + 'mode': Mode; 'scrollByPoint': (x: number, y: number, duration: number, done?: Function | undefined) => Promise; 'scrollEvents': boolean; 'scrollToBottom': (duration: number) => Promise; @@ -5288,7 +5296,7 @@ declare global { * If true and the content does not cause an overflow scroll, the scroll interaction will cause a bounce. If the content exceeds the bounds of ionScroll, nothing will change. Note, the does not disable the system bounce on iOS. That is an OS level setting. */ 'forceOverscroll'?: boolean; - 'mode'?: string; + 'mode'?: Mode; /** * Emitted while scrolling. This event is disabled by default. Look at the property: `scrollEvents` */ @@ -5338,7 +5346,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * Set the input's placeholder. Default `"Search"`. */ @@ -5408,7 +5416,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * Emitted when the input loses focus. */ @@ -5475,7 +5483,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * The value of the segment button. */ @@ -5519,7 +5527,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * Emitted when the segment button is clicked. */ @@ -5545,7 +5553,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * the value of the segment. */ @@ -5580,7 +5588,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * Emitted when the value property has changed. */ @@ -5739,7 +5747,7 @@ declare global { /** * the value of the select. */ - 'value': string | string[] | undefined; + 'value': string | string[]; } } @@ -5821,7 +5829,7 @@ declare global { /** * the value of the select. */ - 'value'?: string | string[] | undefined; + 'value'?: string | string[]; } } } @@ -5832,7 +5840,6 @@ declare global { namespace StencilComponents { interface IonShowWhen { 'mediaQuery': string; - 'mode': string; 'or': boolean; 'orientation': string; 'platform': string; @@ -5860,7 +5867,6 @@ declare global { namespace JSXElements { export interface IonShowWhenAttributes extends HTMLAttributes { 'mediaQuery'?: string; - 'mode'?: string; 'or'?: boolean; 'orientation'?: string; 'platform'?: string; @@ -6106,7 +6112,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * The name of the SVG spinner to use. If a name is not provided, the platform's default spinner will be used. Possible values are: `"lines"`, `"lines-small"`, `"dots"`, `"bubbles"`, `"circles"`, `"crescent"`. */ @@ -6148,7 +6154,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * The name of the SVG spinner to use. If a name is not provided, the platform's default spinner will be used. Possible values are: `"lines"`, `"lines-small"`, `"dots"`, `"bubbles"`, `"circles"`, `"crescent"`. */ @@ -6618,7 +6624,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; } } @@ -6648,7 +6654,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; } } } @@ -6954,10 +6960,6 @@ declare global { * Dismiss the toast overlay after it has been presented. */ 'dismiss': (data?: any, role?: string | undefined) => Promise; - /** - * If true, the toast will dismiss when the page changes. Defaults to `false`. - */ - 'dismissOnPageChange': boolean; /** * How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. */ @@ -7034,10 +7036,6 @@ declare global { * Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. */ 'cssClass'?: string | string[]; - /** - * If true, the toast will dismiss when the page changes. Defaults to `false`. - */ - 'dismissOnPageChange'?: boolean; /** * How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. */ @@ -7120,13 +7118,13 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * The name of the control, which is submitted with the form data. */ 'name': string; /** - * the value of the toggle. + * // TODO! the value of the toggle. */ 'value': string; } @@ -7166,7 +7164,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * The name of the control, which is submitted with the form data. */ @@ -7188,7 +7186,7 @@ declare global { */ 'onIonStyle'?: (event: CustomEvent) => void; /** - * the value of the toggle. + * // TODO! the value of the toggle. */ 'value'?: string; } @@ -7207,7 +7205,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode': 'ios' | 'md'; + 'mode': Mode; /** * If true, the toolbar will be translucent. Note: In order to scroll content behind the toolbar, the `fullscreen` attribute needs to be set on the content. Defaults to `false`. */ @@ -7241,7 +7239,7 @@ declare global { /** * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - 'mode'?: 'ios' | 'md'; + 'mode'?: Mode; /** * If true, the toolbar will be translucent. Note: In order to scroll content behind the toolbar, the `fullscreen` attribute needs to be set on the content. Defaults to `false`. */ diff --git a/core/src/components/action-sheet-controller/action-sheet-controller.tsx b/core/src/components/action-sheet-controller/action-sheet-controller.tsx index 8f679ee764..4266097f5a 100644 --- a/core/src/components/action-sheet-controller/action-sheet-controller.tsx +++ b/core/src/components/action-sheet-controller/action-sheet-controller.tsx @@ -9,7 +9,7 @@ export class ActionSheetController implements OverlayController { private actionSheets = new Map(); - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; @Listen('body:ionActionSheetWillPresent') protected actionSheetWillPresent(ev: any) { diff --git a/core/src/components/action-sheet/action-sheet.tsx b/core/src/components/action-sheet/action-sheet.tsx index e544613730..9625cf9d42 100644 --- a/core/src/components/action-sheet/action-sheet.tsx +++ b/core/src/components/action-sheet/action-sheet.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index'; +import { Animation, AnimationBuilder, Config, CssClassMap, Mode } from '../../index'; import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; @@ -21,37 +21,37 @@ import mdLeaveAnimation from './animations/md.leave'; export class ActionSheet implements OverlayInterface { presented = false; - mode: string; - color: string; - animation: Animation|undefined; + mode!: Mode; + color!: string; + animation?: Animation; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; - @Prop({ context: 'config' }) config: Config; - @Prop() overlayId: number; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; + @Prop({ context: 'config' }) config!: Config; + @Prop() overlayId!: number; @Prop() keyboardClose = true; /** * Animation to use when the action sheet is presented. */ - @Prop() enterAnimation: AnimationBuilder; + @Prop() enterAnimation?: AnimationBuilder; /** * Animation to use when the action sheet is dismissed. */ - @Prop() leaveAnimation: AnimationBuilder; + @Prop() leaveAnimation?: AnimationBuilder; /** * An array of buttons for the action sheet. */ - @Prop() buttons: ActionSheetButton[]; + @Prop() buttons!: ActionSheetButton[]; /** * Additional classes to apply for custom CSS. If multiple classes are * provided they should be separated by spaces. */ - @Prop() cssClass: string | string[]; + @Prop() cssClass?: string | string[]; /** * If true, the action sheet will be dismissed when the backdrop is clicked. Defaults to `true`. @@ -61,12 +61,12 @@ export class ActionSheet implements OverlayInterface { /** * Title for the action sheet. */ - @Prop() header: string; + @Prop() header?: string; /** * Subtitle for the action sheet. */ - @Prop() subHeader: string; + @Prop() subHeader?: string; /** * If true, the action sheet will be translucent. Defaults to `false`. @@ -81,32 +81,32 @@ export class ActionSheet implements OverlayInterface { /** * Emitted after the alert has loaded. */ - @Event() ionActionSheetDidLoad: EventEmitter; + @Event() ionActionSheetDidLoad!: EventEmitter; /** * Emitted after the alert has unloaded. */ - @Event() ionActionSheetDidUnload: EventEmitter; + @Event() ionActionSheetDidUnload!: EventEmitter; /** * Emitted after the alert has presented. */ - @Event({eventName: 'ionActionSheetDidPresent'}) didPresent: EventEmitter; + @Event({eventName: 'ionActionSheetDidPresent'}) didPresent!: EventEmitter; /** * Emitted before the alert has presented. */ - @Event({eventName: 'ionActionSheetWillPresent'}) willPresent: EventEmitter; + @Event({eventName: 'ionActionSheetWillPresent'}) willPresent!: EventEmitter; /** * Emitted before the alert has dismissed. */ - @Event({eventName: 'ionActionSheetWillDismiss'}) willDismiss: EventEmitter; + @Event({eventName: 'ionActionSheetWillDismiss'}) willDismiss!: EventEmitter; /** * Emitted after the alert has dismissed. */ - @Event({eventName: 'ionActionSheetDidDismiss'}) didDismiss: EventEmitter; + @Event({eventName: 'ionActionSheetDidDismiss'}) didDismiss!: EventEmitter; componentDidLoad() { @@ -288,7 +288,7 @@ export interface ActionSheetOptions { header?: string; subHeader?: string; cssClass?: string; - buttons?: (ActionSheetButton | string)[]; + buttons: (ActionSheetButton | string)[]; enableBackdropDismiss?: boolean; translucent?: boolean; } diff --git a/core/src/components/alert-controller/alert-controller.tsx b/core/src/components/alert-controller/alert-controller.tsx index 4f54e312d2..3072aa14fc 100644 --- a/core/src/components/alert-controller/alert-controller.tsx +++ b/core/src/components/alert-controller/alert-controller.tsx @@ -9,7 +9,7 @@ export class AlertController implements OverlayController { private alerts = new Map(); - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; @Listen('body:ionAlertWillPresent') protected alertWillPresent(ev: any) { diff --git a/core/src/components/alert/alert.tsx b/core/src/components/alert/alert.tsx index caa55d4c21..68ccccaf54 100644 --- a/core/src/components/alert/alert.tsx +++ b/core/src/components/alert/alert.tsx @@ -1,5 +1,5 @@ -import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index'; +import { Component, Element, Event, EventEmitter, Listen, Method, Prop, Watch } from '@stencil/core'; +import { Animation, AnimationBuilder, Config, CssClassMap, Mode } from '../../index'; import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; @@ -20,52 +20,53 @@ import mdLeaveAnimation from './animations/md.leave'; }) export class Alert implements OverlayInterface { - private activeId: string | undefined; - private inputType: string | undefined; - private hdrId: string; + private activeId?: string; + private inputType?: string; + private processedInputs: AlertInput[] = []; presented = false; - animation: Animation|undefined; - color: string; + animation?: Animation; - @Element() el: HTMLElement; + color!: string; + mode!: Mode; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; - @Prop({ context: 'config' }) config: Config; - @Prop() overlayId: number; - @Prop() mode: string; + @Element() el!: HTMLStencilElement; + + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; + @Prop({ context: 'config' }) config!: Config; + @Prop() overlayId!: number; @Prop() keyboardClose = true; /** * Animation to use when the alert is presented. */ - @Prop() enterAnimation: AnimationBuilder; + @Prop() enterAnimation?: AnimationBuilder; /** * Animation to use when the alert is dismissed. */ - @Prop() leaveAnimation: AnimationBuilder; + @Prop() leaveAnimation?: AnimationBuilder; /** * Additional classes to apply for custom CSS. If multiple classes are * provided they should be separated by spaces. */ - @Prop() cssClass: string | string[]; + @Prop() cssClass?: string | string[]; /** * The main title in the heading of the alert. */ - @Prop() header: string; + @Prop() header?: string; /** * The subtitle in the heading of the alert. Displayed under the title. */ - @Prop() subHeader: string; + @Prop() subHeader?: string; /** * The main message to be displayed in the alert. */ - @Prop() message: string; + @Prop() message?: string; /** * Array of buttons to be added to the alert. @@ -95,33 +96,62 @@ export class Alert implements OverlayInterface { /** * Emitted after the alert has presented. */ - @Event() ionAlertDidLoad: EventEmitter; + @Event() ionAlertDidLoad!: EventEmitter; /** * Emitted before the alert has presented. */ - @Event() ionAlertDidUnload: EventEmitter; + @Event() ionAlertDidUnload!: EventEmitter; /** * Emitted after the alert has presented. */ - @Event({eventName: 'ionAlertDidPresent'}) didPresent: EventEmitter; + @Event({eventName: 'ionAlertDidPresent'}) didPresent!: EventEmitter; /** * Emitted before the alert has presented. */ - @Event({eventName: 'ionAlertWillPresent'}) willPresent: EventEmitter; + @Event({eventName: 'ionAlertWillPresent'}) willPresent!: EventEmitter; /** * Emitted before the alert has dismissed. */ - @Event({eventName: 'ionAlertWillDismiss'}) willDismiss: EventEmitter; + @Event({eventName: 'ionAlertWillDismiss'}) willDismiss!: EventEmitter; /** * Emitted after the alert has dismissed. */ - @Event({eventName: 'ionAlertDidDismiss'}) didDismiss: EventEmitter; + @Event({eventName: 'ionAlertDidDismiss'}) didDismiss!: EventEmitter; + @Watch('inputs') + inputsChanged() { + const inputs = this.inputs; + + // An alert can be created with several different inputs. Radios, + // checkboxes and inputs are all accepted, but they cannot be mixed. + const inputTypes = new Set(inputs.map(i => i.type)); + if (inputTypes.has('checkbox') || inputTypes.has('radio')) { + console.warn(`Alert cannot mix input types: ${(Array.from(inputTypes.values()).join('/'))}. Please see alert docs for more info.`); + } + this.inputType = inputTypes.values().next().value; + this.processedInputs = inputs.map((i, index) => ({ + type: i.type || 'text', + name: i.name ? i.name : index + '', + placeholder: i.placeholder ? i.placeholder : '', + value: i.value ? i.value : '', + label: i.label, + checked: !!i.checked, + disabled: !!i.disabled, + id: i.id ? i.id : `alert-input-${this.overlayId}-${index}`, + handler: i.handler ? i.handler : null, + min: i.min ? i.min : null, + max: i.max ? i.max : null + }) as AlertInput); + } + + componentWillLoad() { + this.inputsChanged(); + } componentDidLoad() { this.ionAlertDidLoad.emit(); @@ -187,32 +217,23 @@ export class Alert implements OverlayInterface { return eventMethod(this.el, 'ionAlertWillDismiss', callback); } - private rbClick(inputIndex: number) { - this.inputs = this.inputs.map((input, index) => { - input.checked = (inputIndex === index); - return input; - }); - - const rbButton = this.inputs[inputIndex]; - this.activeId = rbButton.id; - - if (rbButton.handler) { - rbButton.handler(rbButton); + private rbClick(selectedInput: AlertInput) { + for (const input of this.processedInputs) { + input.checked = input === selectedInput; } + this.activeId = selectedInput.id; + if (selectedInput.handler) { + selectedInput.handler(selectedInput); + } + this.el.forceUpdate(); } - private cbClick(inputIndex: number) { - this.inputs = this.inputs.map((input, index) => { - if (inputIndex === index) { - input.checked = !input.checked; - } - return input; - }); - - const cbButton = this.inputs[inputIndex]; - if (cbButton.handler) { - cbButton.handler(cbButton); + private cbClick(selectedInput: AlertInput) { + selectedInput.checked = !selectedInput.checked; + if (selectedInput.handler) { + selectedInput.handler(selectedInput); } + this.el.forceUpdate(); } private buttonClick(button: AlertButton) { @@ -243,7 +264,7 @@ export class Alert implements OverlayInterface { if (this.inputType === 'radio') { // this is an alert with radio buttons (single value select) // return the one value which is checked, otherwise undefined - const checkedInput = this.inputs.find(i => i.checked === true); + const checkedInput = this.processedInputs.find(i => i.checked === true); console.debug('returning', checkedInput ? checkedInput.value : undefined); return checkedInput ? checkedInput.value : undefined; } @@ -251,11 +272,11 @@ export class Alert implements OverlayInterface { if (this.inputType === 'checkbox') { // this is an alert with checkboxes (multiple value select) // return an array of all the checked values - console.debug('returning', this.inputs.filter(i => i.checked).map(i => i.value)); - return this.inputs.filter(i => i.checked).map(i => i.value); + console.debug('returning', this.processedInputs.filter(i => i.checked).map(i => i.value)); + return this.processedInputs.filter(i => i.checked).map(i => i.value); } - if (this.inputs.length === 0) { + if (this.processedInputs.length === 0) { // this is an alert without any options/inputs at all console.debug('returning', 'undefined'); return undefined; @@ -264,7 +285,7 @@ export class Alert implements OverlayInterface { // this is an alert with text inputs // return an object of all the values with the input name as the key const values: {[k: string]: string} = {}; - this.inputs.forEach(i => { + this.processedInputs.forEach(i => { values[i.name] = i.value || ''; }); @@ -272,13 +293,23 @@ export class Alert implements OverlayInterface { return values; } - private renderCheckbox(inputs: AlertInput[]) { - if (inputs.length === 0) return null; + private renderAlertInputs(labelledBy: string | undefined) { + switch (this.inputType) { + case 'checkbox': return this.renderCheckbox(labelledBy); + case 'radio': return this.renderRadio(labelledBy); + default: return this.renderInput(labelledBy); + } + } + private renderCheckbox(labelledby: string | undefined) { + const inputs = this.processedInputs; + if (inputs.length === 0) { + return null; + } return ( -
- { inputs.map((i, index) => ( - )} diff --git a/core/src/components/alert/readme.md b/core/src/components/alert/readme.md index 091a6610a0..e7e1fb05f3 100644 --- a/core/src/components/alert/readme.md +++ b/core/src/components/alert/readme.md @@ -87,11 +87,6 @@ string The main message to be displayed in the alert. -#### mode - -string - - #### overlayId number @@ -182,11 +177,6 @@ string The main message to be displayed in the alert. -#### mode - -string - - #### overlay-id number diff --git a/core/src/components/anchor/anchor.tsx b/core/src/components/anchor/anchor.tsx index 72057379b6..9a38eda968 100644 --- a/core/src/components/anchor/anchor.tsx +++ b/core/src/components/anchor/anchor.tsx @@ -7,19 +7,19 @@ import { openURL } from '../../utils/theme'; }) export class Anchor { - @Prop({ context: 'window' }) win: Window; + @Prop({ context: 'window' }) win!: Window; /** * Contains a URL or a URL fragment that the hyperlink points to. * If this property is set, an anchor tag will be rendered. */ - @Prop() href: string; + @Prop() href?: string; /** * When using a router, it specifies the transition direction when navigating to * another page using `href`. */ - @Prop() routerDirection: 'forward' | 'back'; + @Prop() routerDirection?: 'forward' | 'back'; render() { return f()); export class Animator { - private _afterAddClasses: string[] | undefined; - private _afterRemoveClasses: string[] | undefined; - private _afterStyles: { [property: string]: any; } | undefined; - private _beforeAddClasses: string[] | undefined; - private _beforeRemoveClasses: string[] | undefined; - private _beforeStyles: { [property: string]: any; } | undefined; - private _childAnimations: Animator[] | undefined; - private _duration: number | undefined; - private _easingName: string | undefined; - private _elements: HTMLElement[] | undefined; - private _fxProperties: EffectProperty[] | undefined; + private _afterAddClasses?: string[]; + private _afterRemoveClasses?: string[]; + private _afterStyles?: { [property: string]: any; }; + private _beforeAddClasses?: string[]; + private _beforeRemoveClasses?: string[]; + private _beforeStyles?: { [property: string]: any; }; + private _childAnimations?: Animator[]; + private _duration?: number; + private _easingName?: string; + private _elements?: HTMLElement[]; + private _fxProperties?: EffectProperty[]; private _hasDur = false; private _hasTweenEffect = false; private _isAsync = false; private _isReverse = false; - private _onFinishCallbacks: Function[] | undefined; - private _onFinishOneTimeCallbacks: Function[] | undefined; - private _readCallbacks: Function[] | undefined; - private _reversedEasingName: string | undefined; - private _timerId: any | undefined; - private _unregisterTrnsEnd: Function | undefined; - private _writeCallbacks: Function[] | undefined; + private _onFinishCallbacks?: Function[]; + private _onFinishOneTimeCallbacks?: Function[]; + private _readCallbacks?: Function[]; + private _reversedEasingName?: string; + private _timerId?: any; + private _unregisterTrnsEnd?: Function; + private _writeCallbacks?: Function[]; private _destroyed = false; parent: Animator|undefined; diff --git a/core/src/components/app/app.tsx b/core/src/components/app/app.tsx index d1e76eb596..9d91872dbc 100644 --- a/core/src/components/app/app.tsx +++ b/core/src/components/app/app.tsx @@ -1,5 +1,5 @@ import { Component, Element, Prop } from '@stencil/core'; -import { Config } from '../../index'; +import { Config, Mode } from '../../index'; import { isDevice, isHybrid, needInputShims } from '../../utils/platform'; @Component({ @@ -14,12 +14,12 @@ import { isDevice, isHybrid, needInputShims } from '../../utils/platform'; }) export class App { - mode: string; + mode!: Mode; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ context: 'window' }) win: Window; - @Prop({ context: 'config' }) config: Config; + @Prop({ context: 'window' }) win!: Window; + @Prop({ context: 'config' }) config!: Config; hostData() { const hybrid = isHybrid(this.win); diff --git a/core/src/components/back-button/back-button.tsx b/core/src/components/back-button/back-button.tsx index 8dad4f61c9..83e9eef4f9 100644 --- a/core/src/components/back-button/back-button.tsx +++ b/core/src/components/back-button/back-button.tsx @@ -1,5 +1,5 @@ import { Component, Element, Prop } from '@stencil/core'; -import { Config } from '../../index'; +import { Config, Mode } from '../../index'; import { createThemedClasses, getElementClassMap, openURL } from '../../utils/theme'; @Component({ @@ -14,39 +14,39 @@ import { createThemedClasses, getElementClassMap, openURL } from '../../utils/th }) export class BackButton { - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ context: 'config' }) config: Config; - @Prop({ context: 'window' }) win: Window; + @Prop({ context: 'config' }) config!: Config; + @Prop({ context: 'window' }) win!: Window; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * The url to navigate back to by default when there is no history. */ - @Prop() defaultHref: string; + @Prop() defaultHref?: string; /** * The icon name to use for the back button. */ - @Prop() icon: string; + @Prop() icon?: string; /** * The text to display in the back button. */ - @Prop() text: string | undefined; + @Prop() text?: string; private onClick(ev: Event) { diff --git a/core/src/components/backdrop/backdrop.tsx b/core/src/components/backdrop/backdrop.tsx index 19e279b194..1b978277e9 100644 --- a/core/src/components/backdrop/backdrop.tsx +++ b/core/src/components/backdrop/backdrop.tsx @@ -15,7 +15,7 @@ export class Backdrop { private lastClick = -10000; - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; /** * If true, the backdrop will be visible. Defaults to `true`. @@ -35,7 +35,7 @@ export class Backdrop { /** * Emitted when the backdrop is tapped. */ - @Event() ionBackdropTap: EventEmitter; + @Event() ionBackdropTap!: EventEmitter; componentDidLoad() { registerBackdrop(this.doc, this); diff --git a/core/src/components/badge/badge.tsx b/core/src/components/badge/badge.tsx index 440780d320..7adbc66ba2 100644 --- a/core/src/components/badge/badge.tsx +++ b/core/src/components/badge/badge.tsx @@ -1,4 +1,5 @@ import { Component, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -18,13 +19,13 @@ export class Badge { * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; } diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx index 0f2764d099..068828fab4 100644 --- a/core/src/components/button/button.tsx +++ b/core/src/components/button/button.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core'; -import { CssClassMap } from '../../index'; +import { CssClassMap, Mode } from '../../index'; import { BlurEvent, FocusEvent } from '../../utils/input-interfaces'; import { getButtonClassMap, getElementClassMap, openURL } from '../../utils/theme'; @@ -12,26 +12,25 @@ import { getButtonClassMap, getElementClassMap, openURL } from '../../utils/them } }) export class Button { + @Element() el!: HTMLElement; - @Element() private el: HTMLElement; + @Prop({ context: 'window' }) win!: Window; - @Prop({ context: 'window' }) win: Window; - - @State() keyFocus: boolean; + @State() keyFocus = false; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * The type of button. @@ -48,7 +47,7 @@ export class Button { * Set to `"block"` for a full-width button or to `"full"` for a full-width button * without left and right borders. */ - @Prop() expand: 'full' | 'block'; + @Prop() expand?: 'full' | 'block'; /** * Set to `"clear"` for a transparent button, to `"outline"` for a transparent @@ -61,13 +60,13 @@ export class Button { * When using a router, it specifies the transition direction when navigating to * another page using `href`. */ - @Prop() routerDirection: 'forward' | 'back'; + @Prop() routerDirection?: 'forward' | 'back'; /** * Contains a URL or a URL fragment that the hyperlink points to. * If this property is set, an anchor tag will be rendered. */ - @Prop() href: string; + @Prop() href?: string; /** * If true, activates a button with rounded corners. @@ -78,7 +77,7 @@ export class Button { * The button size. * Possible values are: `"small"`, `"default"`, `"large"`. */ - @Prop() size: 'small' | 'default' | 'large'; + @Prop() size?: 'small' | 'default' | 'large'; /** * If true, activates a button with a heavier font weight. @@ -95,12 +94,12 @@ export class Button { /** * Emitted when the button has focus. */ - @Event() ionFocus: EventEmitter; + @Event() ionFocus!: EventEmitter; /** * Emitted when the button loses focus. */ - @Event() ionBlur: EventEmitter; + @Event() ionBlur!: EventEmitter; componentWillLoad() { if (this.el.closest('ion-buttons')) { @@ -129,8 +128,8 @@ export class Button { ...getButtonClassMap(buttonType, mode), ...getButtonTypeClassMap(buttonType, expand, mode), ...getButtonTypeClassMap(buttonType, size, mode), - ...getButtonTypeClassMap(buttonType, round ? 'round' : null, mode), - ...getButtonTypeClassMap(buttonType, strong ? 'strong' : null, mode), + ...getButtonTypeClassMap(buttonType, round ? 'round' : undefined, mode), + ...getButtonTypeClassMap(buttonType, strong ? 'strong' : undefined, mode), ...getColorClassMap(buttonType, color, fill, mode), ...getElementClassMap(this.el.classList), 'focused': this.keyFocus @@ -166,7 +165,7 @@ export class Button { * Get the classes based on the type * e.g. block, full, round, large */ -function getButtonTypeClassMap(buttonType: string, type: string|null, mode: string): CssClassMap { +function getButtonTypeClassMap(buttonType: string, type: string|undefined, mode: Mode): CssClassMap { if (!type) { return {}; } @@ -177,7 +176,7 @@ function getButtonTypeClassMap(buttonType: string, type: string|null, mode: stri }; } -function getColorClassMap(buttonType: string, color: string, fill: string, mode: string): CssClassMap { +function getColorClassMap(buttonType: string, color: string, fill: string, mode: Mode): CssClassMap { let className = buttonType; if (buttonType !== 'bar-button' && fill === 'solid') { diff --git a/core/src/components/card-content/card-content.tsx b/core/src/components/card-content/card-content.tsx index 2dc3cf9399..9b33dc2394 100644 --- a/core/src/components/card-content/card-content.tsx +++ b/core/src/components/card-content/card-content.tsx @@ -1,4 +1,5 @@ import { Component, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ tag: 'ion-card-content', @@ -15,12 +16,12 @@ export class CardContent { * The color to use for the text. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; } diff --git a/core/src/components/card-header/card-header.tsx b/core/src/components/card-header/card-header.tsx index 79e9971629..160e12de34 100644 --- a/core/src/components/card-header/card-header.tsx +++ b/core/src/components/card-header/card-header.tsx @@ -1,6 +1,7 @@ import { Component, Prop } from '@stencil/core'; import { createThemedClasses } from '../../utils/theme'; +import { Mode } from '../..'; @Component({ tag: 'ion-card-header', @@ -17,13 +18,13 @@ export class CardHeader { * The color to use for the background. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * If true, the card header will be translucent. Defaults to `false`. diff --git a/core/src/components/card-subtitle/card-subtitle.tsx b/core/src/components/card-subtitle/card-subtitle.tsx index a359f72035..41b2f2156c 100644 --- a/core/src/components/card-subtitle/card-subtitle.tsx +++ b/core/src/components/card-subtitle/card-subtitle.tsx @@ -1,4 +1,5 @@ import { Component, Prop} from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -16,13 +17,13 @@ export class CardSubtitle { * The color to use for the text color. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; hostData() { return { diff --git a/core/src/components/card-title/card-title.tsx b/core/src/components/card-title/card-title.tsx index 62e1d6895b..c26f5f5e55 100644 --- a/core/src/components/card-title/card-title.tsx +++ b/core/src/components/card-title/card-title.tsx @@ -1,4 +1,5 @@ import { Component, Prop} from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -17,13 +18,13 @@ export class CardTitle { * The color to use for the text color. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; hostData() { return { diff --git a/core/src/components/card/card.tsx b/core/src/components/card/card.tsx index aa9981e5df..5fa1263212 100644 --- a/core/src/components/card/card.tsx +++ b/core/src/components/card/card.tsx @@ -1,4 +1,5 @@ import { Component, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ tag: 'ion-card', @@ -16,12 +17,12 @@ export class Card { * The color to use for the background. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; } diff --git a/core/src/components/checkbox/checkbox.tsx b/core/src/components/checkbox/checkbox.tsx index 28bac33c3b..442928e05a 100644 --- a/core/src/components/checkbox/checkbox.tsx +++ b/core/src/components/checkbox/checkbox.tsx @@ -1,6 +1,6 @@ import { BlurEvent, CheckboxInput, CheckedInputChangeEvent, FocusEvent, StyleEvent } from '../../utils/input-interfaces'; -import { Component, Event, EventEmitter, Prop, State, Watch } from '@stencil/core'; -import { CssClassMap } from '../../index'; +import { Component, Element, Event, EventEmitter, Prop, State, Watch } from '@stencil/core'; +import { CssClassMap, Mode } from '../../index'; import { deferEvent } from '../../utils/helpers'; @@ -15,28 +15,30 @@ import { deferEvent } from '../../utils/helpers'; } }) export class Checkbox implements CheckboxInput { - private didLoad: boolean; - private inputId: string; - private nativeInput: HTMLInputElement; - @State() keyFocus: boolean; + private inputId = `ion-cb-${checkboxIds++}`; + private labelId = `${this.inputId}-lbl`; + + @Element() el!: HTMLElement; + + @State() keyFocus = false; /** * The color to use. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * The name of the control, which is submitted with the form data. */ - @Prop({ mutable: true }) name: string; + @Prop() name: string = this.inputId; /** * If true, the checkbox is selected. Defaults to `false`. @@ -56,53 +58,38 @@ export class Checkbox implements CheckboxInput { /** * Emitted when the checked property has changed. */ - @Event() ionChange: EventEmitter; + @Event() ionChange!: EventEmitter; /** * Emitted when the toggle has focus. */ - @Event() ionFocus: EventEmitter; + @Event() ionFocus!: EventEmitter; /** * Emitted when the toggle loses focus. */ - @Event() ionBlur: EventEmitter; + @Event() ionBlur!: EventEmitter; /** * Emitted when the styles change. */ - @Event() ionStyle: EventEmitter; + @Event() ionStyle!: EventEmitter; + componentWillLoad() { - this.inputId = `ion-cb-${checkboxIds++}`; - if (this.name === undefined) { - this.name = this.inputId; - } this.emitStyle(); } componentDidLoad() { this.ionStyle = deferEvent(this.ionStyle); - this.didLoad = true; - - const parentItem = this.nativeInput.closest('ion-item'); - if (parentItem) { - const itemLabel = parentItem.querySelector('ion-label'); - if (itemLabel) { - itemLabel.id = this.inputId + '-lbl'; - this.nativeInput.setAttribute('aria-labelledby', itemLabel.id); - } - } } @Watch('checked') checkedChanged(isChecked: boolean) { - if (this.didLoad) { - this.ionChange.emit({ - checked: isChecked, - value: this.value - }); - } + this.ionChange.emit({ + checked: isChecked, + value: this.value + }); this.emitStyle(); } @@ -153,16 +140,16 @@ export class Checkbox implements CheckboxInput {
, this.nativeInput = (r as any)}/> + disabled={this.disabled} /> ]; } } diff --git a/core/src/components/chip-button/chip-button.tsx b/core/src/components/chip-button/chip-button.tsx index 88846c8be8..a9faca1bfc 100644 --- a/core/src/components/chip-button/chip-button.tsx +++ b/core/src/components/chip-button/chip-button.tsx @@ -1,5 +1,5 @@ import { Component, Element, Prop } from '@stencil/core'; -import { CssClassMap } from '../../index'; +import { CssClassMap, Mode } from '../../index'; import { getButtonClassMap, getElementClassMap } from '../../utils/theme'; @Component({ @@ -10,19 +10,19 @@ import { getButtonClassMap, getElementClassMap } from '../../utils/theme'; }, }) export class ChipButton { - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; /** * The color to use. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * If true, the user cannot interact with the chip button. Defaults to `false`. @@ -32,13 +32,13 @@ export class ChipButton { /** * Set to `"clear"` for a transparent button style. */ - @Prop() fill: string; + @Prop() fill?: string; /** * Contains a URL or a URL fragment that the hyperlink points to. * If this property is set, an anchor tag will be rendered. */ - @Prop() href: string; + @Prop() href?: string; /** * Get the classes for the style @@ -77,7 +77,7 @@ export class ChipButton { /** * Get the classes for the color */ -function getColorClassMap(color: string, buttonType: string, style: string, mode: string): CssClassMap { +function getColorClassMap(color: string, buttonType: string, style: string, mode: Mode): CssClassMap { const className = (style === 'default') ? `${buttonType}` : `${buttonType}-${style}`; const map: CssClassMap = { diff --git a/core/src/components/chip/chip.tsx b/core/src/components/chip/chip.tsx index 04b2939e86..5f4b9e33ca 100644 --- a/core/src/components/chip/chip.tsx +++ b/core/src/components/chip/chip.tsx @@ -1,4 +1,5 @@ import { Component, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -16,12 +17,12 @@ export class Chip { * The color to use. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; } diff --git a/core/src/components/content/content.tsx b/core/src/components/content/content.tsx index d77fc0deb4..4e220a3ed4 100644 --- a/core/src/components/content/content.tsx +++ b/core/src/components/content/content.tsx @@ -1,5 +1,6 @@ import { Component, Element, Listen, Method, Prop } from '@stencil/core'; -import { Config, QueueController } from '../../index'; +import { Config, Mode, QueueController } from '../../index'; + @Component({ tag: 'ion-content', @@ -10,15 +11,15 @@ export class Content { private cTop = -1; private cBottom = -1; private dirty = false; - private scrollEl: HTMLIonScrollElement; + private scrollEl?: HTMLIonScrollElement; - mode: string; - color: string; + mode!: Mode; + color!: string; - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ context: 'config' }) config: Config; - @Prop({ context: 'queue' }) queue: QueueController; + @Prop({ context: 'config' }) config!: Config; + @Prop({ context: 'queue' }) queue!: QueueController; /** * If true, the content will scroll behind the headers @@ -32,7 +33,7 @@ export class Content { * If the content exceeds the bounds of ionContent, nothing will change. * Note, the does not disable the system bounce on iOS. That is an OS level setting. */ - @Prop() forceOverscroll: boolean; + @Prop() forceOverscroll?: boolean; @Prop() scrollEnabled = true; diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx index 1f0b646624..4af8cdf108 100644 --- a/core/src/components/datetime/datetime.tsx +++ b/core/src/components/datetime/datetime.tsx @@ -18,8 +18,9 @@ import { renderTextFormat, updateDate } from './datetime-util'; -import { clamp } from '../../utils/helpers'; -import { Picker, PickerColumn, PickerController, PickerOptions } from '../../index'; + +import { clamp, deferEvent } from '../../utils/helpers'; +import { PickerColumn, PickerController, PickerOptions } from '../../index'; @Component({ @@ -35,9 +36,10 @@ import { Picker, PickerColumn, PickerController, PickerOptions } from '../../ind export class Datetime { [key: string]: any; - private datetimeId: string; - private labelId: string; - private picker: Picker; + private inputId = `ion-dt-${datetimeIds++}`; + private labelId = `${this.inputId}-lbl`; + + private picker?: HTMLIonPickerElement; locale: LocaleData = {}; datetimeMin: DatetimeData = {}; @@ -46,7 +48,7 @@ export class Datetime { @State() text: any; - @Prop({ connect: 'ion-picker-controller' }) pickerCtrl: PickerController; + @Prop({ connect: 'ion-picker-controller' }) pickerCtrl!: PickerController; /** * If true, the user cannot interact with the datetime. Defaults to `false`. @@ -95,7 +97,7 @@ export class Datetime { * choose an exact date from the datetime picker. Each column follows the string * parse format. Defaults to use `displayFormat`. */ - @Prop() pickerFormat: string | undefined; + @Prop() pickerFormat?: string; /** * The text to display on the picker's cancel button. Default: `Cancel`. @@ -114,7 +116,7 @@ export class Datetime { * of numbers, or string of comma separated numbers. For example, to show upcoming and * recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`. */ - @Prop() yearValues: number[] | number | string | undefined; + @Prop() yearValues?: number[] | number | string; /** * Values used to create the list of selectable months. By default @@ -124,7 +126,7 @@ export class Datetime { * input value would be `monthValues="6,7,8"`. Note that month numbers do *not* have a * zero-based index, meaning January's value is `1`, and December's is `12`. */ - @Prop() monthValues: number[] | number | string | undefined; + @Prop() monthValues?: number[] | number | string; /** * Values used to create the list of selectable days. By default @@ -134,7 +136,7 @@ export class Datetime { * number for the selected month, like `31` in February, it will correctly not show * days which are not valid for the selected month. */ - @Prop() dayValues: number[] | number | string | undefined; + @Prop() dayValues?: number[] | number | string; /** * Values used to create the list of selectable hours. By default @@ -142,7 +144,7 @@ export class Datetime { * to control exactly which hours to display, the `hourValues` input can take a number, an * array of numbers, or a string of comma separated numbers. */ - @Prop() hourValues: number[] | number | string | undefined; + @Prop() hourValues?: number[] | number | string; /** * Values used to create the list of selectable minutes. By default @@ -151,31 +153,31 @@ export class Datetime { * separated numbers. For example, if the minute selections should only be every 15 minutes, * then this input value would be `minuteValues="0,15,30,45"`. */ - @Prop() minuteValues: number[] | number | string | undefined; + @Prop() minuteValues?: number[] | number | string; /** * Full names for each month name. This can be used to provide * locale month names. Defaults to English. */ - @Prop() monthNames: string[] | string | undefined; + @Prop() monthNames?: string[] | string; /** * Short abbreviated names for each month name. This can be used to provide * locale month names. Defaults to English. */ - @Prop() monthShortNames: string[] | string | undefined; + @Prop() monthShortNames?: string[] | string; /** * Full day of the week names. This can be used to provide * locale names for each day in the week. Defaults to English. */ - @Prop() dayNames: string[] | string | undefined; + @Prop() dayNames?: string[] | string; /** * Short abbreviated day of the week names. This can be used to provide * locale names for each day in the week. Defaults to English. */ - @Prop() dayShortNames: string[] | string | undefined; + @Prop() dayShortNames?: string[] | string; /** * Any additional options that the picker interface can accept. @@ -190,12 +192,12 @@ export class Datetime { * The text to display when there's no date selected yet. * Using lowercase to match the input attribute */ - @Prop() placeholder: string | undefined; + @Prop() placeholder?: string; /** * the value of the datetime. */ - @Prop({ mutable: true }) value: string; + @Prop({ mutable: true }) value?: string; /** * Update the datetime value when the value changes @@ -209,18 +211,19 @@ export class Datetime { /** * Emitted when the datetime selection was cancelled. */ - @Event() ionCancel: EventEmitter; + @Event() ionCancel!: EventEmitter; /** * Emitted when the styles change. */ - @Event() ionStyle: EventEmitter; + @Event() ionStyle!: EventEmitter; componentWillLoad() { // first see if locale names were provided in the inputs // then check to see if they're in the config // if neither were provided then it will use default English names + this.ionStyle = deferEvent(this.ionStyle); this.locale = { // this.locale[type] = convertToArrayOfStrings((this[type] ? this[type] : this.config.get(type), type); monthNames: convertToArrayOfStrings(this.monthNames, 'monthNames'), @@ -237,14 +240,10 @@ export class Datetime { } private emitStyle() { - clearTimeout(this.styleTmr); - - this.styleTmr = setTimeout(() => { - this.ionStyle.emit({ - 'datetime': true, - 'datetime-disabled': this.disabled, - 'input-has-value': this.hasValue() - }); + this.ionStyle.emit({ + 'datetime': true, + 'datetime-disabled': this.disabled, + 'input-has-value': this.hasValue() }); } @@ -289,26 +288,15 @@ export class Datetime { return picker; } - private open() { - const pickerOptions = {...this.pickerOptions}; - + private async open() { // TODO check this.isFocus() || this.disabled if (this.disabled) { return; } - - let controller: Promise; - - controller = this.buildPicker(pickerOptions); - - controller.then((component: any) => { - // Update picker status before presenting - this.picker = component; - - this.validate(); - - component.present(); - }); + const pickerOptions = {...this.pickerOptions}; + this.picker = await this.buildPicker(pickerOptions); + this.validate(); + await this.picker.present(); } private generateColumns(): PickerColumn[] { @@ -390,7 +378,7 @@ export class Datetime { const today = new Date(); const minCompareVal = dateDataSortValue(this.datetimeMin); const maxCompareVal = dateDataSortValue(this.datetimeMax); - const yearCol = this.picker.getColumn('year'); + const yearCol = this.picker!.getColumn('year'); let selectedYear: number = today.getFullYear(); if (yearCol) { @@ -492,7 +480,7 @@ export class Datetime { } private validateColumn(name: string, index: number, min: number, max: number, lowerBounds: number[], upperBounds: number[]): number { - const column = this.picker.getColumn(name); + const column = this.picker!.getColumn(name); if (!column) { return 0; } @@ -624,4 +612,6 @@ export class Datetime { } } +let datetimeIds = 0; + const DEFAULT_FORMAT = 'MMM D, YYYY'; diff --git a/core/src/components/fab-button/fab-button.tsx b/core/src/components/fab-button/fab-button.tsx index d3cc647820..0fdaa026c0 100755 --- a/core/src/components/fab-button/fab-button.tsx +++ b/core/src/components/fab-button/fab-button.tsx @@ -1,6 +1,6 @@ import { Component, Element, Prop } from '@stencil/core'; import { createThemedClasses, getElementClassMap } from '../../utils/theme'; -import { CssClassMap } from '../../index'; +import { CssClassMap, Mode } from '../../index'; @Component({ @@ -14,21 +14,21 @@ export class FabButton { private inList = false; - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * If true, the fab button will be show a close icon. Defaults to `false`. @@ -44,7 +44,7 @@ export class FabButton { * Contains a URL or a URL fragment that the hyperlink points to. * If this property is set, an anchor tag will be rendered. */ - @Prop() href: string | undefined; + @Prop() href?: string; /** * If true, the fab button will be translucent. Defaults to `false`. diff --git a/core/src/components/fab-list/fab-list.tsx b/core/src/components/fab-list/fab-list.tsx index 4eb0e102b3..989435ffe4 100644 --- a/core/src/components/fab-list/fab-list.tsx +++ b/core/src/components/fab-list/fab-list.tsx @@ -6,7 +6,7 @@ import { Component, Element, Prop, Watch } from '@stencil/core'; styleUrl: 'fab-list.scss' }) export class FabList { - @Element() private el: HTMLIonFabElement; + @Element() el!: HTMLIonFabElement; /** * If true, the fab list will be show all fab buttons in the list. Defaults to `false`. diff --git a/core/src/components/fab/fab.tsx b/core/src/components/fab/fab.tsx index 3752275518..2bcc01278e 100644 --- a/core/src/components/fab/fab.tsx +++ b/core/src/components/fab/fab.tsx @@ -7,19 +7,19 @@ import { Component, Element, Listen, Method, Prop, Watch } from '@stencil/core'; }) export class Fab { - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; /** * Where to align the fab horizontally in the viewport. * Possible values are: `"center"`, `"start"`, `"end"`. */ - @Prop() horizontal: 'start' | 'end' | 'center'; + @Prop() horizontal?: 'start' | 'end' | 'center'; /** * Where to align the fab vertically in the viewport. * Possible values are: `"top"`, `"center"`, `"bottom"`. */ - @Prop() vertical: 'top' | 'bottom' | 'center'; + @Prop() vertical?: 'top' | 'bottom' | 'center'; /** * If true, the fab will display on the edge of the header if diff --git a/core/src/components/footer/footer.tsx b/core/src/components/footer/footer.tsx index 5eb3617f4d..a9a20323bc 100644 --- a/core/src/components/footer/footer.tsx +++ b/core/src/components/footer/footer.tsx @@ -1,6 +1,7 @@ import { Component, Prop } from '@stencil/core'; import { createThemedClasses } from '../../utils/theme'; +import { Mode } from '../..'; @Component({ tag: 'ion-footer', @@ -13,8 +14,8 @@ import { createThemedClasses } from '../../utils/theme'; } }) export class Footer { - mode: string; - color: string; + mode!: Mode; + color!: string; /** * If true, the footer will be translucent. diff --git a/core/src/components/gesture-controller/gesture-controller.tsx b/core/src/components/gesture-controller/gesture-controller.tsx index 1af506911c..a69df4407c 100644 --- a/core/src/components/gesture-controller/gesture-controller.tsx +++ b/core/src/components/gesture-controller/gesture-controller.tsx @@ -13,7 +13,7 @@ export class GestureController { private disabledScroll = new Set(); private capturedId: number|null = null; - @Event() ionGestureCaptured: EventEmitter; + @Event() ionGestureCaptured!: EventEmitter; @Method() create(config: GestureConfig): Promise { diff --git a/core/src/components/gesture/gesture.tsx b/core/src/components/gesture/gesture.tsx index a323a16a1f..e9d117442e 100644 --- a/core/src/components/gesture/gesture.tsx +++ b/core/src/components/gesture/gesture.tsx @@ -16,19 +16,19 @@ export class Gesture { private detail: GestureDetail; private positions: number[] = []; - private gesture: GestureDelegate; + private gesture!: GestureDelegate; private lastTouch = 0; - private pan: PanRecognizer; + private pan?: PanRecognizer; // TODO private hasCapturedPan = false; private hasPress = false; private hasStartedPan = false; private hasFiredStart = true; private isMoveQueued = false; - private blocker: BlockerDelegate|undefined; + private blocker?: BlockerDelegate; - @Prop({ connect: 'ion-gesture-controller' }) gestureCtrl: HTMLIonGestureControllerElement; - @Prop({ context: 'queue' }) queue: QueueController; - @Prop({ context: 'enableListener' }) enableListener: EventListenerEnable; + @Prop({ connect: 'ion-gesture-controller' }) gestureCtrl!: HTMLIonGestureControllerElement; + @Prop({ context: 'queue' }) queue!: QueueController; + @Prop({ context: 'enableListener' }) enableListener!: EventListenerEnable; @Prop() disabled = false; @Prop() attachTo: string|HTMLElement = 'child'; @@ -42,38 +42,38 @@ export class Gesture { @Prop() threshold = 10; @Prop() type = 'pan'; - @Prop() canStart: GestureCallback; - @Prop() onWillStart: (_: GestureDetail) => Promise; - @Prop() onStart: GestureCallback; - @Prop() onMove: GestureCallback; - @Prop() onEnd: GestureCallback; - @Prop() onPress: GestureCallback; - @Prop() notCaptured: GestureCallback; + @Prop() canStart?: GestureCallback; + @Prop() onWillStart?: (_: GestureDetail) => Promise; + @Prop() onStart?: GestureCallback; + @Prop() onMove?: GestureCallback; + @Prop() onEnd?: GestureCallback; + @Prop() onPress?: GestureCallback; + @Prop() notCaptured?: GestureCallback; /** * Emitted when the gesture moves. */ - @Event() ionGestureMove: EventEmitter; + @Event() ionGestureMove!: EventEmitter; /** * Emitted when the gesture starts. */ - @Event() ionGestureStart: EventEmitter; + @Event() ionGestureStart!: EventEmitter; /** * Emitted when the gesture ends. */ - @Event() ionGestureEnd: EventEmitter; + @Event() ionGestureEnd!: EventEmitter; /** * Emitted when the gesture is not captured. */ - @Event() ionGestureNotCaptured: EventEmitter; + @Event() ionGestureNotCaptured!: EventEmitter; /** * Emitted when press is detected. */ - @Event() ionPress: EventEmitter; + @Event() ionPress!: EventEmitter; constructor() { this.detail = { @@ -224,7 +224,10 @@ export class Gesture { } private pointerMove(ev: UIEvent) { - assert(!!this.pan, 'pan must be non null'); + if (!this.pan) { + assert(false, 'pan must be non null'); + return; + } // fast path, if gesture is currently captured // do minimun job to get user-land even dispatched diff --git a/core/src/components/gesture/recognizers.ts b/core/src/components/gesture/recognizers.ts index 9b7622fafb..69f3d77cdd 100644 --- a/core/src/components/gesture/recognizers.ts +++ b/core/src/components/gesture/recognizers.ts @@ -1,7 +1,8 @@ export class PanRecognizer { - private startX: number; - private startY: number; + + private startX!: number; + private startY!: number; private dirty = false; private threshold: number; diff --git a/core/src/components/header/header.tsx b/core/src/components/header/header.tsx index e8708cb8d0..d73a4b2660 100644 --- a/core/src/components/header/header.tsx +++ b/core/src/components/header/header.tsx @@ -1,6 +1,7 @@ import { Component, Prop } from '@stencil/core'; import { createThemedClasses } from '../../utils/theme'; +import { Mode } from '../..'; @Component({ tag: 'ion-header', @@ -13,8 +14,8 @@ import { createThemedClasses } from '../../utils/theme'; } }) export class Header { - mode: string; - color: string; + mode!: Mode; + color!: string; /** * If true, the header will be translucent. diff --git a/core/src/components/hide-when/hide-when.tsx b/core/src/components/hide-when/hide-when.tsx index 603a370ede..68662fba3c 100644 --- a/core/src/components/hide-when/hide-when.tsx +++ b/core/src/components/hide-when/hide-when.tsx @@ -1,5 +1,5 @@ import { Component, Element, Listen, Prop, State } from '@stencil/core'; -import { Config } from '../../index'; +import { Config, Mode } from '../../index'; import { DisplayWhen, PLATFORM_CONFIGS, PlatformConfig, detectPlatforms, updateTestResults, @@ -11,17 +11,17 @@ import { }) export class HideWhen implements DisplayWhen { - calculatedPlatforms: PlatformConfig[]; + mode!: Mode; + calculatedPlatforms!: PlatformConfig[]; - @Element() element: HTMLElement; - @Prop({ context: 'config' }) config: Config; - @Prop({ context: 'window' }) win: Window; + @Element() element!: HTMLElement; + @Prop({ context: 'config' }) config!: Config; + @Prop({ context: 'window' }) win!: Window; - @Prop() orientation: string; - @Prop() mediaQuery: string; - @Prop() size: string; - @Prop() mode: string; - @Prop() platform: string; + @Prop() orientation?: string; + @Prop() mediaQuery?: string; + @Prop() size?: string; + @Prop() platform?: string; @Prop() or = false; @State() passesTest = false; diff --git a/core/src/components/hide-when/readme.md b/core/src/components/hide-when/readme.md index 0ef88127fa..f4c7a8782f 100644 --- a/core/src/components/hide-when/readme.md +++ b/core/src/components/hide-when/readme.md @@ -12,11 +12,6 @@ string -#### mode - -string - - #### or boolean @@ -44,11 +39,6 @@ string string -#### mode - -string - - #### or boolean diff --git a/core/src/components/infinite-scroll-content/infinite-scroll-content.tsx b/core/src/components/infinite-scroll-content/infinite-scroll-content.tsx index ec4d879ec3..cac7faa416 100644 --- a/core/src/components/infinite-scroll-content/infinite-scroll-content.tsx +++ b/core/src/components/infinite-scroll-content/infinite-scroll-content.tsx @@ -14,17 +14,17 @@ import { Config } from '../../index'; }) export class InfiniteScrollContent { - @Prop({ context: 'config' }) config: Config; + @Prop({ context: 'config' }) config!: Config; /** * An animated SVG spinner that shows while loading. */ - @Prop({ mutable: true }) loadingSpinner: string; + @Prop({ mutable: true }) loadingSpinner?: string; /** * Optional text to display while loading. */ - @Prop() loadingText: string; + @Prop() loadingText?: string; componentDidLoad() { diff --git a/core/src/components/infinite-scroll/infinite-scroll.tsx b/core/src/components/infinite-scroll/infinite-scroll.tsx index cb4eabd89f..86e09e2c86 100644 --- a/core/src/components/infinite-scroll/infinite-scroll.tsx +++ b/core/src/components/infinite-scroll/infinite-scroll.tsx @@ -19,11 +19,11 @@ export class InfiniteScroll { private didFire = false; private isBusy = false; - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; @State() isLoading = false; - @Prop({ context: 'queue' }) queue: QueueController; - @Prop({ context: 'enableListener' }) enableListener: EventListenerEnable; + @Prop({ context: 'queue' }) queue!: QueueController; + @Prop({ context: 'enableListener' }) enableListener!: EventListenerEnable; /** * The threshold distance from the bottom @@ -79,7 +79,7 @@ export class InfiniteScroll { * you must call the infinite scroll's `complete()` method when * your async operation has completed. */ - @Event() ionInfinite: EventEmitter; + @Event() ionInfinite!: EventEmitter; async componentWillLoad() { const scrollEl = this.el.closest('ion-scroll'); diff --git a/core/src/components/input-shims/input-shims.tsx b/core/src/components/input-shims/input-shims.tsx index 7949cb27d9..22f0175107 100644 --- a/core/src/components/input-shims/input-shims.tsx +++ b/core/src/components/input-shims/input-shims.tsx @@ -23,8 +23,8 @@ export class InputShims { private hideCaretMap = new WeakMap(); private scrollAssistMap = new WeakMap(); - @Prop({ context: 'config' }) config: Config; - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'config' }) config!: Config; + @Prop({ context: 'document' }) doc!: Document; componentDidLoad() { this.keyboardHeight = this.config.getNumber('keyboardHeight', 290); diff --git a/core/src/components/input/input-base.tsx b/core/src/components/input/input-base.tsx index 46ca3c2355..01410f539b 100644 --- a/core/src/components/input/input-base.tsx +++ b/core/src/components/input/input-base.tsx @@ -9,49 +9,43 @@ export interface InputBaseComponent { clearOnEdit: boolean; didBlurAfterEdit: boolean; - styleTmr: number; + styleTmr?: number; // Shared Attributes - autocapitalize: string; - autocomplete: string; - autofocus: boolean; - disabled: boolean; - minlength: number; - maxlength: number; - name: string; - placeholder: string; - readonly: boolean; - required: boolean; - spellcheck: boolean; - value: string; - - // Shared Methods - inputBlurred: (ev: Event) => void; - inputChanged: (ev: Event) => void; - inputFocused: (ev: Event) => void; - inputKeydown: (ev: Event) => void; + autocapitalize?: string; + autocomplete?: string; + autofocus?: boolean; + disabled?: boolean; + minlength?: number; + maxlength?: number; + name?: string; + placeholder?: string; + readonly?: boolean; + required?: boolean; + spellcheck?: boolean; + value?: string; } export interface InputComponent extends InputBaseComponent { clearInput: boolean; // Input Attributes - accept: string; - autocorrect: string; - min: string; - max: string; - multiple: boolean; - pattern: string; - results: number; - step: string; - size: number; - type: string; + accept?: string; + autocorrect?: string; + min?: string; + max?: string; + multiple?: boolean; + pattern?: string; + results?: number; + step?: string; + size?: number; + type?: string; } export interface TextareaComponent extends InputBaseComponent { // Textarea Attributes - cols: number; - rows: number; - wrap: string; + cols?: number; + rows?: number; + wrap?: string; } diff --git a/core/src/components/input/input.tsx b/core/src/components/input/input.tsx index 5511555b74..ae6636ae06 100644 --- a/core/src/components/input/input.tsx +++ b/core/src/components/input/input.tsx @@ -1,8 +1,9 @@ import { Component, Element, Event, EventEmitter, Prop, Watch } from '@stencil/core'; -import { debounceEvent } from '../../utils/helpers'; +import { debounceEvent, deferEvent } from '../../utils/helpers'; import { createThemedClasses } from '../../utils/theme'; import { InputComponent } from './input-base'; +import { Mode } from '../..'; @Component({ @@ -17,49 +18,48 @@ import { InputComponent } from './input-base'; }) export class Input implements InputComponent { + mode!: Mode; + color!: string; + private nativeInput: HTMLInputElement|undefined; - mode: string; - color: string; + didBlurAfterEdit = false; - didBlurAfterEdit: boolean; - styleTmr: number; - - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; /** * Emitted when the input value has changed. */ - @Event() ionInput: EventEmitter; + @Event() ionInput!: EventEmitter; /** * Emitted when the styles change. */ - @Event() ionStyle: EventEmitter; + @Event() ionStyle!: EventEmitter; /** * Emitted when the input loses focus. */ - @Event() ionBlur: EventEmitter; + @Event() ionBlur!: EventEmitter; /** * Emitted when the input has focus. */ - @Event() ionFocus: EventEmitter; + @Event() ionFocus!: EventEmitter; /** * Emitted when the input has been created. */ - @Event() ionInputDidLoad: EventEmitter; + @Event() ionInputDidLoad!: EventEmitter; /** * Emitted when the input has been removed. */ - @Event() ionInputDidUnload: EventEmitter; + @Event() ionInputDidUnload!: EventEmitter; /** * If the value of the type attribute is `"file"`, then this attribute will indicate the types of files that the server accepts, otherwise it will be ignored. The value must be a comma-separated list of unique content type specifiers. */ - @Prop() accept: string; + @Prop() accept?: string; /** * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Defaults to `"none"`. @@ -99,7 +99,7 @@ export class Input implements InputComponent { /** * If true, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types. */ - @Prop({ mutable: true }) clearOnEdit: boolean; + @Prop({ mutable: true }) clearOnEdit!: boolean; /** * Set the amount of time, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. Default `0`. @@ -124,47 +124,47 @@ export class Input implements InputComponent { /** * A hint to the browser for which keyboard to display. This attribute applies when the value of the type attribute is `"text"`, `"password"`, `"email"`, or `"url"`. Possible values are: `"verbatim"`, `"latin"`, `"latin-name"`, `"latin-prose"`, `"full-width-latin"`, `"kana"`, `"katakana"`, `"numeric"`, `"tel"`, `"email"`, `"url"`. */ - @Prop() inputmode: string; + @Prop() inputmode?: string; /** * The maximum value, which must not be less than its minimum (min attribute) value. */ - @Prop() max: string; + @Prop() max?: string; /** * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the maximum number of characters that the user can enter. */ - @Prop() maxlength: number; + @Prop() maxlength?: number; /** * The minimum value, which must not be greater than its maximum (max attribute) value. */ - @Prop() min: string; + @Prop() min?: string; /** * If the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, this attribute specifies the minimum number of characters that the user can enter. */ - @Prop() minlength: number; + @Prop() minlength?: number; /** * If true, the user can enter more than one value. This attribute applies when the type attribute is set to `"email"` or `"file"`, otherwise it is ignored. */ - @Prop() multiple: boolean; + @Prop() multiple?: boolean; /** * The name of the control, which is submitted with the form data. */ - @Prop() name: string; + @Prop() name?: string; /** * A regular expression that the value is checked against. The pattern must match the entire value, not just some subset. Use the title attribute to describe the pattern to help the user. This attribute applies when the value of the type attribute is `"text"`, `"search"`, `"tel"`, `"url"`, `"email"`, or `"password"`, otherwise it is ignored. */ - @Prop() pattern: string; + @Prop() pattern?: string; /** * Instructional text that shows before the input has a value. */ - @Prop() placeholder: string; + @Prop() placeholder?: string; /** * If true, the user cannot modify the value. Defaults to `false`. @@ -179,7 +179,7 @@ export class Input implements InputComponent { /** * This is a nonstandard attribute supported by Safari that only applies when the type is `"search"`. Its value should be a nonnegative decimal integer. */ - @Prop() results: number; + @Prop() results?: number; /** * If true, the element will have its spelling and grammar checked. Defaults to `false`. @@ -189,12 +189,12 @@ export class Input implements InputComponent { /** * Works with the min and max attributes to limit the increments at which a value can be set. Possible values are: `"any"` or a positive floating point number. */ - @Prop() step: string; + @Prop() step?: string; /** * The initial size of the control. This value is in pixels unless the value of the type attribute is `"text"` or `"password"`, in which case it is an integer number of characters. This attribute applies only when the `type` attribute is set to `"text"`, `"search"`, `"tel"`, `"url"`, `"email"`, or `"password"`, otherwise it is ignored. */ - @Prop() size: number; + @Prop() size?: number; /** * The type of control to display. The default type is text. Possible values are: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, or `"url"`. @@ -204,7 +204,7 @@ export class Input implements InputComponent { /** * The value of the input. */ - @Prop({ mutable: true }) value: string; + @Prop({ mutable: true }) value = ''; /** @@ -218,14 +218,18 @@ export class Input implements InputComponent { } } + componentWillLoad() { + // By default, password inputs clear after focus when they have content + if (this.clearOnEdit === undefined && this.type === 'password') { + this.clearOnEdit = true; + } + } + componentDidLoad() { + this.ionStyle = deferEvent(this.ionStyle); this.debounceChanged(); this.emitStyle(); - // By default, password inputs clear after focus when they have content - if (this.type === 'password' && this.clearOnEdit !== false) { - this.clearOnEdit = true; - } this.ionInputDidLoad.emit(this.el); } @@ -235,56 +239,50 @@ export class Input implements InputComponent { } private emitStyle() { - clearTimeout(this.styleTmr); - - const styles = { + this.ionStyle.emit({ 'input': true, 'input-checked': this.checked, 'input-disabled': this.disabled, 'input-has-value': this.hasValue(), 'input-has-focus': this.hasFocus() - }; - - this.styleTmr = setTimeout(() => { - this.ionStyle.emit(styles); }); } - inputBlurred(ev: Event) { + private inputBlurred(ev: Event) { this.ionBlur.emit(ev); this.focusChange(this.hasFocus()); this.emitStyle(); } - inputChanged(ev: Event) { + private inputChanged(ev: Event) { this.value = ev.target && (ev.target as HTMLInputElement).value || ''; this.ionInput.emit(ev); this.emitStyle(); } - inputFocused(ev: Event) { + private inputFocused(ev: Event) { this.ionFocus.emit(ev); this.focusChange(this.hasFocus()); this.emitStyle(); } - focusChange(inputHasFocus: boolean) { + private focusChange(inputHasFocus: boolean) { // If clearOnEdit is enabled and the input blurred but has a value, set a flag if (this.clearOnEdit && !inputHasFocus && this.hasValue()) { this.didBlurAfterEdit = true; } } - inputKeydown(ev: Event) { + private inputKeydown(ev: Event) { this.checkClearOnEdit(ev); } /** * Check if we need to clear the text input if clearOnEdit is enabled */ - checkClearOnEdit(ev: Event) { + private checkClearOnEdit(ev: Event) { if (!this.clearOnEdit) { return; } @@ -299,17 +297,17 @@ export class Input implements InputComponent { this.didBlurAfterEdit = false; } - clearTextInput(ev: Event) { + private clearTextInput(ev: Event) { this.value = ''; this.ionInput.emit(ev); } - hasFocus(): boolean { + private hasFocus(): boolean { // check if an input has focus or not return this.nativeInput === document.activeElement; } - hasValue(): boolean { + private hasValue(): boolean { return (this.value !== null && this.value !== undefined && this.value !== ''); } diff --git a/core/src/components/item-divider/item-divider.tsx b/core/src/components/item-divider/item-divider.tsx index 4472b82096..2f61085554 100644 --- a/core/src/components/item-divider/item-divider.tsx +++ b/core/src/components/item-divider/item-divider.tsx @@ -1,4 +1,5 @@ import { Component, Element, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -12,21 +13,21 @@ import { Component, Element, Prop } from '@stencil/core'; } }) export class ItemDivider { - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; componentDidLoad() { // Change the button size to small for each ion-button in the item diff --git a/core/src/components/item-option/item-option.tsx b/core/src/components/item-option/item-option.tsx index 89d2c0175c..7c95b54468 100644 --- a/core/src/components/item-option/item-option.tsx +++ b/core/src/components/item-option/item-option.tsx @@ -1,4 +1,5 @@ import { Component, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -17,14 +18,14 @@ export class ItemOption { * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * If true, the user cannot interact with the item option. Defaults to `false`. @@ -40,7 +41,7 @@ export class ItemOption { * Contains a URL or a URL fragment that the hyperlink points to. * If this property is set, an anchor tag will be rendered. */ - @Prop() href: string; + @Prop() href?: string; private clickedOptionButton(ev: Event): boolean { const el = (ev.target as HTMLElement).closest('ion-item-option'); diff --git a/core/src/components/item-options/item-options.tsx b/core/src/components/item-options/item-options.tsx index acb7847069..2608edc831 100644 --- a/core/src/components/item-options/item-options.tsx +++ b/core/src/components/item-options/item-options.tsx @@ -10,9 +10,9 @@ import { Side, isRightSide } from '../../utils/helpers'; } }) export class ItemOptions { - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ context: 'window' }) win: Window; + @Prop({ context: 'window' }) win!: Window; /** * The side the option button should be on. @@ -25,7 +25,7 @@ export class ItemOptions { /** * Emitted when the item has been fully swiped. */ - @Event() ionSwipe: EventEmitter; + @Event() ionSwipe!: EventEmitter; @Method() isRightSide() { diff --git a/core/src/components/item-sliding/item-sliding.tsx b/core/src/components/item-sliding/item-sliding.tsx index cdb8f8f679..c04c91fdec 100644 --- a/core/src/components/item-sliding/item-sliding.tsx +++ b/core/src/components/item-sliding/item-sliding.tsx @@ -37,20 +37,20 @@ export class ItemSliding { private initialOpenAmount = 0; private optsWidthRightSide = 0; private optsWidthLeftSide = 0; - private sides: ItemSide; + private sides = ItemSide.None; private tmr: number|undefined; private leftOptions: HTMLIonItemOptionsElement|undefined; private rightOptions: HTMLIonItemOptionsElement|undefined; private optsDirty = true; - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; @State() state: SlidingState = SlidingState.Disabled; /** * Emitted when the sliding position changes. */ - @Event() ionDrag: EventEmitter; + @Event() ionDrag!: EventEmitter; componentDidLoad() { this.item = this.el.querySelector('ion-item'); @@ -249,7 +249,7 @@ export class ItemSliding { this.state = SlidingState.Disabled; this.tmr = undefined; }, 600); - this.list && this.list.setOpenItem(null); + this.list && this.list.setOpenItem(undefined); style.transform = ''; return; } diff --git a/core/src/components/item/item.tsx b/core/src/components/item/item.tsx index 4d45257a1c..16117b74c1 100644 --- a/core/src/components/item/item.tsx +++ b/core/src/components/item/item.tsx @@ -1,6 +1,6 @@ import { Component, Element, Listen, Prop } from '@stencil/core'; import { createThemedClasses, getElementClassMap, openURL } from '../../utils/theme'; -import { CssClassMap } from '../../index'; +import { CssClassMap, Mode } from '../../index'; @Component({ @@ -14,23 +14,23 @@ export class Item { private itemStyles: { [key: string]: CssClassMap } = {}; - @Element() private el: HTMLStencilElement; + @Element() el!: HTMLStencilElement; - @Prop({ context: 'window' }) win: Window; + @Prop({ context: 'window' }) win!: Window; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * If true, a button tag will be rendered and the item will be tappable. Defaults to `false`. @@ -41,7 +41,7 @@ export class Item { * If true, a detail arrow will appear on the item. Defaults to `false` unless the `mode` * is `ios` and an `href`, `onclick` or `button` property is present. */ - @Prop() detail: boolean; + @Prop() detail?: boolean; /** * If true, the user cannot interact with the item. Defaults to `false`. @@ -52,13 +52,13 @@ export class Item { * Contains a URL or a URL fragment that the hyperlink points to. * If this property is set, an anchor tag will be rendered. */ - @Prop() href: string; + @Prop() href?: string; /** * When using a router, it specifies the transition direction when navigating to * another page using `href`. */ - @Prop() routerDirection: 'forward' | 'back'; + @Prop() routerDirection?: 'forward' | 'back'; @Listen('ionStyle') diff --git a/core/src/components/label/label.tsx b/core/src/components/label/label.tsx index a85f24ef73..08f7234ec9 100644 --- a/core/src/components/label/label.tsx +++ b/core/src/components/label/label.tsx @@ -1,4 +1,6 @@ import { Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core'; +import { Mode } from '../..'; + @Component({ tag: 'ion-label', @@ -12,21 +14,21 @@ import { Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@s }) export class Label { - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * The position determines where and how the label behaves inside an item. @@ -37,7 +39,7 @@ export class Label { /** * Emitted when the styles change. */ - @Event() ionStyle: EventEmitter; + @Event() ionStyle!: EventEmitter; @Method() getText(): string { diff --git a/core/src/components/list-header/list-header.tsx b/core/src/components/list-header/list-header.tsx index aa191367a8..4d780e875f 100644 --- a/core/src/components/list-header/list-header.tsx +++ b/core/src/components/list-header/list-header.tsx @@ -1,4 +1,5 @@ import { Component, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -18,13 +19,13 @@ export class ListHeader { * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; } diff --git a/core/src/components/list/list.tsx b/core/src/components/list/list.tsx index aa66250af6..ab387b5004 100644 --- a/core/src/components/list/list.tsx +++ b/core/src/components/list/list.tsx @@ -14,7 +14,8 @@ import { ItemSliding } from '../item-sliding/item-sliding'; } }) export class List { - private openItem: ItemSliding | null; + + private openItem?: ItemSliding; /** * Get the [Item Sliding](../../item-sliding/ItemSliding) that is currently opene. @@ -28,7 +29,7 @@ export class List { * Set an [Item Sliding](../../item-sliding/ItemSliding) as the open item. */ @Method() - setOpenItem(itemSliding: ItemSliding | null) { + setOpenItem(itemSliding: ItemSliding | undefined) { this.openItem = itemSliding; } @@ -40,7 +41,7 @@ export class List { closeSlidingItems(): boolean { if (this.openItem) { this.openItem.close(); - this.openItem = null; + this.openItem = undefined; return true; } return false; diff --git a/core/src/components/loading-controller/loading-controller.tsx b/core/src/components/loading-controller/loading-controller.tsx index 8aed467c4a..2d721ed031 100644 --- a/core/src/components/loading-controller/loading-controller.tsx +++ b/core/src/components/loading-controller/loading-controller.tsx @@ -10,7 +10,7 @@ export class LoadingController implements OverlayController { private loadings = new Map(); - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; @Listen('body:ionLoadingWillPresent') protected loadingWillPresent(ev: any) { diff --git a/core/src/components/loading/loading.tsx b/core/src/components/loading/loading.tsx index 85553f1993..dd4d5c9a2e 100644 --- a/core/src/components/loading/loading.tsx +++ b/core/src/components/loading/loading.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, Config } from '../../index'; +import { Animation, AnimationBuilder, Config, Mode } from '../../index'; import { createThemedClasses, getClassMap } from '../../utils/theme'; import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; @@ -24,37 +24,37 @@ export class Loading implements OverlayInterface { private durationTimeout: any; presented = false; - animation: Animation; - color: string; - mode: string; + animation?: Animation; + color!: string; + mode!: Mode; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; - @Prop({ context: 'config' }) config: Config; - @Prop() overlayId: number; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; + @Prop({ context: 'config' }) config!: Config; + @Prop() overlayId!: number; @Prop() keyboardClose = true; /** * Animation to use when the loading indicator is presented. */ - @Prop() enterAnimation: AnimationBuilder; + @Prop() enterAnimation?: AnimationBuilder; /** * Animation to use when the loading indicator is dismissed. */ - @Prop() leaveAnimation: AnimationBuilder; + @Prop() leaveAnimation?: AnimationBuilder; /** * Optional text content to display in the loading indicator. */ - @Prop() content: string; + @Prop() content?: string; /** * Additional classes to apply for custom CSS. If multiple classes are * provided they should be separated by spaces. */ - @Prop() cssClass: string | string[]; + @Prop() cssClass?: string | string[]; /** * If true, the loading indicator will dismiss when the page changes. Defaults to `false`. @@ -64,7 +64,7 @@ export class Loading implements OverlayInterface { /** * Number of milliseconds to wait before dismissing the loading indicator. */ - @Prop() duration: number; + @Prop() duration?: number; /** * If true, the loading indicator will be dismissed when the backdrop is clicked. Defaults to `false`. @@ -80,7 +80,7 @@ export class Loading implements OverlayInterface { * The name of the spinner to display. Possible values are: `"lines"`, `"lines-small"`, `"dots"`, * `"bubbles"`, `"circles"`, `"crescent"`. */ - @Prop() spinner: string; + @Prop() spinner?: string; /** * If true, the loading indicator will be translucent. Defaults to `false`. @@ -95,32 +95,32 @@ export class Loading implements OverlayInterface { /** * Emitted after the loading has unloaded. */ - @Event() ionLoadingDidUnload: EventEmitter; + @Event() ionLoadingDidUnload!: EventEmitter; /** * Emitted after the loading has loaded. */ - @Event() ionLoadingDidLoad: EventEmitter; + @Event() ionLoadingDidLoad!: EventEmitter; /** * Emitted after the loading has presented. */ - @Event({eventName: 'ionLoadingDidPresent'}) didPresent: EventEmitter; + @Event({eventName: 'ionLoadingDidPresent'}) didPresent!: EventEmitter; /** * Emitted before the loading has presented. */ - @Event({eventName: 'ionLoadingWillPresent'}) willPresent: EventEmitter; + @Event({eventName: 'ionLoadingWillPresent'}) willPresent!: EventEmitter; /** * Emitted before the loading has dismissed. */ - @Event({eventName: 'ionLoadingWillDismiss'}) willDismiss: EventEmitter; + @Event({eventName: 'ionLoadingWillDismiss'}) willDismiss!: EventEmitter; /** * Emitted after the loading has dismissed. */ - @Event({eventName: 'ionLoadingDidDismiss'}) didDismiss: EventEmitter; + @Event({eventName: 'ionLoadingDidDismiss'}) didDismiss!: EventEmitter; componentWillLoad() { if (!this.spinner) { @@ -147,7 +147,7 @@ export class Loading implements OverlayInterface { async present(): Promise { await present(this, 'loadingEnter', iosEnterAnimation, mdEnterAnimation, undefined); - if (this.duration > 0) { + if (this.duration) { this.durationTimeout = setTimeout(() => this.dismiss(), this.duration + 10); } } diff --git a/core/src/components/menu-button/menu-button.tsx b/core/src/components/menu-button/menu-button.tsx index 85623c38ca..62d9cedb9c 100644 --- a/core/src/components/menu-button/menu-button.tsx +++ b/core/src/components/menu-button/menu-button.tsx @@ -15,19 +15,19 @@ export class MenuButton { private custom = true; - @Prop({ context: 'config' }) config: Config; + @Prop({ context: 'config' }) config!: Config; /** * Optional property that maps to a Menu's `menuId` prop. Can also be `left` or `right` for the menu side. This is used to find the correct menu to toggle */ - @Prop() menu: string; + @Prop() menu?: string; /** * Automatically hides the menu button when the corresponding menu is not active */ @Prop() autoHide = true; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; componentWillLoad() { this.custom = this.el.childElementCount > 0; diff --git a/core/src/components/menu-controller/menu-controller.ts b/core/src/components/menu-controller/menu-controller.ts index 8891ec6eaa..dc782a667a 100644 --- a/core/src/components/menu-controller/menu-controller.ts +++ b/core/src/components/menu-controller/menu-controller.ts @@ -13,7 +13,7 @@ export class MenuController { private menus: Menu[] = []; private menuAnimations = new Map(); - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; constructor() { this.registerAnimation('reveal', MenuRevealAnimation); diff --git a/core/src/components/menu-toggle/menu-toggle.tsx b/core/src/components/menu-toggle/menu-toggle.tsx index 56e497273e..fb447c97ba 100644 --- a/core/src/components/menu-toggle/menu-toggle.tsx +++ b/core/src/components/menu-toggle/menu-toggle.tsx @@ -6,14 +6,14 @@ import { Component, Listen, Prop, State } from '@stencil/core'; }) export class MenuToggle { - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; @State() visible = false; /** * Optional property that maps to a Menu's `menuId` prop. Can also be `left` or `right` for the menu side. This is used to find the correct menu to toggle */ - @Prop() menu: string; + @Prop() menu?: string; /** * Automatically hides the content when the corresponding menu is not diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index 9c5fa39d24..f106f41ed9 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, EventListenerEnable, Listen, Method, Prop, State, Watch } from '@stencil/core'; -import { Animation, Config, GestureDetail } from '../../index'; +import { Animation, Config, GestureDetail, Mode } from '../../index'; import { Side, assert, isRightSide } from '../../utils/helpers'; @Component({ @@ -19,41 +19,41 @@ export class Menu { private _isOpen = false; private lastOnEnd = 0; - mode: string; - color: string; + mode!: Mode; + color!: string; isAnimating = false; - width: number; + width!: number; // TOOD backdropEl: HTMLElement|undefined; menuInnerEl: HTMLElement|undefined; contentEl: HTMLElement|undefined; menuCtrl: HTMLIonMenuControllerElement|undefined; - @Element() el: HTMLIonMenuElement; + @Element() el!: HTMLIonMenuElement; @State() isRightSide = false; - @Prop({ context: 'config' }) config: Config; - @Prop({ context: 'isServer' }) isServer: boolean; - @Prop({ connect: 'ion-menu-controller' }) lazyMenuCtrl: HTMLIonMenuControllerElement; - @Prop({ context: 'enableListener' }) enableListener: EventListenerEnable; - @Prop({ context: 'window' }) win: Window; + @Prop({ context: 'config' }) config!: Config; + @Prop({ context: 'isServer' }) isServer!: boolean; + @Prop({ connect: 'ion-menu-controller' }) lazyMenuCtrl!: HTMLIonMenuControllerElement; + @Prop({ context: 'enableListener' }) enableListener!: EventListenerEnable; + @Prop({ context: 'window' }) win!: Window; /** * The content's id the menu should use. */ - @Prop() contentId: string; + @Prop() contentId?: string; /** * An id for the menu. */ - @Prop() menuId: string; + @Prop() menuId?: string; /** * The display type of the menu. Default varies based on the mode, * see the `menuType` in the [config](../../config/Config). Available options: * `"overlay"`, `"reveal"`, `"push"`. */ - @Prop({ mutable: true }) type: string; + @Prop({ mutable: true }) type!: string; @Watch('type') typeChanged(type: string, oldType: string | null) { @@ -111,15 +111,15 @@ export class Menu { /** * Emitted when the menu is open. */ - @Event() ionOpen: EventEmitter; + @Event() ionOpen!: EventEmitter; /** * Emitted when the menu is closed. */ - @Event() ionClose: EventEmitter; + @Event() ionClose!: EventEmitter; - @Event() protected ionMenuChange: EventEmitter; + @Event() protected ionMenuChange!: EventEmitter; async componentWillLoad() { if (this.type == null) { @@ -133,9 +133,10 @@ export class Menu { return; } const el = this.el; + const parent = el.parentNode as any; const content = (this.contentId) - ? this.win.document.getElementById(this.contentId) - : el.parentElement && el.parentElement.querySelector('[main]'); + ? document.getElementById(this.contentId) + : parent && parent.querySelector && parent.querySelector('[main]'); if (!content || !content.tagName) { // requires content element diff --git a/core/src/components/modal-controller/modal-controller.tsx b/core/src/components/modal-controller/modal-controller.tsx index 2fe34e4a98..b5472ffea8 100644 --- a/core/src/components/modal-controller/modal-controller.tsx +++ b/core/src/components/modal-controller/modal-controller.tsx @@ -10,7 +10,7 @@ export class ModalController implements OverlayController { private modals = new Map(); - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; @Listen('body:ionModalWillPresent') protected modalWillPresent(ev: any) { diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 049776665d..b4cb660681 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate } from '../../index'; +import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate, Mode } from '../../index'; import { createThemedClasses, getClassMap } from '../../utils/theme'; import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; @@ -23,18 +23,18 @@ import mdLeaveAnimation from './animations/md.leave'; }) export class Modal implements OverlayInterface { - private usersElement: HTMLElement; + private usersElement?: HTMLElement; animation: Animation|undefined; presented = false; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; - @Prop({ context: 'config' }) config: Config; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; + @Prop({ context: 'config' }) config!: Config; - @Prop() overlayId: number; - @Prop() delegate: FrameworkDelegate; + @Prop() overlayId!: number; + @Prop() delegate?: FrameworkDelegate; @Prop() keyboardClose = true; /** @@ -42,40 +42,40 @@ export class Modal implements OverlayInterface { * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * Animation to use when the modal is presented. */ - @Prop() enterAnimation: AnimationBuilder; + @Prop() enterAnimation?: AnimationBuilder; /** * Animation to use when the modal is dismissed. */ - @Prop() leaveAnimation: AnimationBuilder; + @Prop() leaveAnimation?: AnimationBuilder; /** * The component to display inside of the modal. */ - @Prop() component: ComponentRef; + @Prop() component!: ComponentRef; /** * The data to pass to the modal component. */ - @Prop() componentProps: ComponentProps; + @Prop() componentProps?: ComponentProps; /** * Additional classes to apply for custom CSS. If multiple classes are * provided they should be separated by spaces. */ - @Prop() cssClass: string | string[]; + @Prop() cssClass?: string | string[]; /** * If true, the modal will be dismissed when the backdrop is clicked. Defaults to `true`. @@ -95,32 +95,32 @@ export class Modal implements OverlayInterface { /** * Emitted after the modal has loaded. */ - @Event() ionModalDidLoad: EventEmitter; + @Event() ionModalDidLoad!: EventEmitter; /** * Emitted after the modal has unloaded. */ - @Event() ionModalDidUnload: EventEmitter; + @Event() ionModalDidUnload!: EventEmitter; /** * Emitted after the modal has presented. */ - @Event({eventName: 'ionModalDidPresent'}) didPresent: EventEmitter; + @Event({eventName: 'ionModalDidPresent'}) didPresent!: EventEmitter; /** * Emitted before the modal has presented. */ - @Event({eventName: 'ionModalWillPresent'}) willPresent: EventEmitter; + @Event({eventName: 'ionModalWillPresent'}) willPresent!: EventEmitter; /** * Emitted before the modal has dismissed. */ - @Event({eventName: 'ionModalWillDismiss'}) willDismiss: EventEmitter; + @Event({eventName: 'ionModalWillDismiss'}) willDismiss!: EventEmitter; /** * Emitted after the modal has dismissed. */ - @Event({eventName: 'ionModalDidDismiss'}) didDismiss: EventEmitter; + @Event({eventName: 'ionModalDidDismiss'}) didDismiss!: EventEmitter; componentDidLoad() { this.ionModalDidLoad.emit(); diff --git a/core/src/components/nav-pop/nav-pop.tsx b/core/src/components/nav-pop/nav-pop.tsx index 2ae5b2c7e4..9a73dc88fd 100644 --- a/core/src/components/nav-pop/nav-pop.tsx +++ b/core/src/components/nav-pop/nav-pop.tsx @@ -5,7 +5,7 @@ import { Component, Element, Listen } from '@stencil/core'; }) export class NavPop { - @Element() el: HTMLElement; + @Element() el!: HTMLElement; @Listen('child:click') pop(): Promise { diff --git a/core/src/components/nav-push/nav-push.tsx b/core/src/components/nav-push/nav-push.tsx index 5e652cce1f..eeda704a0c 100644 --- a/core/src/components/nav-push/nav-push.tsx +++ b/core/src/components/nav-push/nav-push.tsx @@ -7,15 +7,15 @@ import { NavComponent } from '../nav/nav-util'; }) export class NavPush { - @Element() el: HTMLElement; - @Prop() component: NavComponent; - @Prop() componentProps: ComponentProps; - @Prop() url: string; + @Element() el!: HTMLElement; + + @Prop() component?: NavComponent; + @Prop() componentProps?: ComponentProps; @Listen('child:click') push(): Promise { const nav = this.el.closest('ion-nav'); - const toPush = this.url || this.component; + const toPush = this.component; if (nav && toPush) { return nav.push(toPush, this.componentProps); } diff --git a/core/src/components/nav-push/readme.md b/core/src/components/nav-push/readme.md index 6c24c3eb45..c22d00e616 100644 --- a/core/src/components/nav-push/readme.md +++ b/core/src/components/nav-push/readme.md @@ -17,11 +17,6 @@ string -#### url - -string - - ## Attributes #### component @@ -34,11 +29,6 @@ string -#### url - -string - - ---------------------------------------------- diff --git a/core/src/components/nav-set-root/nav-set-root.tsx b/core/src/components/nav-set-root/nav-set-root.tsx index 897177ebfc..5fffc0b94b 100644 --- a/core/src/components/nav-set-root/nav-set-root.tsx +++ b/core/src/components/nav-set-root/nav-set-root.tsx @@ -7,16 +7,15 @@ import { NavComponent } from '../nav/nav-util'; }) export class NavSetRoot { - @Element() el: HTMLElement; - @Prop() component: NavComponent; - @Prop() componentProps: ComponentProps; - @Prop() url: string; + @Element() el!: HTMLElement; + @Prop() component?: NavComponent; + @Prop() componentProps?: ComponentProps; @Listen('child:click') push(): Promise { const nav = this.el.closest('ion-nav'); - if (nav) { - const toPush = this.url || this.component; + const toPush = this.component; + if (nav && toPush) { return nav.setRoot(toPush, this.componentProps); } return Promise.resolve(null); diff --git a/core/src/components/nav-set-root/readme.md b/core/src/components/nav-set-root/readme.md index 40f7660ddf..3790c0a040 100644 --- a/core/src/components/nav-set-root/readme.md +++ b/core/src/components/nav-set-root/readme.md @@ -17,11 +17,6 @@ string -#### url - -string - - ## Attributes #### component @@ -34,11 +29,6 @@ string -#### url - -string - - ---------------------------------------------- diff --git a/core/src/components/nav/nav.tsx b/core/src/components/nav/nav.tsx index 126518cae8..29c222cfa9 100644 --- a/core/src/components/nav/nav.tsx +++ b/core/src/components/nav/nav.tsx @@ -1,23 +1,14 @@ import { Build, Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core'; -import { - NavComponent, - NavDirection, - NavOptions, - NavResult, - TransitionDoneFn, - TransitionInstruction, - ViewState, - convertToViews, -} from './nav-util'; - -import { ViewController, matches } from './view-controller'; -import { Animation, ComponentProps, Config, FrameworkDelegate, GestureDetail, NavOutlet, QueueController } from '../..'; -import { RouteID, RouteWrite, RouterDirection } from '../router/utils/interfaces'; -import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition'; +import { Animation, ComponentProps, Config, FrameworkDelegate, GestureDetail, Mode, NavOutlet, QueueController } from '../..'; import { assert } from '../../utils/helpers'; - +import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition'; +import { RouteID, RouteWrite, RouterDirection } from '../router/utils/interfaces'; import iosTransitionAnimation from './animations/ios.transition'; import mdTransitionAnimation from './animations/md.transition'; +import { NavComponent, NavDirection, NavOptions, NavResult, TransitionDoneFn, TransitionInstruction, ViewState, convertToViews } from './nav-util'; +import { ViewController, matches } from './view-controller'; + + @Component({ tag: 'ion-nav', @@ -32,18 +23,18 @@ export class Nav implements NavOutlet { private destroyed = false; private views: ViewController[] = []; - mode: string; + mode!: Mode; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ context: 'queue' }) queue: QueueController; - @Prop({ context: 'config' }) config: Config; - @Prop({ context: 'window' }) win: Window; + @Prop({ context: 'queue' }) queue!: QueueController; + @Prop({ context: 'config' }) config!: Config; + @Prop({ context: 'window' }) win!: Window; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; - @Prop({ mutable: true }) swipeBackEnabled: boolean; - @Prop({ mutable: true }) animated: boolean; - @Prop() delegate: FrameworkDelegate|undefined; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; + @Prop({ mutable: true }) swipeBackEnabled?: boolean; + @Prop({ mutable: true }) animated?: boolean; + @Prop() delegate?: FrameworkDelegate|undefined; @Prop() rootParams: ComponentProps|undefined; @Prop() root: NavComponent|undefined; @Watch('root') @@ -58,8 +49,8 @@ export class Nav implements NavOutlet { } } - @Event() ionNavWillChange: EventEmitter; - @Event() ionNavDidChange: EventEmitter; + @Event() ionNavWillChange!: EventEmitter; + @Event() ionNavDidChange!: EventEmitter; componentWillLoad() { this.useRouter = !!this.win.document.querySelector('ion-router') && !this.el.closest('[no-router]'); @@ -745,7 +736,7 @@ export class Nav implements NavOutlet { private canSwipeBack(): boolean { return ( - this.swipeBackEnabled && + !!this.swipeBackEnabled && !this.isTransitioning && this.canGoBack() ); diff --git a/core/src/components/nav/test/nav-controller.spec.ts b/core/src/components/nav/test/nav-controller.spec.ts index 47a8838ef2..f2a51769a1 100644 --- a/core/src/components/nav/test/nav-controller.spec.ts +++ b/core/src/components/nav/test/nav-controller.spec.ts @@ -1,10 +1,10 @@ import { Nav } from '../nav'; import { ViewController } from '../view-controller'; import { AnimationControllerImpl } from '../../animation-controller/animation-controller'; -import { createConfigController } from '../../../global/config-controller'; import { NavDirection, NavOptions, ViewState } from '../nav-util'; import { TestWindow } from '@stencil/core/dist/testing'; +import { Config } from '../../../global/config'; describe('NavController', () => { @@ -1072,7 +1072,7 @@ describe('NavController', () => { nav.ionNavWillChange = {emit: function() { return; } }; nav.animationCtrl = new AnimationControllerImpl() as any; - nav.config = createConfigController({animate: false}, []); + nav.config = new Config({animate: false}); nav._viewInit = function (enteringView: ViewController) { if (!enteringView.element) { console.log(enteringView.component); diff --git a/core/src/components/nav/view-controller.ts b/core/src/components/nav/view-controller.ts index 20ef85841b..f3fc2045c4 100644 --- a/core/src/components/nav/view-controller.ts +++ b/core/src/components/nav/view-controller.ts @@ -9,7 +9,7 @@ export class ViewController { nav: Nav|undefined; state: ViewState = ViewState.New; element: HTMLElement|undefined; - delegate: FrameworkDelegate|undefined; + delegate?: FrameworkDelegate|undefined; constructor( public component: any, diff --git a/core/src/components/note/note.tsx b/core/src/components/note/note.tsx index afaded1dba..2ea9fdc53f 100644 --- a/core/src/components/note/note.tsx +++ b/core/src/components/note/note.tsx @@ -1,4 +1,5 @@ import { Component, Prop } from '@stencil/core'; +import { Mode } from '../..'; @Component({ @@ -18,13 +19,13 @@ export class Note { * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; } diff --git a/core/src/components/picker-column/picker-column.tsx b/core/src/components/picker-column/picker-column.tsx index b3467b6e2e..5e0fffad89 100644 --- a/core/src/components/picker-column/picker-column.tsx +++ b/core/src/components/picker-column/picker-column.tsx @@ -1,7 +1,7 @@ import { Component, Element, Prop } from '@stencil/core'; -import { clamp } from '../../utils/helpers'; -import { GestureDetail, PickerColumn, PickerColumnOption, QueueController } from '../../index'; +import { GestureDetail, Mode, PickerColumn, PickerColumnOption, QueueController } from '../../index'; import { hapticSelectionChanged } from '../../utils'; +import { clamp } from '../../utils/helpers'; @Component({ @@ -11,26 +11,26 @@ import { hapticSelectionChanged } from '../../utils'; } }) export class PickerColumnCmp { - private mode: string; + mode!: Mode; - private bounceFrom: number; - private lastIndex: number; - private lastTempIndex: number; - private minY: number; - private maxY: number; - private optHeight: number; + private bounceFrom!: number; + private lastIndex?: number; + private lastTempIndex?: number; + private minY!: number; + private maxY!: number; + private optHeight = 0; private pos: number[] = []; - private rotateFactor: number; - private scaleFactor: number; - private startY: number|undefined; - private velocity: number; + private rotateFactor = 0; + private scaleFactor = 1; + private startY?: number; + private velocity = 0; private y = 0; - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ context: 'queue' }) queue: QueueController; + @Prop({ context: 'queue' }) queue!: QueueController; - @Prop() col: PickerColumn; + @Prop() col!: PickerColumn; componentWillLoad() { let pickerRotateFactor = 0; diff --git a/core/src/components/picker-controller/picker-controller.tsx b/core/src/components/picker-controller/picker-controller.tsx index 298bff0924..36323054e6 100644 --- a/core/src/components/picker-controller/picker-controller.tsx +++ b/core/src/components/picker-controller/picker-controller.tsx @@ -10,7 +10,7 @@ export class PickerController implements OverlayController { private pickers = new Map(); - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; @Listen('body:ionPickerWillPresent') protected pickerWillPresent(ev: any) { diff --git a/core/src/components/picker/picker.tsx b/core/src/components/picker/picker.tsx index 332276a12a..1f42bab1e0 100644 --- a/core/src/components/picker/picker.tsx +++ b/core/src/components/picker/picker.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core'; -import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index'; +import { Animation, AnimationBuilder, Config, CssClassMap, Mode } from '../../index'; import { getClassMap } from '../../utils/theme'; import { OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; @@ -21,29 +21,29 @@ export class Picker implements OverlayInterface { private durationTimeout: any; - mode: string; + mode!: Mode; presented = false; - animation: Animation; + animation?: Animation; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @State() private showSpinner: boolean|undefined; - @State() private spinner: string; + @State() private showSpinner!: boolean; + @State() private spinner!: string; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; - @Prop({ context: 'config' }) config: Config; - @Prop() overlayId: number; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; + @Prop({ context: 'config' }) config!: Config; + @Prop() overlayId!: number; @Prop() keyboardClose = true; /** * Animation to use when the picker is presented. */ - @Prop() enterAnimation: AnimationBuilder; + @Prop() enterAnimation?: AnimationBuilder; /** * Animation to use when the picker is dismissed. */ - @Prop() leaveAnimation: AnimationBuilder; + @Prop() leaveAnimation?: AnimationBuilder; /** * Array of buttons to be displayed at the top of the picker. @@ -59,12 +59,12 @@ export class Picker implements OverlayInterface { * Additional classes to apply for custom CSS. If multiple classes are * provided they should be separated by spaces. */ - @Prop() cssClass: string | string[]; + @Prop() cssClass?: string | string[]; /** * Number of milliseconds to wait before dismissing the picker. */ - @Prop() duration: number; + @Prop() duration?: number; /** * If true, a backdrop will be displayed behind the picker. Defaults to `true`. @@ -84,32 +84,32 @@ export class Picker implements OverlayInterface { /** * Emitted after the picker has loaded. */ - @Event() ionPickerDidLoad: EventEmitter; + @Event() ionPickerDidLoad!: EventEmitter; /** * Emitted after the picker has presented. */ - @Event({eventName: 'ionPickerDidPresent'}) didPresent: EventEmitter; + @Event({eventName: 'ionPickerDidPresent'}) didPresent!: EventEmitter; /** * Emitted before the picker has presented. */ - @Event({eventName: 'ionPickerWillPresent'}) willPresent: EventEmitter; + @Event({eventName: 'ionPickerWillPresent'}) willPresent!: EventEmitter; /** * Emitted before the picker has dismissed. */ - @Event({eventName: 'ionPickerWillDismiss'}) willDismiss: EventEmitter; + @Event({eventName: 'ionPickerWillDismiss'}) willDismiss!: EventEmitter; /** * Emitted after the picker has dismissed. */ - @Event({eventName: 'ionPickerDidDismiss'}) didDismiss: EventEmitter; + @Event({eventName: 'ionPickerDidDismiss'}) didDismiss!: EventEmitter; /** * Emitted after the picker has unloaded. */ - @Event() ionPickerDidUnload: EventEmitter; + @Event() ionPickerDidUnload!: EventEmitter; componentWillLoad() { @@ -147,7 +147,7 @@ export class Picker implements OverlayInterface { async present(): Promise { await present(this, 'pickerEnter', iosEnterAnimation, iosEnterAnimation, undefined); - if (this.duration > 0) { + if (this.duration) { this.durationTimeout = setTimeout(() => this.dismiss(), this.duration); } } diff --git a/core/src/components/popover-controller/popover-controller.tsx b/core/src/components/popover-controller/popover-controller.tsx index e6a8d4f2e9..7d0f858eba 100644 --- a/core/src/components/popover-controller/popover-controller.tsx +++ b/core/src/components/popover-controller/popover-controller.tsx @@ -9,7 +9,7 @@ export class PopoverController implements OverlayController { private popovers = new Map(); - @Prop({ context: 'document' }) doc: Document; + @Prop({ context: 'document' }) doc!: Document; @Listen('body:ionPopoverWillPresent') protected popoverWillPresent(ev: any) { diff --git a/core/src/components/popover/popover.tsx b/core/src/components/popover/popover.tsx index 0640f0a10a..a8064d6e0e 100644 --- a/core/src/components/popover/popover.tsx +++ b/core/src/components/popover/popover.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate } from '../../index'; +import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate, Mode } from '../../index'; import { createThemedClasses, getClassMap } from '../../utils/theme'; import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; @@ -23,17 +23,17 @@ import mdLeaveAnimation from './animations/md.leave'; }) export class Popover implements OverlayInterface { - private usersElement: HTMLElement; + private usersElement?: HTMLElement; presented = false; - animation: Animation; + animation?: Animation; - @Element() el: HTMLElement; + @Element() el!: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; - @Prop({ context: 'config' }) config: Config; - @Prop() delegate: FrameworkDelegate; - @Prop() overlayId: number; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; + @Prop({ context: 'config' }) config!: Config; + @Prop() delegate?: FrameworkDelegate; + @Prop() overlayId!: number; @Prop() keyboardClose = true; /** @@ -41,40 +41,40 @@ export class Popover implements OverlayInterface { * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * Animation to use when the popover is presented. */ - @Prop() enterAnimation: AnimationBuilder; + @Prop() enterAnimation?: AnimationBuilder; /** * Animation to use when the popover is dismissed. */ - @Prop() leaveAnimation: AnimationBuilder; + @Prop() leaveAnimation?: AnimationBuilder; /** * The component to display inside of the popover. */ - @Prop() component: ComponentRef; + @Prop() component!: ComponentRef; /** * The data to pass to the popover component. */ - @Prop() componentProps: ComponentProps; + @Prop() componentProps?: ComponentProps; /** * Additional classes to apply for custom CSS. If multiple classes are * provided they should be separated by spaces. */ - @Prop() cssClass: string | string[]; + @Prop() cssClass?: string | string[]; /** * If true, the popover will be dismissed when the backdrop is clicked. Defaults to `true`. @@ -104,32 +104,32 @@ export class Popover implements OverlayInterface { /** * Emitted after the popover has loaded. */ - @Event() ionPopoverDidLoad: EventEmitter; + @Event() ionPopoverDidLoad!: EventEmitter; /** * Emitted after the popover has unloaded. */ - @Event() ionPopoverDidUnload: EventEmitter; + @Event() ionPopoverDidUnload!: EventEmitter; /** * Emitted after the popover has presented. */ - @Event({eventName: 'ionPopoverDidPresent'}) didPresent: EventEmitter; + @Event({eventName: 'ionPopoverDidPresent'}) didPresent!: EventEmitter; /** * Emitted before the popover has presented. */ - @Event({eventName: 'ionPopoverWillPresent'}) willPresent: EventEmitter; + @Event({eventName: 'ionPopoverWillPresent'}) willPresent!: EventEmitter; /** * Emitted before the popover has dismissed. */ - @Event({eventName: 'ionPopoverWillDismiss'}) willDismiss: EventEmitter; + @Event({eventName: 'ionPopoverWillDismiss'}) willDismiss!: EventEmitter; /** * Emitted after the popover has dismissed. */ - @Event({eventName: 'ionPopoverDidDismiss'}) didDismiss: EventEmitter; + @Event({eventName: 'ionPopoverDidDismiss'}) didDismiss!: EventEmitter; componentDidLoad() { diff --git a/core/src/components/radio-group/radio-group.tsx b/core/src/components/radio-group/radio-group.tsx index c1786334c8..3a70031a4f 100644 --- a/core/src/components/radio-group/radio-group.tsx +++ b/core/src/components/radio-group/radio-group.tsx @@ -1,4 +1,4 @@ -import { Component, ComponentDidLoad, Element, Event, EventEmitter, Listen, Prop, State, Watch } from '@stencil/core'; +import { Component, ComponentDidLoad, Element, Event, EventEmitter, Listen, Prop, Watch } from '@stencil/core'; import { HTMLIonRadioElementEvent } from '../radio/radio'; import { InputChangeEvent, RadioGroupInput } from '../../utils/input-interfaces'; @@ -7,111 +7,66 @@ import { InputChangeEvent, RadioGroupInput } from '../../utils/input-interfaces' tag: 'ion-radio-group' }) export class RadioGroup implements ComponentDidLoad, RadioGroupInput { - private didLoad: boolean; + + private inputId = `ion-rg-${radioGroupIds++}`; + private labelId = `${this.inputId}-lbl`; private radios: HTMLIonRadioElement[] = []; - @Element() el: HTMLElement; - - @State() labelId: string; + @Element() el!: HTMLElement; /* * If true, the radios can be deselected. Default false. */ @Prop() allowEmptySelection = false; + /** + * The name of the control, which is submitted with the form data. + */ + @Prop() name: string = this.inputId; + /* * If true, the user cannot interact with the radio group. Default false. */ @Prop() disabled = false; - /** - * The name of the control, which is submitted with the form data. - */ - @Prop({ mutable: true }) name: string; + @Watch('disabled') + disabledChanged() { + for (const radio of this.radios) { + radio.disabled = this.disabled; + } + } /** * the value of the radio group. */ - @Prop({ mutable: true }) value: string; - - @Watch('disabled') - disabledChanged() { - this.setDisabled(); - } + @Prop({ mutable: true }) value?: string; @Watch('value') - valueChanged() { - // this radio group's value just changed - // double check the button with this value is checked - if (this.value === undefined) { - // set to undefined - // ensure all that are checked become unchecked - this.radios.filter(r => r.checked).forEach(radio => { - radio.checked = false; - }); - - } else { - let hasChecked = false; - - this.radios.forEach(radio => { - if (radio.value === this.value) { - if (!radio.checked && !hasChecked) { - // correct value for this radio - // but this radio isn't checked yet - // and we haven't found a checked yet - // so CHECK IT! - radio.checked = true; - - } else if (hasChecked && radio.checked) { - // somehow we've got multiple radios - // with the same value, but only one can be checked - radio.checked = false; - } - - // remember we've got a checked radio button now - hasChecked = true; - - } else if (radio.checked) { - // this radio doesn't have the correct value - // and it's also checked, so let's uncheck it - radio.checked = false; - } - }); - } - - if (this.didLoad) { - // emit the new value - this.ionChange.emit({ value: this.value }); - } + valueChanged(value: string | undefined) { + this.updateRadios(); + this.ionChange.emit({ value }); } /** * Emitted when the value has changed. */ - @Event() ionChange: EventEmitter; + @Event() ionChange!: EventEmitter; @Listen('ionRadioDidLoad') onRadioDidLoad(ev: HTMLIonRadioElementEvent) { const radio = ev.target; - this.radios.push(radio); radio.name = this.name; - if (this.value !== undefined && radio.value === this.value) { - // this radio-group has a value and this - // radio equals the correct radio-group value - // so let's check this radio - radio.checked = true; + // add radio to internal list + this.radios.push(radio); - } else if (this.value === undefined && radio.checked) { - // this radio-group does not have a value - // but this radio is checked, so let's set the - // radio-group's value from the checked radio + // this radio-group does not have a value + // but this radio is checked, so let's set the + // radio-group's value from the checked radio + if (this.value === undefined && radio.checked) { this.value = radio.value; - - } else if (radio.checked) { - // if it doesn't match one of the above cases, but the - // radio is still checked, then we need to uncheck it - radio.checked = false; + } else { + this.updateRadios(); } } @@ -125,20 +80,10 @@ export class RadioGroup implements ComponentDidLoad, RadioGroupInput { @Listen('ionSelect') onRadioSelect(ev: HTMLIonRadioElementEvent) { - // ionSelect only come from the checked radio button - this.radios.forEach(radio => { - if (radio === ev.target) { - if (radio.value !== this.value) { - this.value = radio.value; - } - } else { - radio.checked = false; - } - }); - } - - componentWillLoad() { - this.name = this.name || 'ion-rg-' + (radioGroupIds++); + const selectedRadio = ev.target; + if (selectedRadio) { + this.value = selectedRadio.value; + } } componentDidLoad() { @@ -155,14 +100,26 @@ export class RadioGroup implements ComponentDidLoad, RadioGroupInput { } } - this.setDisabled(); - this.didLoad = true; + this.disabledChanged(); + this.updateRadios(); } - setDisabled() { - this.radios.forEach(radio => { - radio.disabled = this.disabled; - }); + private updateRadios() { + const value = this.value; + let hasChecked = false; + for (const radio of this.radios) { + if (!hasChecked && radio.value === value) { + // correct value for this radio + // but this radio isn't checked yet + // and we haven't found a checked yet + hasChecked = true; + radio.checked = true; + } else { + // this radio doesn't have the correct value + // or the radio group has been already checked + radio.checked = false; + } + } } hostData() { diff --git a/core/src/components/radio/radio.tsx b/core/src/components/radio/radio.tsx index 97312cd59a..2c2d6a83e3 100644 --- a/core/src/components/radio/radio.tsx +++ b/core/src/components/radio/radio.tsx @@ -1,7 +1,8 @@ import { BlurEvent, CheckedInputChangeEvent, FocusEvent, RadioButtonInput, StyleEvent } from '../../utils/input-interfaces'; import { Component, ComponentDidLoad, ComponentDidUnload, ComponentWillLoad, Event, EventEmitter, Prop, State, Watch } from '@stencil/core'; import { createThemedClasses } from '../../utils/theme'; -import { CssClassMap } from '../../index'; +import { CssClassMap, Mode } from '../../index'; +import { deferEvent } from '../../utils/helpers'; @Component({ @@ -15,33 +16,30 @@ import { CssClassMap } from '../../index'; } }) export class Radio implements RadioButtonInput, ComponentDidLoad, ComponentDidUnload, ComponentWillLoad { - private checkedTmr: any; - private didLoad: boolean; - private inputId: string; - private nativeInput: HTMLInputElement; - private styleTmr: any; + private inputId = `ion-rb-${radioButtonIds++}`; + private nativeInput!: HTMLInputElement; - @State() keyFocus: boolean; + @State() keyFocus = false; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * The name of the control, which is submitted with the form data. */ - @Prop() name: string; + @Prop() name: string = this.inputId; /* * If true, the user cannot interact with the radio. Defaults to `false`. @@ -56,41 +54,43 @@ export class Radio implements RadioButtonInput, ComponentDidLoad, ComponentDidUn /** * the value of the radio. */ - @Prop({ mutable: true }) value: string; + @Prop({ mutable: true }) value!: string; /** * Emitted when the radio loads. */ - @Event() ionRadioDidLoad: EventEmitter; + @Event() ionRadioDidLoad!: EventEmitter; /** * Emitted when the radio unloads. */ - @Event() ionRadioDidUnload: EventEmitter; + @Event() ionRadioDidUnload!: EventEmitter; /** * Emitted when the styles change. */ - @Event() ionStyle: EventEmitter; + @Event() ionStyle!: EventEmitter; /** * Emitted when the radio button is selected. */ - @Event() ionSelect: EventEmitter; + @Event() ionSelect!: EventEmitter; /** * Emitted when the radio button has focus. */ - @Event() ionFocus: EventEmitter; + @Event() ionFocus!: EventEmitter; /** * Emitted when the radio button loses focus. */ - @Event() ionBlur: EventEmitter; + @Event() ionBlur!: EventEmitter; componentWillLoad() { - this.inputId = 'ion-rb-' + (radioButtonIds++); + this.ionSelect = deferEvent(this.ionSelect); + this.ionStyle = deferEvent(this.ionStyle); + if (this.value === undefined) { this.value = this.inputId; } @@ -100,7 +100,6 @@ export class Radio implements RadioButtonInput, ComponentDidLoad, ComponentDidUn componentDidLoad() { this.ionRadioDidLoad.emit({ radio: this }); this.nativeInput.checked = this.checked; - this.didLoad = true; const parentItem = this.nativeInput.closest('ion-item'); if (parentItem) { @@ -128,17 +127,12 @@ export class Radio implements RadioButtonInput, ComponentDidLoad, ComponentDidUn this.nativeInput.checked = isChecked; } - clearTimeout(this.checkedTmr); - this.checkedTmr = setTimeout(() => { - // only emit ionSelect when checked is true - if (this.didLoad && isChecked) { - this.ionSelect.emit({ - checked: isChecked, - value: this.value - }); - } - }); - + if (isChecked) { + this.ionSelect.emit({ + checked: true, + value: this.value + }); + } this.emitStyle(); } @@ -149,14 +143,10 @@ export class Radio implements RadioButtonInput, ComponentDidLoad, ComponentDidUn } emitStyle() { - clearTimeout(this.styleTmr); - - this.styleTmr = setTimeout(() => { - this.ionStyle.emit({ - ...createThemedClasses(this.mode, this.color, 'radio'), - 'radio-checked': this.checked, - 'radio-disabled': this.disabled - }); + this.ionStyle.emit({ + ...createThemedClasses(this.mode, this.color, 'radio'), + 'radio-checked': this.checked, + 'radio-disabled': this.disabled }); } @@ -183,15 +173,13 @@ export class Radio implements RadioButtonInput, ComponentDidLoad, ComponentDidUn } hostData() { - const hostAttrs: any = { + return { 'class': { 'radio-checked': this.checked, 'radio-disabled': this.disabled, 'radio-key': this.keyFocus } }; - - return hostAttrs; } render() { diff --git a/core/src/components/range-knob/range-knob.tsx b/core/src/components/range-knob/range-knob.tsx index 41e9c59f2c..2d28046ee8 100644 --- a/core/src/components/range-knob/range-knob.tsx +++ b/core/src/components/range-knob/range-knob.tsx @@ -5,18 +5,18 @@ import { Component, Event, EventEmitter, Listen, Prop } from '@stencil/core'; }) export class RangeKnob { - @Prop() pressed: boolean; - @Prop() pin: boolean; - @Prop() min: number; - @Prop() max: number; - @Prop() val: number; - @Prop() disabled: boolean; - @Prop() labelId: string; - @Prop() knob: string; - @Prop() ratio: number; + @Prop() pressed = false; + @Prop() pin = false; + @Prop() min!: number; + @Prop() max!: number; + @Prop() val!: number; + @Prop() disabled = false; + @Prop() labelId!: string; + @Prop() knob!: string; + @Prop() ratio!: number; - @Event() ionIncrease: EventEmitter; - @Event() ionDecrease: EventEmitter; + @Event() ionIncrease!: EventEmitter; + @Event() ionDecrease!: EventEmitter; @Listen('keydown') handleKeyBoard(ev: KeyboardEvent) { diff --git a/core/src/components/range/range.tsx b/core/src/components/range/range.tsx index d7d3c5a603..2387f23722 100644 --- a/core/src/components/range/range.tsx +++ b/core/src/components/range/range.tsx @@ -1,6 +1,7 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop, State, Watch } from '@stencil/core'; -import { BaseInputComponent, GestureDetail } from '../../index'; -import { clamp, debounceEvent } from '../../utils/helpers'; +import { GestureDetail, Mode } from '../../index'; +import { clamp, debounceEvent, deferEvent } from '../../utils/helpers'; +import { BaseInput } from '../../utils/input-interfaces'; export interface Tick { ratio: number | (() => number); @@ -18,63 +19,40 @@ export interface Tick { theme: 'range' } }) -export class Range implements BaseInputComponent { +export class Range implements BaseInput { - private styleTmr: any; - - activated = false; hasFocus = false; - startX: number; - @Element() private el: HTMLElement; + @Element() el!: HTMLElement; - @State() barL: string; - @State() barR: string; + @State() barL!: string; + @State() barR!: string; @State() valA = 0; @State() valB = 0; @State() ratioA = 0; @State() ratioB = 0; @State() ticks: Tick[] = []; - @State() activeB: boolean; - @State() rect: ClientRect; + @State() activeB = false; + @State() rect!: ClientRect; - @State() pressed: boolean; - @State() pressedA: boolean; - @State() pressedB: boolean; + @State() pressed = false; + @State() pressedA = false; + @State() pressedB = false; - /** - * Emitted when the value property has changed. - */ - @Event() ionChange: EventEmitter; - - /** - * Emitted when the styles change. - */ - @Event() ionStyle: EventEmitter; - - /** - * Emitted when the range has focus. - */ - @Event() ionFocus: EventEmitter; - - /** - * Emitted when the range loses focus. - */ - @Event() ionBlur: EventEmitter; /** * The color to use from your Sass `$colors` map. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * For more information, see [Theming your App](/docs/theming/theming-your-app). */ - @Prop() color: string; + @Prop() color!: string; /** * The mode determines which platform styles to use. * Possible values are: `"ios"` or `"md"`. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles). */ - @Prop() mode: 'ios' | 'md'; + @Prop() mode!: Mode; /** * How long, in milliseconds, to wait to trigger the @@ -87,10 +65,10 @@ export class Range implements BaseInputComponent { this.ionChange = debounceEvent(this.ionChange, this.debounce); } - /* - * If true, the user cannot interact with the range. Defaults to `false`. + /** + * The name of the control, which is submitted with the form data. */ - @Prop() disabled = false; + @Prop() name = ''; /** * Show two knobs. Defaults to `false`. @@ -124,17 +102,19 @@ export class Range implements BaseInputComponent { */ @Prop() step = 1; - /** - * the value of the range. + /* + * If true, the user cannot interact with the range. Defaults to `false`. */ - @Prop({ mutable: true }) value: any; - - + @Prop() disabled = false; @Watch('disabled') protected disabledChanged() { this.emitStyle(); } + /** + * the value of the range. + */ + @Prop({ mutable: true }) value: any; @Watch('value') protected valueChanged(val: boolean) { this.ionChange.emit({value: val}); @@ -142,7 +122,31 @@ export class Range implements BaseInputComponent { this.emitStyle(); } + + /** + * Emitted when the value property has changed. + */ + @Event() ionChange!: EventEmitter; + + /** + * Emitted when the styles change. + */ + @Event() ionStyle!: EventEmitter; + + /** + * Emitted when the range has focus. + */ + @Event() ionFocus!: EventEmitter; + + /** + * Emitted when the range loses focus. + */ + @Event() ionBlur!: EventEmitter; + + componentWillLoad() { + this.ionStyle = deferEvent(this.ionStyle); + this.inputUpdated(); this.createTicks(); this.debounceChanged(); @@ -150,16 +154,12 @@ export class Range implements BaseInputComponent { } private emitStyle() { - clearTimeout(this.styleTmr); - - this.styleTmr = setTimeout(() => { - this.ionStyle.emit({ - 'range-disabled': this.disabled - }); + this.ionStyle.emit({ + 'range-disabled': this.disabled }); } - fireBlur() { + private fireBlur() { if (this.hasFocus) { this.hasFocus = false; this.ionBlur.emit(); @@ -167,7 +167,7 @@ export class Range implements BaseInputComponent { } } - fireFocus() { + private fireFocus() { if (!this.hasFocus) { this.hasFocus = true; this.ionFocus.emit(); @@ -175,7 +175,7 @@ export class Range implements BaseInputComponent { } } - inputUpdated() { + private inputUpdated() { const val = this.value; if (this.dualKnobs) { this.valA = val.lower; @@ -189,7 +189,7 @@ export class Range implements BaseInputComponent { this.updateBar(); } - updateBar() { + private updateBar() { const ratioA = this.ratioA; const ratioB = this.ratioB; @@ -204,7 +204,7 @@ export class Range implements BaseInputComponent { this.updateTicks(); } - createTicks() { + private createTicks() { if (this.snaps) { for (let value = this.min; value <= this.max; value += this.step) { const ratio = this.valueToRatio(value); @@ -217,7 +217,7 @@ export class Range implements BaseInputComponent { } } - updateTicks() { + private updateTicks() { const ticks = this.ticks; const ratio = this.ratio; if (this.snaps && ticks) { @@ -235,28 +235,28 @@ export class Range implements BaseInputComponent { } } - valueToRatio(value: number) { + private valueToRatio(value: number) { value = Math.round((value - this.min) / this.step) * this.step; value = value / (this.max - this.min); return clamp(0, value, 1); } - ratioToValue(ratio: number) { + private ratioToValue(ratio: number) { ratio = Math.round((this.max - this.min) * ratio); ratio = Math.round(ratio / this.step) * this.step + this.min; return clamp(this.min, ratio, this.max); } - inputNormalize(val: any): any { - if (this.dualKnobs) { - return val; - } else { - val = parseFloat(val); - return isNaN(val) ? undefined : val; - } - } + // private inputNormalize(val: any): any { + // if (this.dualKnobs) { + // return val; + // } else { + // val = parseFloat(val); + // return isNaN(val) ? undefined : val; + // } + // } - update(current: { x: number; y: number }, rect: ClientRect, isPressed: boolean) { + private update(current: { x: number; y: number }, rect: ClientRect, isPressed: boolean) { // figure out where the pointer is currently at // update the knob being interacted with let ratio = clamp(0, (current.x - rect.left) / rect.width, 1); @@ -360,14 +360,14 @@ export class Range implements BaseInputComponent { this.updateBar(); } - onDragStart(detail: GestureDetail) { + private onDragStart(detail: GestureDetail) { if (this.disabled) return false; this.fireFocus(); const current = { x: detail.currentX, y: detail.currentY }; const el = this.el.querySelector('.range-slider')!; - this.rect = el.getBoundingClientRect(); - const rect = this.rect; + const rect = el.getBoundingClientRect(); + this.rect = rect; // figure out which knob they started closer to const ratio = clamp(0, (current.x - rect.left) / rect.width, 1); @@ -383,7 +383,7 @@ export class Range implements BaseInputComponent { return true; } - onDragEnd(detail: GestureDetail) { + private onDragEnd(detail: GestureDetail) { if (this.disabled) { return; } @@ -393,7 +393,7 @@ export class Range implements BaseInputComponent { this.fireBlur(); } - onDragMove(detail: GestureDetail) { + private onDragMove(detail: GestureDetail) { if (this.disabled) { return; } @@ -416,19 +416,17 @@ export class Range implements BaseInputComponent { return [ , + disableScroll={true} + onStart={this.onDragStart.bind(this)} + onMove={this.onDragMove.bind(this)} + onEnd={this.onDragEnd.bind(this)} + disabled={this.disabled} + gestureName='range' + gesturePriority={30} + type='pan' + direction='x' + threshold={0}> +
{this.ticks.map(t =>