diff --git a/core/src/components.d.ts b/core/src/components.d.ts index bec643e268..dad9532e9a 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -2980,7 +2980,7 @@ declare global { */ 'button': boolean; /** - * 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). + * The color to use for the background of the item. */ 'color': Color; /** @@ -3000,7 +3000,7 @@ declare global { */ 'lines': 'full' | 'inset' | 'none'; /** - * 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). + * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ 'mode': Mode; /** @@ -3034,7 +3034,7 @@ declare global { */ 'button'?: boolean; /** - * 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). + * The color to use for the background of the item. */ 'color'?: Color; /** @@ -3054,7 +3054,7 @@ declare global { */ 'lines'?: 'full' | 'inset' | 'none'; /** - * 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). + * The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. */ 'mode'?: Mode; /** diff --git a/core/src/components/item/item.tsx b/core/src/components/item/item.tsx index 874cd2ca78..991f81670a 100644 --- a/core/src/components/item/item.tsx +++ b/core/src/components/item/item.tsx @@ -1,7 +1,10 @@ import { Component, Element, Listen, Prop } from '@stencil/core'; import { Color, CssClassMap, Mode, RouterDirection } from '../../interface'; -import { createThemedClasses, getElementClassMap, openURL } from '../../utils/theme'; - +import { + createThemedClasses, + getElementClassMap, + openURL +} from '../../utils/theme'; @Component({ tag: 'ion-item', @@ -11,24 +14,21 @@ import { createThemedClasses, getElementClassMap, openURL } from '../../utils/th } }) export class Item { - private itemStyles: { [key: string]: CssClassMap } = {}; @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). + * The color to use for the background of the item. */ @Prop() color?: Color; /** * 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!: Mode; @@ -65,7 +65,6 @@ export class Item { */ @Prop() routerDirection?: RouterDirection; - @Listen('ionStyle') itemStyle(ev: UIEvent) { ev.stopPropagation(); @@ -110,15 +109,13 @@ export class Item { const clickable = !!(this.href || this.el.onclick || this.button); - const TagType = clickable - ? this.href ? 'a' : 'button' - : 'div'; + const TagType = clickable ? (this.href ? 'a' : 'button') : 'div'; - const attrs = (TagType === 'button') - ? { type: 'button' } - : { href: this.href }; + const attrs = + TagType === 'button' ? { type: 'button' } : { href: this.href }; - const showDetail = this.detail != null ? this.detail : (this.mode === 'ios' && clickable); + const showDetail = + this.detail != null ? this.detail : this.mode === 'ios' && clickable; const themedClasses = { ...childStyles, @@ -134,17 +131,18 @@ export class Item { openURL(this.win, this.href, ev, this.routerDirection)}> - + onClick={ev => openURL(this.win, this.href, ev, this.routerDirection)} + > +
- +
- +
- { clickable && this.mode === 'md' && } + {clickable && + this.mode === 'md' && }
); } - } diff --git a/core/src/components/item/readme.md b/core/src/components/item/readme.md index d1d2bfb6d2..6f19896224 100644 --- a/core/src/components/item/readme.md +++ b/core/src/components/item/readme.md @@ -7,20 +7,20 @@ Items are elements that can contain text, icons, avatars, images, inputs, and an By default, clickable items will display a right arrow icon on `ios` mode. To hide the right arrow icon on clickable elements, set the `detail` property to `false`. To show the right arrow icon on an item that doesn't display it naturally, add the `detail` attribute to the item. -This feature is not enabled by default on clickable items for the `md` mode, but it can be enabled by setting the following Sass variable: + + + + + -```scss -$item-md-detail-push-show: true; -``` - -It can also be turned off by default on clickable items for ios by setting the following Sass variable: - -```scss -$item-ios-detail-push-show: false; -``` - -See the [theming documentation](http://ionicframework.com/docs/theming/overriding-ionic-variables/) for more information on overriding Sass variables. + + + + + + + ## Item Placement @@ -28,11 +28,11 @@ Item uses named [slots](https://developer.mozilla.org/en-US/docs/Web/HTML/Elemen The below chart details the item slots and where it will place the element inside of the item: -| Slot | Description | -|---------|-----------------------------------------------------------------------------------| -| `start` | Placed to the left of all other content in LTR, and to the `right` in RTL. | -| `end` | Placed to the right of all other content in LTR, and to the `right` in RTL. | -| none | Placed inside of the input wrapper. | +| Slot | Description | +|---------|-----------------------------------------------------------------------------| +| `start` | Placed to the left of all other content in LTR, and to the `right` in RTL. | +| `end` | Placed to the right of all other content in LTR, and to the `right` in RTL. | +| none | Placed inside of the input wrapper. | ### Text Alignment @@ -56,9 +56,7 @@ If true, a button tag will be rendered and the item will be tappable. Defaults t string -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). +The color to use for the background of the item. #### detail @@ -97,7 +95,6 @@ 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). #### routerDirection @@ -121,9 +118,7 @@ If true, a button tag will be rendered and the item will be tappable. Defaults t string -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). +The color to use for the background of the item. #### detail @@ -162,7 +157,6 @@ 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). #### router-direction diff --git a/core/src/components/label/label.tsx b/core/src/components/label/label.tsx index 40a488691d..80f470f54b 100644 --- a/core/src/components/label/label.tsx +++ b/core/src/components/label/label.tsx @@ -1,7 +1,14 @@ -import { Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core'; +import { + Component, + Element, + Event, + EventEmitter, + Method, + Prop, + Watch +} from '@stencil/core'; import { Color, Mode, StyleEvent } from '../../interface'; - @Component({ tag: 'ion-label', styleUrls: { @@ -13,20 +20,16 @@ import { Color, Mode, StyleEvent } from '../../interface'; } }) export class Label { - @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). + * The color to use for the label's text */ @Prop() color?: Color; /** * 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!: Mode; @@ -54,7 +57,7 @@ export class Label { positionChanged() { const position = this.position; return this.ionStyle.emit({ - [`label-${position}`]: !!position, + [`label-${position}`]: !!position }); } diff --git a/core/src/components/label/readme.md b/core/src/components/label/readme.md index 80913523b2..c0601bba57 100644 --- a/core/src/components/label/readme.md +++ b/core/src/components/label/readme.md @@ -1,5 +1,5 @@ # ion-label - +Label is a wrapper element that can be used in combination with `ion-item`. diff --git a/core/src/components/label/usage/javascript.md b/core/src/components/label/usage/javascript.md new file mode 100644 index 0000000000..1f5e493227 --- /dev/null +++ b/core/src/components/label/usage/javascript.md @@ -0,0 +1,24 @@ +```html + + + Default + + + + Wrap label this label just goes on and on and on + + + + Fixed + + + + Floating + + + + Stacked + + + +``` diff --git a/core/src/components/list-header/list-header.tsx b/core/src/components/list-header/list-header.tsx index 8296099270..d52507fb97 100644 --- a/core/src/components/list-header/list-header.tsx +++ b/core/src/components/list-header/list-header.tsx @@ -1,7 +1,6 @@ import { Component, Prop } from '@stencil/core'; import { Color, Mode } from '../../interface'; - @Component({ tag: 'ion-list-header', styleUrls: { @@ -13,19 +12,14 @@ import { Color, Mode } from '../../interface'; } }) export class ListHeader { - /** - * 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). + * The color to use for the background. */ @Prop() color?: Color; /** * 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!: Mode; - } diff --git a/core/src/components/list-header/readme.md b/core/src/components/list-header/readme.md index 9f0d52557c..73a44642de 100644 --- a/core/src/components/list-header/readme.md +++ b/core/src/components/list-header/readme.md @@ -1,5 +1,5 @@ # ion-list-header - +List header a header component for a list. diff --git a/core/src/components/list-header/usage/javascript.md b/core/src/components/list-header/usage/javascript.md new file mode 100644 index 0000000000..ef3d82696c --- /dev/null +++ b/core/src/components/list-header/usage/javascript.md @@ -0,0 +1,12 @@ +```html + + + Items + + Item 1 + Item 2 + Item 3 + Item 4 + Item 5 + +``` diff --git a/core/src/components/list/list.tsx b/core/src/components/list/list.tsx index 069cdc4fc8..af7e0dfd40 100644 --- a/core/src/components/list/list.tsx +++ b/core/src/components/list/list.tsx @@ -58,5 +58,4 @@ export class List { } }; } - } diff --git a/core/src/components/loading-controller/loading-controller.tsx b/core/src/components/loading-controller/loading-controller.tsx index 2fa1c06c83..cde8cbe859 100644 --- a/core/src/components/loading-controller/loading-controller.tsx +++ b/core/src/components/loading-controller/loading-controller.tsx @@ -28,7 +28,7 @@ export class LoadingController implements OverlayController { removeLastOverlay(this.loadings); } - /* + /** * Create a loading overlay with loading options. */ @Method() @@ -36,7 +36,7 @@ export class LoadingController implements OverlayController { return createOverlay(this.doc.createElement('ion-loading'), opts); } - /* + /** * Dismiss the open loading overlay. */ @Method() @@ -44,7 +44,7 @@ export class LoadingController implements OverlayController { return dismissOverlay(data, role, this.loadings, loadingId); } - /* + /** * Get the most recently opened loading overlay. */ @Method() diff --git a/core/src/components/loading-controller/readme.md b/core/src/components/loading-controller/readme.md index fc9f26af64..67ecd80215 100644 --- a/core/src/components/loading-controller/readme.md +++ b/core/src/components/loading-controller/readme.md @@ -3,19 +3,6 @@ Loading controllers programmatically control the loading component. Loadings can be created and dismissed from the loading controller. View the [Loading](../../loading/Loading) documentation for a full list of options to pass upon creation. -```javascript -async function presentLoading() { - const loadingController = document.querySelector('ion-loading-controller'); - await loadingController.componentOnReady(); - - const loadingElement = await loadingController.create({ - content: 'Please wait...', - spinner: 'crescent', - duration: 2000 - }); - return await loadingElement.present(); -} -``` diff --git a/core/src/components/loading-controller/usage/javascript.md b/core/src/components/loading-controller/usage/javascript.md new file mode 100644 index 0000000000..9999484bb6 --- /dev/null +++ b/core/src/components/loading-controller/usage/javascript.md @@ -0,0 +1,13 @@ +```javascript +async function presentLoading() { + const loadingController = document.querySelector('ion-loading-controller'); + await loadingController.componentOnReady(); + + const loadingElement = await loadingController.create({ + content: 'Please wait...', + spinner: 'crescent', + duration: 2000 + }); + return await loadingElement.present(); +} +``` diff --git a/core/src/components/loading/loading.tsx b/core/src/components/loading/loading.tsx index cdbc922446..2720570b71 100644 --- a/core/src/components/loading/loading.tsx +++ b/core/src/components/loading/loading.tsx @@ -1,6 +1,27 @@ -import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, Color, Config, Mode } from '../../interface'; -import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; +import { + Component, + Element, + Event, + EventEmitter, + Listen, + Method, + Prop +} from '@stencil/core'; +import { + Animation, + AnimationBuilder, + Color, + Config, + Mode +} from '../../interface'; +import { + BACKDROP, + OverlayEventDetail, + OverlayInterface, + dismiss, + eventMethod, + present +} from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; import { iosEnterAnimation } from './animations/ios.enter'; @@ -20,7 +41,6 @@ import { mdLeaveAnimation } from './animations/md.leave'; } }) export class Loading implements OverlayInterface { - private durationTimeout: any; presented = false; @@ -30,8 +50,10 @@ export class Loading implements OverlayInterface { @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() keyboardClose = true; @@ -105,28 +127,36 @@ export class Loading implements OverlayInterface { /** * 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) { - this.spinner = this.config.get('loadingSpinner', this.mode === 'ios' ? 'lines' : 'crescent'); + this.spinner = this.config.get( + 'loadingSpinner', + this.mode === 'ios' ? 'lines' : 'crescent' + ); } } + componentDidLoad() { this.ionLoadingDidLoad.emit(); } @@ -145,10 +175,19 @@ export class Loading implements OverlayInterface { */ @Method() async present(): Promise { - await present(this, 'loadingEnter', iosEnterAnimation, mdEnterAnimation, undefined); + await present( + this, + 'loadingEnter', + iosEnterAnimation, + mdEnterAnimation, + undefined + ); if (this.duration) { - this.durationTimeout = setTimeout(() => this.dismiss(), this.duration + 10); + this.durationTimeout = setTimeout( + () => this.dismiss(), + this.duration + 10 + ); } } @@ -160,19 +199,25 @@ export class Loading implements OverlayInterface { if (this.durationTimeout) { clearTimeout(this.durationTimeout); } - return dismiss(this, data, role, 'loadingLeave', iosLeaveAnimation, mdLeaveAnimation); + return dismiss( + this, + data, + role, + 'loadingLeave', + iosLeaveAnimation, + mdLeaveAnimation + ); } /** * Returns a promise that resolves when the loading did dismiss. It also accepts a callback * that is called in the same circustances. * - * ``` - * const {data, role} = await loading.onDidDismiss(); - * ``` */ @Method() - onDidDismiss(callback?: (detail: OverlayEventDetail) => void): Promise { + onDidDismiss( + callback?: (detail: OverlayEventDetail) => void + ): Promise { return eventMethod(this.el, 'ionLoadingDidDismiss', callback); } @@ -185,16 +230,20 @@ export class Loading implements OverlayInterface { * ``` */ @Method() - onWillDismiss(callback?: (detail: OverlayEventDetail) => void): Promise { + onWillDismiss( + callback?: (detail: OverlayEventDetail) => void + ): Promise { return eventMethod(this.el, 'ionLoadingWillDismiss', callback); } hostData() { - const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'loading-translucent') : {}; + const themedClasses = this.translucent + ? createThemedClasses(this.mode, this.color, 'loading-translucent') + : {}; return { style: { - zIndex: 20000 + this.overlayId, + zIndex: 20000 + this.overlayId }, class: { ...themedClasses, @@ -207,13 +256,13 @@ export class Loading implements OverlayInterface { return [ , ]; } diff --git a/core/src/components/loading/usage/angular.md b/core/src/components/loading/usage/angular.md index d7abd229f8..4fb27e5f61 100644 --- a/core/src/components/loading/usage/angular.md +++ b/core/src/components/loading/usage/angular.md @@ -18,7 +18,7 @@ export class LoadingExample { return await loading.present(); } - presentLoadingWithOptions() { + async presentLoadingWithOptions() { const loading = await this.loadingController.create({ spinner: 'hide', duration: 5000, diff --git a/core/src/components/menu-button/menu-button.tsx b/core/src/components/menu-button/menu-button.tsx index 607d7e4181..deed5e5c23 100644 --- a/core/src/components/menu-button/menu-button.tsx +++ b/core/src/components/menu-button/menu-button.tsx @@ -12,8 +12,8 @@ import { Config } from '../../interface'; } }) export class MenuButton { - - @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 diff --git a/core/src/components/menu-button/readme.md b/core/src/components/menu-button/readme.md index 9cd409b6c9..ee9b5b51cd 100644 --- a/core/src/components/menu-button/readme.md +++ b/core/src/components/menu-button/readme.md @@ -1,5 +1,6 @@ # ion-menu-button +Menu Button is component that automatically creates the icon and functionality to open a menu on a page. diff --git a/core/src/components/menu-controller/menu-controller.ts b/core/src/components/menu-controller/menu-controller.ts index e2c3f8842a..311c3cbe24 100644 --- a/core/src/components/menu-controller/menu-controller.ts +++ b/core/src/components/menu-controller/menu-controller.ts @@ -9,11 +9,11 @@ import { menuRevealAnimation } from './animations/reveal'; tag: 'ion-menu-controller' }) 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); @@ -22,9 +22,7 @@ export class MenuController { } /** - * Programatically open the Menu. - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {Promise} returns a promise when the menu is fully opened + * Open the Menu. */ @Method() open(menuId?: string): Promise { @@ -36,17 +34,13 @@ export class MenuController { } /** - * Programatically close the Menu. If no `menuId` is given as the first + * Close the Menu. If no `menuId` is given as the first * argument then it'll close any menu which is open. If a `menuId` * is given then it'll close that exact menu. - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {Promise} returns a promise when the menu is fully closed */ @Method() close(menuId?: string): Promise { - const menu = (menuId) - ? this.get(menuId) - : this.getOpen(); + const menu = menuId ? this.get(menuId) : this.getOpen(); if (menu) { return menu.close(); @@ -57,8 +51,6 @@ export class MenuController { /** * Toggle the menu. If it's closed, it will open, and if opened, it * will close. - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {Promise} returns a promise when the menu has been toggled */ @Method() toggle(menuId?: string): Promise { @@ -74,11 +66,9 @@ export class MenuController { * left menus, but only one of them should be able to be opened at the same * time. If there are multiple menus on the same side, then enabling one menu * will also automatically disable all the others that are on the same side. - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {HTMLIonMenuElement} Returns the instance of the menu, which is useful for chaining. */ @Method() - enable(shouldEnable: boolean, menuId?: string): HTMLIonMenuElement|null { + enable(shouldEnable: boolean, menuId?: string): HTMLIonMenuElement | null { const menu = this.get(menuId); if (menu) { menu.disabled = !shouldEnable; @@ -88,12 +78,12 @@ export class MenuController { /** * Used to enable or disable the ability to swipe open the menu. - * @param {boolean} shouldEnable True if it should be swipe-able, false if not. - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {HTMLIonMenuElement} Returns the instance of the menu, which is useful for chaining. */ @Method() - swipeEnable(shouldEnable: boolean, menuId?: string): HTMLIonMenuElement|null { + swipeEnable( + shouldEnable: boolean, + menuId?: string + ): HTMLIonMenuElement | null { const menu = this.get(menuId); if (menu) { menu.swipeEnabled = shouldEnable; @@ -102,22 +92,19 @@ export class MenuController { } /** - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {boolean} Returns true if the specified menu is currently open, otherwise false. * If the menuId is not specified, it returns true if ANY menu is currenly open. */ @Method() isOpen(menuId?: string): boolean { if (menuId) { const menu = this.get(menuId); - return menu && menu.isOpen() || false; + return (menu && menu.isOpen()) || false; } return !!this.getOpen(); } /** - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {boolean} Returns true if the menu is currently enabled, otherwise false. + * Returns true or false if the menuId is enabled or not */ @Method() isEnabled(menuId?: string): boolean { @@ -134,8 +121,6 @@ export class MenuController { * it'll return the enabled menu on that side. Otherwise, if a `menuId` is * provided, then it'll try to find the menu using the menu's `id` * property. If a menu is not found then it'll return `null`. - * @param {string} [menuId] Optionally get the menu by its id, or side. - * @return {HTMLIonMenuElement} Returns the instance of the menu if found, otherwise `null`. */ @Method() get(menuId?: string): HTMLIonMenuElement | null { @@ -147,7 +132,7 @@ export class MenuController { console.error('menu.side=right is deprecated, use "end" instead'); return null; } - if (menuId === 'start' || menuId === 'end' ) { + if (menuId === 'start' || menuId === 'end') { // there could be more than one menu on the same side // so first try to get the enabled one const menu = this.find(m => m.side === menuId && !m.disabled); @@ -158,7 +143,6 @@ export class MenuController { // didn't find a menu side that is enabled // so try to get the first menu side found return this.find(m => m.side === menuId) || null; - } else if (menuId) { // the menuId was not left or right // so try to get the menu by its "id" @@ -172,19 +156,19 @@ export class MenuController { } // get the first menu in the array, if one exists - return (this.menus.length > 0 ? this.menus[0].el : null); + return this.menus.length > 0 ? this.menus[0].el : null; } /** - * @return {Menu} Returns the instance of the menu already opened, otherwise `null`. + * Returns the instance of the menu already opened, otherwise `null`. */ @Method() - getOpen(): HTMLIonMenuElement|null { + getOpen(): HTMLIonMenuElement | null { return this.find(m => m.isOpen()); } /** - * @return {Array} Returns an array of all menu instances. + * Returns an array of all menu instances. */ @Method() getMenus(): HTMLIonMenuElement[] { @@ -192,17 +176,13 @@ export class MenuController { } /** - * @hidden - * @return {boolean} if any menu is currently animating + * If any menu is currently animating */ @Method() isAnimating(): boolean { return this.menus.some(menu => menu.isAnimating); } - /** - * @hidden - */ @Method() _register(menu: Menu) { if (this.menus.indexOf(menu) < 0) { @@ -210,9 +190,6 @@ export class MenuController { } } - /** - * @hidden - */ @Method() _unregister(menu: Menu) { const index = this.menus.indexOf(menu); @@ -221,9 +198,6 @@ export class MenuController { } } - /** - * @hidden - */ @Method() _setActiveMenu(menu: Menu) { // if this menu should be enabled @@ -232,14 +206,15 @@ export class MenuController { const side = menu.side; this.menus .filter(m => m.side === side && m !== menu) - .forEach(m => m.disabled = true); + .forEach(m => (m.disabled = true)); } - /** - * @hidden - */ @Method() - _setOpen(menu: Menu, shouldOpen: boolean, animated: boolean): Promise { + _setOpen( + menu: Menu, + shouldOpen: boolean, + animated: boolean + ): Promise { if (this.isAnimating()) { return Promise.resolve(false); } @@ -252,9 +227,6 @@ export class MenuController { return menu._setOpen(shouldOpen, animated); } - /** - * @hidden - */ @Method() createAnimation(type: string, menuCmp: Menu): Promise { const animationBuilder = this.menuAnimations.get(type); @@ -269,14 +241,13 @@ export class MenuController { this.menuAnimations.set(name, animation); } - private find(predicate: (menu: Menu) => boolean): HTMLIonMenuElement|null { + private find(predicate: (menu: Menu) => boolean): HTMLIonMenuElement | null { const instance = this.menus.find(predicate); if (instance) { return instance.el; } return null; } - } export { menuOverlayAnimation, menuPushAnimation, menuRevealAnimation }; diff --git a/core/src/components/menu-controller/readme.md b/core/src/components/menu-controller/readme.md index 72f10a37fa..7cd3921dbc 100644 --- a/core/src/components/menu-controller/readme.md +++ b/core/src/components/menu-controller/readme.md @@ -1,5 +1,6 @@ # ion-menu-controller +The MenuController makes it easy to control a Menu. Its methods can be used to display the menu, enable the menu, toggle the menu, and more. The controller will grab a reference to the menu by the side, id, or, if neither of these are passed to it, it will grab the first menu it finds. diff --git a/core/src/components/menu-toggle/menu-toggle.tsx b/core/src/components/menu-toggle/menu-toggle.tsx index ec15e71929..962c5d9d8d 100644 --- a/core/src/components/menu-toggle/menu-toggle.tsx +++ b/core/src/components/menu-toggle/menu-toggle.tsx @@ -5,19 +5,20 @@ import { Component, Listen, Prop, State } from '@stencil/core'; styleUrl: 'menu-toggle.scss' }) 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 + * 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; /** - * Automatically hides the content when the corresponding menu is not - * active + * Automatically hides the content when the corresponding menu is not active */ @Prop() autoHide = true; @@ -54,15 +55,16 @@ export class MenuToggle { hostData() { const hidden = this.autoHide && !this.visible; return { - class: { + class: { 'menu-toggle-hidden': hidden } }; } - } -function getMenuController(doc: Document): Promise { +function getMenuController( + doc: Document +): Promise { const menuControllerElement = doc.querySelector('ion-menu-controller'); if (!menuControllerElement) { return Promise.resolve(null); diff --git a/core/src/components/menu-toggle/readme.md b/core/src/components/menu-toggle/readme.md index a29e55a641..41692c0424 100644 --- a/core/src/components/menu-toggle/readme.md +++ b/core/src/components/menu-toggle/readme.md @@ -1,5 +1,5 @@ # ion-menu-toggle - +The MenuToggle component can be used to toggle a menu open or closed. diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index 0860308768..b3c4dd7bc9 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -1,5 +1,23 @@ -import { Component, Element, Event, EventEmitter, EventListenerEnable, Listen, Method, Prop, State, Watch } from '@stencil/core'; -import { Animation, Color, Config, GestureDetail, MenuChangeEventDetail, Mode } from '../../interface'; +import { + Component, + Element, + Event, + EventEmitter, + EventListenerEnable, + Listen, + Method, + Prop, + State, + Watch +} from '@stencil/core'; +import { + Animation, + Color, + Config, + GestureDetail, + MenuChangeEventDetail, + Mode +} from '../../interface'; import { Side, assert, isEndSide } from '../../utils/helpers'; @Component({ @@ -13,7 +31,6 @@ import { Side, assert, isEndSide } from '../../utils/helpers'; } }) export class Menu { - private animation?: Animation; private isPane = false; private _isOpen = false; @@ -33,11 +50,20 @@ export class Menu { @State() isEndSide = 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. @@ -50,11 +76,11 @@ export class Menu { @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"`. + * The display type of the menu. + * Available options: `"overlay"`, `"reveal"`, `"push"`. */ - @Prop({ mutable: true }) type!: string; + @Prop({ mutable: true }) + type!: string; @Watch('type') typeChanged(type: string, oldType: string | null) { @@ -74,12 +100,13 @@ export class Menu { /** * If true, the menu is disabled. Default `false`. */ - @Prop({ mutable: true }) disabled = false; + @Prop({ mutable: true }) + disabled = false; @Watch('disabled') protected disabledChanged(disabled: boolean) { this.updateState(); - this.ionMenuChange.emit({ disabled: disabled, open: this._isOpen}); + this.ionMenuChange.emit({ disabled: disabled, open: this._isOpen }); } /** @@ -107,6 +134,10 @@ export class Menu { */ @Prop() persistent = false; + /** + * The edge threshold for dragging the menu open. + * If a drag/swipe happens over this value, the menu is not triggered. + */ @Prop() maxEdgeStart = 50; /** @@ -119,7 +150,6 @@ export class Menu { */ @Event() ionClose!: EventEmitter; - @Event() protected ionMenuChange!: EventEmitter; async componentWillLoad() { @@ -139,13 +169,15 @@ export class Menu { } const el = this.el; const parent = el.parentNode as any; - const content = (this.contentId) + const content = this.contentId ? document.getElementById(this.contentId) : parent && parent.querySelector && parent.querySelector('[main]'); if (!content || !content.tagName) { // requires content element - console.error('Menu: must have a "content" element to listen for drag events on.'); + console.error( + 'Menu: must have a "content" element to listen for drag events on.' + ); return; } this.contentEl = content as HTMLElement; @@ -165,7 +197,7 @@ export class Menu { } // register this menu with the app's menu controller this.menuCtrl!._register(this); - this.ionMenuChange.emit({ disabled: !isEnabled, open: this._isOpen}); + this.ionMenuChange.emit({ disabled: !isEnabled, open: this._isOpen }); // mask it as enabled / disabled this.disabled = !isEnabled; @@ -188,7 +220,7 @@ export class Menu { @Listen('body:click', { enabled: false, capture: true }) onBackdropClick(ev: UIEvent) { const el = ev.target as HTMLElement; - if (!el.closest('.menu-inner') && this.lastOnEnd < (ev.timeStamp - 100)) { + if (!el.closest('.menu-inner') && this.lastOnEnd < ev.timeStamp - 100) { ev.preventDefault(); ev.stopPropagation(); this.close(); @@ -222,7 +254,7 @@ export class Menu { async _setOpen(shouldOpen: boolean, animated = true): Promise { // If the menu is disabled or it is currenly being animated, let's do nothing - if (!this.isActive() || this.isAnimating || (shouldOpen === this._isOpen)) { + if (!this.isActive() || this.isAnimating || shouldOpen === this._isOpen) { return this._isOpen; } @@ -257,7 +289,10 @@ export class Menu { this.animation = await this.menuCtrl!.createAnimation(this.type, this); } - private async startAnimation(shouldOpen: boolean, animated: boolean): Promise { + private async startAnimation( + shouldOpen: boolean, + animated: boolean + ): Promise { const ani = this.animation!.reverse(!shouldOpen); if (animated) { await ani.playAsync(); @@ -267,9 +302,7 @@ export class Menu { } private canSwipe(): boolean { - return this.swipeEnabled && - !this.isAnimating && - this.isActive(); + return this.swipeEnabled && !this.isAnimating && this.isActive(); } private canStart(detail: GestureDetail): boolean { @@ -281,7 +314,12 @@ export class Menu { } else if (this.menuCtrl!.getOpen()) { return false; } - return checkEdgeSide(this.win, detail.currentX, this.isEndSide, this.maxEdgeStart); + return checkEdgeSide( + this.win, + detail.currentX, + this.isEndSide, + this.maxEdgeStart + ); } private onWillStart(): Promise { @@ -296,9 +334,7 @@ export class Menu { } // the cloned animation should not use an easing curve during seek - this.animation - .reverse(this._isOpen) - .progressStart(); + this.animation.reverse(this._isOpen).progressStart(); } private onDragMove(detail: GestureDetail) { @@ -324,17 +360,17 @@ export class Menu { const stepValue = delta / width; const velocity = detail.velocityX; const z = width / 2.0; - const shouldCompleteRight = (velocity >= 0) - && (velocity > 0.2 || detail.deltaX > z); + const shouldCompleteRight = + velocity >= 0 && (velocity > 0.2 || detail.deltaX > z); - const shouldCompleteLeft = (velocity <= 0) - && (velocity < -0.2 || detail.deltaX < -z); + const shouldCompleteLeft = + velocity <= 0 && (velocity < -0.2 || detail.deltaX < -z); - const shouldComplete = (isOpen) + const shouldComplete = isOpen ? isEndSide ? shouldCompleteRight : shouldCompleteLeft : isEndSide ? shouldCompleteLeft : shouldCompleteRight; - let shouldOpen = (!isOpen && shouldComplete); + let shouldOpen = !isOpen && shouldComplete; if (isOpen && !shouldComplete) { shouldOpen = true; } @@ -349,7 +385,9 @@ export class Menu { this.lastOnEnd = detail.timeStamp; this.animation - .onFinish(() => this.afterAnimation(shouldOpen), { clearExistingCallacks: true }) + .onFinish(() => this.afterAnimation(shouldOpen), { + clearExistingCallacks: true + }) .progressEnd(shouldComplete, stepValue, realDur); } @@ -382,7 +420,6 @@ export class Menu { // emit open event this.ionOpen.emit(); - } else { // remove css classes this.el.classList.remove(SHOW_MENU); @@ -425,22 +462,23 @@ export class Menu { [`menu-type-${this.type}`]: true, 'menu-enabled': !this.disabled, 'menu-side-right': isEndSide, - 'menu-side-left': !isEndSide, + 'menu-side-left': !isEndSide } }; } render() { - return ([ -