From 17ad73ace2d04ec960f9daf62bbdfc6a4196c86e Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Wed, 29 May 2019 17:19:42 -0400 Subject: [PATCH] docs(readme): move usages from readme to usage folder (#18384) closes ionic-team/ionic-docs#664 closes ionic-team/ionic-docs#550 closes ionic-team/ionic-docs#148 --- .../src/components/alert-controller/readme.md | 18 +- core/src/components/datetime/readme.md | 94 +++----- core/src/components/loading/readme.md | 2 +- core/src/components/modal/readme.md | 208 ++++++++++++------ core/src/components/modal/usage/angular.md | 99 +++++++-- core/src/components/modal/usage/javascript.md | 63 +++++- core/src/components/route-redirect/readme.md | 105 +++++---- .../route-redirect/usage/javascript.md | 41 ++++ core/src/components/split-pane/readme.md | 26 +-- core/src/components/tabs/readme.md | 156 +++++++------ core/src/components/tabs/usage/angular.md | 44 ++++ core/src/components/tabs/usage/javascript.md | 36 +++ core/src/components/virtual-scroll/readme.md | 161 +++++++------- .../virtual-scroll/usage/angular.md | 71 +++++- 14 files changed, 729 insertions(+), 395 deletions(-) create mode 100644 core/src/components/route-redirect/usage/javascript.md diff --git a/core/src/components/alert-controller/readme.md b/core/src/components/alert-controller/readme.md index 257a3bb170..f21939495a 100644 --- a/core/src/components/alert-controller/readme.md +++ b/core/src/components/alert-controller/readme.md @@ -1,22 +1,6 @@ # ion-alert-controller -Alert controllers programmatically control the alert component. Alerts can be created and dismissed from the alert controller. View the [Alert](../alert) documentation for a full list of options to pass upon creation. - - -```javascript -async function presentAlert() { - const alertController = document.querySelector('ion-alert-controller'); - await alertController.componentOnReady(); - - const alert = await alertController.create({ - header: 'Alert', - subHeader: 'Subtitle', - message: 'This is an alert message.', - buttons: ['OK'] - }); - return await alert.present(); -} -``` +Alert controllers programmatically control the alert component. Alerts can be created and dismissed by the alert controller. View the [Alert](../alert) documentation for the list of options to pass upon creation and usage information. diff --git a/core/src/components/datetime/readme.md b/core/src/components/datetime/readme.md index 69b627e2ae..4f9fdb2962 100644 --- a/core/src/components/datetime/readme.md +++ b/core/src/components/datetime/readme.md @@ -1,10 +1,11 @@ # ion-datetime -Datetimes present a picker interface from the bottom of a page, making it easy for users to select -dates and times. The picker displays scrollable columns that can be used to individually select years, -months, days, hours and minute values. Datetimes are similar to the native `input` elements of type -`datetime-local`, however, Ionic's Datetime component makes it easy to display the date and time in a -preferred format, and manage the datetime values. +Datetimes present a picker interface from the bottom of a page, making it easy for +users to select dates and times. The picker displays scrollable columns that can be +used to individually select years, months, days, hours and minute values. Datetimes +are similar to the native `input` elements of type `datetime-local`, however, Ionic's +Datetime component makes it easy to display the date and time in a preferred format, +and manage the datetime values. ## Display and Picker Formats @@ -43,43 +44,33 @@ different names for the month and day. ### Display Format -The `displayFormat` input property specifies how a datetime's value should be +The `displayFormat` property specifies how a datetime's value should be printed, as formatted text, within the datetime component. -In the following example, the display in the `` will use the -month's short name, the numerical day with a leading zero, a comma and the -four-digit year. In addition to the date, it will display the time with the -hours in the 24-hour format and the minutes. Any character can be used as a -separator. An example display using this format is: `Jun 17, 2005 11:06`. +A few examples are provided in the chart below. The formats mentioned +above can be passed in to the display format in any combination. -```html - - Date - - -``` +| Display Format | Example | +| ----------------------| ----------------------- | +| `M-YYYY` | `6-2005` | +| `MM/YY` | `06/05` | +| `MMM YYYY` | `Jun 2005` | +| `YYYY, MMMM` | `2005, June` | +| `MMM DD, YYYY HH:mm` | `Jun 17, 2005 11:06` | **Important**: `ion-datetime` will always display values relative to the user's timezone. Given a value of `09:00:00+01:00`, the datetime component will display it as `04:00:00-04:00` for users in a `-04:00` timezone offset. + ### Picker Format -The `pickerFormat` input property determines which columns should be shown in -the interface, the order of the columns, and which format to use within each -column. If the `pickerFormat` input is not provided then it will default to the -`displayFormat`. +The `pickerFormat` property determines which columns should be shown in the picker +interface, the order of the columns, and which format to use within each +column. If `pickerFormat` is not provided then it will use the value of +`displayFormat`. Refer to the chart in the [Display Format](#display-format) section +for some formatting examples. -In the following example, the display in the `` will use the -`MM/YYYY` format, such as `06/2020`. However, the picker interface will display -two columns with the month's long name, and the four-digit year. - -```html - - Date - - -``` ### Datetime Data @@ -138,52 +129,33 @@ the maximum date is to the end of the current year, and the minimum date is from the beginning of the year that was 100 years ago. To customize the minimum and maximum datetime values, the `min` and `max` -component inputs can be provided which may make more sense for the app's +component properties can be provided which may make more sense for the app's use-case, rather than the default of the last 100 years. Following the same IS0 8601 format listed in the table above, each component can restrict which dates -can be selected by the user. Below is an example of restricting the date -selection between the beginning of 2016, and October 31st of 2020: +can be selected by the user. By passing `2016` to the `min` property and `2020-10-31` +to the `max` property, the datetime will restrict the date selection between the +beginning of 2016, and October 31st of 2020. -```html - - Date - - -``` ## Month Names and Day of the Week Names At this time, there is no one-size-fits-all standard to automatically choose the correct language/spelling for a month name, or day of the week name, depending -on the language or locale. +on the language or locale. The good news is that there is an [Intl.DatetimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DatetimeFormat) standard which [most browsers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DatetimeFormat#Browser_compatibility) have adopted. However, at this time the standard has not been fully implemented by all popular browsers -so Ionic is unavailable to take advantage of it yet. +so Ionic is unavailable to take advantage of it yet. Additionally, Angular also provides an internationalization service, but it is still under heavy development so Ionic does not depend on it at this time. -The current best practice is to provide an array of names if the app needs to use names other -than the default English version of month and day names. The month names and day names can be +The current best practice is to provide an array of names if the app needs to use names other +than the default English version of month and day names. The month names and day names can be either configured at the app level, or individual `ion-datetime` level. -### Component Input Level - -```html - - Período - - - -``` ### Advanced Datetime Validation and Manipulation @@ -197,12 +169,6 @@ subtracting 30 minutes, etc.), or even formatting data to a specific locale, then we highly recommend using [date-fns](https://date-fns.org) to work with dates in JavaScript. -```html - - Date - - -``` diff --git a/core/src/components/loading/readme.md b/core/src/components/loading/readme.md index 3569f67142..970a9ffe9e 100644 --- a/core/src/components/loading/readme.md +++ b/core/src/components/loading/readme.md @@ -5,7 +5,7 @@ An overlay that can be used to indicate activity while blocking user interaction ### Creating -Loading indicators can be created using a [Loading Controller](../loading-controller). They can be customized by passing loading options in the loading controller's create method. The spinner name should be passed in the `spinner` property. If a value is not passed to `spinner` the loading indicator will use the spinner specified by the platform. +Loading indicators can be created using a [Loading Controller](../loading-controller). They can be customized by passing loading options in the loading controller's `create()` method. The spinner name should be passed in the `spinner` property. If a value is not passed to `spinner` the loading indicator will use the spinner specified by the platform. ### Dismissing diff --git a/core/src/components/modal/readme.md b/core/src/components/modal/readme.md index fd6c59a2dd..030e009033 100644 --- a/core/src/components/modal/readme.md +++ b/core/src/components/modal/readme.md @@ -5,53 +5,13 @@ A Modal is a dialog that appears on top of the app's content, and must be dismis ### Creating -Modals can be created using a [Modal Controller](../modal-controller). They can be customized by passing modal options in the modal controller's create method. +Modals can be created using a [Modal Controller](../modal-controller). They can be customized by passing modal options in the modal controller's `create()` method. -### Passing parameters +### Dismissing -When a modal is created, parameters might be passed to the newly created modal: +The modal can be dismissed after creation by calling the `dismiss()` method on the modal controller. The `onDidDismiss` function can be called to perform an action after the modal is dismissed. -```ts -// Create a modal using MyModalComponent with some initial data -const modal = await modalController.create({ - component: MyModalComponent, - componentProps: { - 'prop1': value, - 'prop2': value2 - } -}); -``` - -Under the hood, the controller creates a new `ion-modal` and attaches the specified component to it. -It also assigns the specified `componentProps` to the component's instance: - -```js -// pseudo-code -const instance = create(MyModalComponent); -instance.prop1 = value; -instance.prop2 = value2; -``` - -This way, your component can access the passed params, check the "Usage" section for further code example for each frameworks. - - -### Returning data - -Modals can also return data back to the controller when they are dismissed. - -```js -const modal = await modalController.create({...}); -const { data } = await modal.onDidDismiss(); -console.log(data); -``` - -```js -// Dismiss the top modal returning some data object -modalController.dismiss({ - 'result': value -}) -``` @@ -64,18 +24,20 @@ modalController.dismiss({ import { Component } from '@angular/core'; import { ModalController } from '@ionic/angular'; import { ModalPage } from '../modal/modal.page'; + @Component({ selector: 'modal-example', templateUrl: 'modal-example.html', styleUrls: ['./modal-example.css'] }) export class ModalExample { - constructor(public modalController: ModalController) {} + constructor(public modalController: ModalController) { + + } async presentModal() { const modal = await this.modalController.create({ - component: ModalPage, - componentProps: { value: 123 } + component: ModalPage }); return await modal.present(); } @@ -89,18 +51,77 @@ import { NavParams } from '@ionic/angular'; @Component({ selector: 'modal-page', }) -export class ModalExample { +export class ModalPage { - // "value" passed in componentProps - @Input() value: number; + constructor() { - constructor(navParams: NavParams) { - // componentProps can also be accessed at construction time using NavParams } } ``` +### Passing Data + +During creation of a modal, data can be passed in through the `componentProps`. The previous example can be written to include data: + +```typescript +async presentModal() { + const modal = await this.modalController.create({ + component: ModalPage, + componentProps: { + 'firstName': 'Douglas', + 'lastName': 'Adams', + 'middleInitial': 'N' + } + }); + return await modal.present(); +} +``` + +To get the data passed into the `componentProps`, either set it as an `@Input` or access it via `NavParams` on the `ModalPage`: + +```typescript +export class ModalPage { + + // Data passed in by componentProps + @Input() firstName: string; + @Input() lastName: string; + @Input() middleInitial: string; + + constructor(navParams: NavParams) { + // componentProps can also be accessed at construction time using NavParams + console.log(navParams.get('firstName'); + } + +} +``` + +### Dismissing a Modal + +A modal can be dismissed by calling the dismiss method on the modal controller and optionally passing any data from the modal. + +```javascript +export class ModalPage { + ... + + dismiss() { + // using the injected ModalController this page + // can "dismiss" itself and optionally pass back data + this.modalCtrl.dismiss({ + 'dismissed': true + }); + } +} +``` + +After being dismissed, the data can be read in through the `onWillDismiss` or `onDidDismiss` attached to the modal after creation: + +```javascript +const { data } = await modal.onWillDismiss(); +console.log(data); +``` + + #### Lazy Loading When lazy loading a modal, it's important to note that the modal will not be loaded when it is opened, but rather when the module that imports the modal's module is loaded. @@ -116,17 +137,17 @@ import { CalendarComponent } from './calendar.component'; import { EventModalModule } from '../modals/event/event.module'; @NgModule({ - declarations: [ - CalendarComponent - ], - imports: [ - IonicModule, - CommonModule, - EventModalModule - ], - exports: [ - CalendarComponent - ] + declarations: [ + CalendarComponent + ], + imports: [ + IonicModule, + CommonModule, + EventModalModule + ], + exports: [ + CalendarComponent + ] }) export class CalendarComponentModule {} @@ -147,11 +168,16 @@ customElements.define('modal-page', class extends HTMLElement { this.innerHTML = ` - Super Modal + Modal Header + + + + + - - Content + + Modal Content `; } }); @@ -161,14 +187,64 @@ async function presentModal() { const modalController = document.querySelector('ion-modal-controller'); await modalController.componentOnReady(); - // present the modal + // create the modal with the `modal-page` component const modalElement = await modalController.create({ component: 'modal-page' }); + + // present the modal await modalElement.present(); } ``` +### Passing Data + +During creation of a modal, data can be passed in through the `componentProps`. The previous example can be written to include data: + +```javascript +const modalElement = await modalController.create({ + component: 'modal-page', + componentProps: { + 'firstName': 'Douglas', + 'lastName': 'Adams', + 'middleInitial': 'N' + } +}); +``` + +To get the data passed into the `componentProps`, query for the modal in the `modal-page`: + +```js +customElements.define('modal-page', class extends HTMLElement { + connectedCallback() { + const modalElement = document.querySelector('ion-modal'); + console.log(modalElement.componentProps.firstName); + + ... + } +} +``` + + +### Dismissing a Modal + +A modal can be dismissed by calling the dismiss method on the modal controller and optionally passing any data from the modal. + +```javascript +async function dismissModal() { + await modalController.dismiss({ + 'dismissed': true + }); +} +``` + +After being dismissed, the data can be read in through the `onWillDismiss` or `onDidDismiss` attached to the modal after creation: + +```javascript +const { data } = await modalElement.onWillDismiss(); +console.log(data); +``` + ### React diff --git a/core/src/components/modal/usage/angular.md b/core/src/components/modal/usage/angular.md index 358053f321..8fbec8a0d5 100644 --- a/core/src/components/modal/usage/angular.md +++ b/core/src/components/modal/usage/angular.md @@ -2,18 +2,20 @@ import { Component } from '@angular/core'; import { ModalController } from '@ionic/angular'; import { ModalPage } from '../modal/modal.page'; + @Component({ selector: 'modal-example', templateUrl: 'modal-example.html', styleUrls: ['./modal-example.css'] }) export class ModalExample { - constructor(public modalController: ModalController) {} + constructor(public modalController: ModalController) { + + } async presentModal() { const modal = await this.modalController.create({ - component: ModalPage, - componentProps: { value: 123 } + component: ModalPage }); return await modal.present(); } @@ -27,18 +29,77 @@ import { NavParams } from '@ionic/angular'; @Component({ selector: 'modal-page', }) -export class ModalExample { +export class ModalPage { - // "value" passed in componentProps - @Input() value: number; + constructor() { - constructor(navParams: NavParams) { - // componentProps can also be accessed at construction time using NavParams } } ``` +### Passing Data + +During creation of a modal, data can be passed in through the `componentProps`. The previous example can be written to include data: + +```typescript +async presentModal() { + const modal = await this.modalController.create({ + component: ModalPage, + componentProps: { + 'firstName': 'Douglas', + 'lastName': 'Adams', + 'middleInitial': 'N' + } + }); + return await modal.present(); +} +``` + +To get the data passed into the `componentProps`, either set it as an `@Input` or access it via `NavParams` on the `ModalPage`: + +```typescript +export class ModalPage { + + // Data passed in by componentProps + @Input() firstName: string; + @Input() lastName: string; + @Input() middleInitial: string; + + constructor(navParams: NavParams) { + // componentProps can also be accessed at construction time using NavParams + console.log(navParams.get('firstName'); + } + +} +``` + +### Dismissing a Modal + +A modal can be dismissed by calling the dismiss method on the modal controller and optionally passing any data from the modal. + +```javascript +export class ModalPage { + ... + + dismiss() { + // using the injected ModalController this page + // can "dismiss" itself and optionally pass back data + this.modalCtrl.dismiss({ + 'dismissed': true + }); + } +} +``` + +After being dismissed, the data can be read in through the `onWillDismiss` or `onDidDismiss` attached to the modal after creation: + +```javascript +const { data } = await modal.onWillDismiss(); +console.log(data); +``` + + #### Lazy Loading When lazy loading a modal, it's important to note that the modal will not be loaded when it is opened, but rather when the module that imports the modal's module is loaded. @@ -54,17 +115,17 @@ import { CalendarComponent } from './calendar.component'; import { EventModalModule } from '../modals/event/event.module'; @NgModule({ - declarations: [ - CalendarComponent - ], - imports: [ - IonicModule, - CommonModule, - EventModalModule - ], - exports: [ - CalendarComponent - ] + declarations: [ + CalendarComponent + ], + imports: [ + IonicModule, + CommonModule, + EventModalModule + ], + exports: [ + CalendarComponent + ] }) export class CalendarComponentModule {} diff --git a/core/src/components/modal/usage/javascript.md b/core/src/components/modal/usage/javascript.md index 01cbd160b0..6aef7890fd 100644 --- a/core/src/components/modal/usage/javascript.md +++ b/core/src/components/modal/usage/javascript.md @@ -10,11 +10,16 @@ customElements.define('modal-page', class extends HTMLElement { this.innerHTML = ` - Super Modal + Modal Header + + + + + - - Content + + Modal Content `; } }); @@ -24,10 +29,60 @@ async function presentModal() { const modalController = document.querySelector('ion-modal-controller'); await modalController.componentOnReady(); - // present the modal + // create the modal with the `modal-page` component const modalElement = await modalController.create({ component: 'modal-page' }); + + // present the modal await modalElement.present(); } ``` + +### Passing Data + +During creation of a modal, data can be passed in through the `componentProps`. The previous example can be written to include data: + +```javascript +const modalElement = await modalController.create({ + component: 'modal-page', + componentProps: { + 'firstName': 'Douglas', + 'lastName': 'Adams', + 'middleInitial': 'N' + } +}); +``` + +To get the data passed into the `componentProps`, query for the modal in the `modal-page`: + +```js +customElements.define('modal-page', class extends HTMLElement { + connectedCallback() { + const modalElement = document.querySelector('ion-modal'); + console.log(modalElement.componentProps.firstName); + + ... + } +} +``` + + +### Dismissing a Modal + +A modal can be dismissed by calling the dismiss method on the modal controller and optionally passing any data from the modal. + +```javascript +async function dismissModal() { + await modalController.dismiss({ + 'dismissed': true + }); +} +``` + +After being dismissed, the data can be read in through the `onWillDismiss` or `onDidDismiss` attached to the modal after creation: + +```javascript +const { data } = await modalElement.onWillDismiss(); +console.log(data); +``` \ No newline at end of file diff --git a/core/src/components/route-redirect/readme.md b/core/src/components/route-redirect/readme.md index f915c7481c..fffea562a1 100644 --- a/core/src/components/route-redirect/readme.md +++ b/core/src/components/route-redirect/readme.md @@ -1,74 +1,85 @@ # ion-route-redirect -A redirect router can only be used in the scope of `ion-router` as a direct children of it. +A route redirect can only be used with an `ion-router` as a direct child of it. -> Note: this is only meant for vanilla JavaScript project. For Angular projects, use `ion-router-outlet` and the Angular router. +> Note: this element should only be used with a vanilla JavaScript project. For Angular projects, use `ion-router-outlet` and the Angular router. -This route has only two configurable values: +The route redirect has two configurable properties: - `from` - `to` -Their meaning is obvious under the context of a redirection, that occurs `from` a given URL `to` another given URL. +It redirects "from" a URL "to" another URL. When the defined `ion-route-redirect` rule matches, the router will redirect from the path specified in the `from` property to the path in the `to` property. In order for a redirect to occur the `from` path needs to be an exact match to the navigated URL. -In other for a redirection to occurs the `from` path needs to be an exact match of the navigated URL. -## Redirection evaluation +## Multiple Route Redirects An arbitrary number of redirect routes can be defined inside an `ion-router`, but only one can match. -Also, a redirection route WILL never redirect to another redirection router, since this could lead to infinity loops. +A route redirect will never call another redirect after its own redirect, since this could lead to infinite loops. -Let's say we have this two redirection rules: +Take the following two redirects: ```html - - + + ``` -And the user navigates to `/admin`. The router will then redirect to `/login` and stop there. +If the user navigates to `/admin` the router will redirect to `/login` and stop there. It will never evaluate more than one redirect. -It WILL NOT never evaluate more than one redirection rule in a roll. - - -## Examples - -### Simple path - -```html - -``` - -This route will apply (redirect) when the user navigates to: `/admin` but it will NOT apply if the user navigates to `/admin/posts`. - -In order to match any subpath of admin, the wildcard character (`*`) needs to be used. - -```html - -``` - -### Redirect all routes to login - -Redirection routes can work as guards, since that can prevent user to navigate to areas to your application based in a given condition, for example, if the user is authenticated or not. - - -```tsx -{!this.isLoggedIn && - } -``` - -A router can be added and removed dynamically to redirect (or guard) some routes from being accessed. - -Another approach is to modify the value of `to`, since given `to` the value of `null` or `undefined` makes disables the redirection. - -```tsx - -``` +## Usage + +### Javascript + +```html + + + + + +``` + +### Route Redirects as Guards + +Redirection routes can work as guards to prevent users from navigating to certain areas of an application based on a given condition, such as if the user is authenticated or not. + +A route redirect can be added and removed dynamically to redirect (or guard) some routes from being accessed. In the following example, all urls `*` will be redirected to the `/login` url if `isLoggedIn` is `false`. + +```tsx +const isLoggedIn = false; + +const router = document.querySelector('ion-router'); +const routeRedirect = document.createElement('ion-route-redirect'); +routeRedirect.setAttribute('from', '*'); +routeRedirect.setAttribute('to', '/login'); + +if (!isLoggedIn) { + router.appendChild(routeRedirect); +} +``` + +Alternatively, the value of `to` can be modified based on a condition. In the following example, the route redirect will check if the user is logged in and redirect to the `/login` url if not. + +```html + +``` + +```javascript +const isLoggedIn = false; +const routeRedirect = document.querySelector('#tutorialRedirect'); + +routeRedirect.setAttribute('to', isLoggedIn ? undefined : '/login'); +``` + + + ## Properties | Property | Attribute | Description | Type | Default | diff --git a/core/src/components/route-redirect/usage/javascript.md b/core/src/components/route-redirect/usage/javascript.md new file mode 100644 index 0000000000..ed82e5a385 --- /dev/null +++ b/core/src/components/route-redirect/usage/javascript.md @@ -0,0 +1,41 @@ +```html + + + + + +``` + +### Route Redirects as Guards + +Redirection routes can work as guards to prevent users from navigating to certain areas of an application based on a given condition, such as if the user is authenticated or not. + +A route redirect can be added and removed dynamically to redirect (or guard) some routes from being accessed. In the following example, all urls `*` will be redirected to the `/login` url if `isLoggedIn` is `false`. + +```tsx +const isLoggedIn = false; + +const router = document.querySelector('ion-router'); +const routeRedirect = document.createElement('ion-route-redirect'); +routeRedirect.setAttribute('from', '*'); +routeRedirect.setAttribute('to', '/login'); + +if (!isLoggedIn) { + router.appendChild(routeRedirect); +} +``` + +Alternatively, the value of `to` can be modified based on a condition. In the following example, the route redirect will check if the user is logged in and redirect to the `/login` url if not. + +```html + +``` + +```javascript +const isLoggedIn = false; +const routeRedirect = document.querySelector('#tutorialRedirect'); + +routeRedirect.setAttribute('to', isLoggedIn ? undefined : '/login'); +``` \ No newline at end of file diff --git a/core/src/components/split-pane/readme.md b/core/src/components/split-pane/readme.md index ac9f1fb25b..d611687058 100644 --- a/core/src/components/split-pane/readme.md +++ b/core/src/components/split-pane/readme.md @@ -1,27 +1,22 @@ # ion-split-pane -SplitPane is a component that makes it possible to create multi-view layout. -Similar to iPad apps, SplitPane allows UI elements, like Menus, to be -displayed as the viewport increases. +A split pane is useful when creating multi-view layouts. It allows UI elements, like menus, to be +displayed as the viewport width increases. -If the devices screen size is below a certain size, the SplitPane will -collapse and the menu will become hidden again. This is especially useful when -creating an app that will be served over a browser or deployed through the app -store to phones and tablets. +If the device's screen width is below a certain size, the split pane will collapse and the menu will be hidden. This is ideal for creating an app that will be served in a browser and deployed through the app store to phones and tablets. -### Setting breakpoints +### Setting Breakpoints -By default, SplitPane will expand when the screen is larger than 992px. -If you want to customize this, use the `when` input. The `when` input can -accept any valid media query, as it uses `matchMedia()` underneath. +By default, the split pane will expand when the screen is larger than 992px. To customize this, pass a breakpoint in the `when` property. The `when` property can accept a boolean value, any valid media query, or one of Ionic's predefined sizes. -SplitPane also provides some predefined media queries that can be used. - ```html - + + + + ``` @@ -33,9 +28,6 @@ SplitPane also provides some predefined media queries that can be used. | `lg` | `(min-width: 992px)` | Show the split-pane when the min-width is 992px (default break point) | | `xl` | `(min-width: 1200px)` | Show the split-pane when the min-width is 1200px | - You can also pass in boolean values that will trigger SplitPane when the value - or expression evaluates to true. - diff --git a/core/src/components/tabs/readme.md b/core/src/components/tabs/readme.md index 017f2d6cf8..ede08f81f2 100644 --- a/core/src/components/tabs/readme.md +++ b/core/src/components/tabs/readme.md @@ -3,82 +3,12 @@ Tabs are a top level navigation component to implement a tab-based navigation. The component is a container of individual [Tab](../tab/) components. -`ion-tabs` is a styleless component that works as a router outlet in order to handle navigation. -This component does not provide any UI feedback or mechanism to switch between tabs. -In order to do so, an `ion-tab-bar` should be provided as a direct child of `ion-tabs`: +The `ion-tabs` component does not have any styling and works as a router outlet in order to handle navigation. It does not provide any UI feedback or mechanism to switch between tabs. In order to do so, an `ion-tab-bar` should be provided as a direct child of `ion-tabs`. -```html - - Home Content - Settings Content +Both `ion-tabs` and `ion-tab-bar` can be used as standalone elements. They don’t depend on each other to work, but they are usually used together in order to implement a tab-based navigation that behaves like a native app. - +The `ion-tab-bar` needs a slot defined in order to be projected to the right place in an `ion-tabs` component. - - Home - - 6 - - - - Settings - - - - - -``` - -Note that both `ion-tabs` and `ion-tab-bar` can be used as standalone elements. They don’t depend on each other to work, but they are usually used together in order to implement a tab-based navigation that feels like a native app. - -`ion-tab-bar` always needs `slot="bottom"` in order to be projected into `ion-tabs` at the right place. - -## The "tab" property - -Each `ion-tab-button` will activate one of the tabs when tapped. -In order to link the button to the `ion-tab` container, a matching `tab` property must be used. - -```html - -[...] - -``` - -This `ion-tab-button` and `ion-tab` are now linked by the common `tab` property. - -The `tab` property identifies each tab, and it has to be unique within the scope of the same `ion-tabs`. It's important to set the same property to `ion-tab` and `ion-tab-button`, even if you are only using one. e.g. You could use the `ion-tab-bar` without using `ion-tabs`. In this case you should still give each `ion-tab` the property of `tab="something"`. - -### Router integration - -When the ionic's router (`ion-router`) is used, the `tab` property matches the "component" of `ion-route`: - -The following route within the scope of a `ion-tabs` outlet: - -```html - -``` - -Would match the following tab: - -```html - -``` - -### Angular Router integration - -Using tabs with Angular's router is fairly straight forward. Here you only need to define tab which is the reference to the route. - -```html - - - - - - Schedule - - - -``` @@ -115,6 +45,50 @@ Using tabs with Angular's router is fairly straight forward. Here you only need ``` +### Router integration + +When used with Angular's router the `tab` property of the `ion-tab-button` should be a reference to the route path. + +```html + + + + + Schedule + + + +``` + +```typescript +import { Routes } from '@angular/router'; +import { TabsPage } from './tabs-page'; + +const routes: Routes = [ + { + path: 'tabs', + component: TabsPage, + children: [ + { + path: 'schedule', + children: [ + { + path: '', + loadChildren: '../schedule/schedule.module#ScheduleModule' + } + ] + }, + { + path: '', + redirectTo: '/app/tabs/schedule', + pathMatch: 'full' + } + ] + } +]; +``` + + ### Javascript ```html @@ -163,6 +137,42 @@ Using tabs with Angular's router is fairly straight forward. Here you only need ``` +## Activating Tabs + +Each `ion-tab-button` will activate one of the tabs when pressed. In order to link the `ion-tab-button` to the `ion-tab` container, a matching `tab` property should be set on each component. + +```html + + ... + + + + ... + +``` + +The `ion-tab-button` and `ion-tab` above are linked by the common `tab` property. + +The `tab` property identifies each tab, and it has to be unique within the `ion-tabs`. It's important to always set the `tab` property on the `ion-tab` and `ion-tab-button`, even if one component is not used. + + +### Router integration + +When used with Ionic's router (`ion-router`) the `tab` property of the `ion-tab` matches the `component` property of an `ion-route`. + +The following route within the scope of an `ion-tabs` outlet: + +```html + +``` + +will match the following tab: + +```html + +``` + + ### React ```tsx diff --git a/core/src/components/tabs/usage/angular.md b/core/src/components/tabs/usage/angular.md index 452d52aa8e..fff379b30c 100644 --- a/core/src/components/tabs/usage/angular.md +++ b/core/src/components/tabs/usage/angular.md @@ -24,3 +24,47 @@ ``` + + +### Router integration + +When used with Angular's router the `tab` property of the `ion-tab-button` should be a reference to the route path. + +```html + + + + + Schedule + + + +``` + +```typescript +import { Routes } from '@angular/router'; +import { TabsPage } from './tabs-page'; + +const routes: Routes = [ + { + path: 'tabs', + component: TabsPage, + children: [ + { + path: 'schedule', + children: [ + { + path: '', + loadChildren: '../schedule/schedule.module#ScheduleModule' + } + ] + }, + { + path: '', + redirectTo: '/app/tabs/schedule', + pathMatch: 'full' + } + ] + } +]; +``` diff --git a/core/src/components/tabs/usage/javascript.md b/core/src/components/tabs/usage/javascript.md index d873220446..b48482d43c 100644 --- a/core/src/components/tabs/usage/javascript.md +++ b/core/src/components/tabs/usage/javascript.md @@ -42,3 +42,39 @@ ``` + + +## Activating Tabs + +Each `ion-tab-button` will activate one of the tabs when pressed. In order to link the `ion-tab-button` to the `ion-tab` container, a matching `tab` property should be set on each component. + +```html + + ... + + + + ... + +``` + +The `ion-tab-button` and `ion-tab` above are linked by the common `tab` property. + +The `tab` property identifies each tab, and it has to be unique within the `ion-tabs`. It's important to always set the `tab` property on the `ion-tab` and `ion-tab-button`, even if one component is not used. + + +### Router integration + +When used with Ionic's router (`ion-router`) the `tab` property of the `ion-tab` matches the `component` property of an `ion-route`. + +The following route within the scope of an `ion-tabs` outlet: + +```html + +``` + +will match the following tab: + +```html + +``` \ No newline at end of file diff --git a/core/src/components/virtual-scroll/readme.md b/core/src/components/virtual-scroll/readme.md index 4250d0ae9b..9cd5290ce4 100644 --- a/core/src/components/virtual-scroll/readme.md +++ b/core/src/components/virtual-scroll/readme.md @@ -3,68 +3,16 @@ Virtual Scroll displays a virtual, "infinite" list. An array of records is passed to the virtual scroll containing the data to create templates for. The template created for each record, referred to as a cell, can -consist of items, headers, and footers. -For performance reasons, not every record in the list is rendered at once; -instead a small subset of records (enough to fill the viewport) are rendered -and reused as the user scrolls. +consist of items, headers, and footers. For performance reasons, not every record +in the list is rendered at once; instead a small subset of records (enough to fill the viewport) +are rendered and reused as the user scrolls. -### The Basics -The array of records should be passed to the `items` property on the `ion-virtual-scroll` element. -The data given to the `items` property must be an array. An item -template with the `*virtualItem` property is required in the `ion-virtual-scroll`. -The `*virtualItem` property can be added to any element. - -```html - - - {{ item }} - - -``` - -### Section Headers and Footers - -Section headers and footers are optional. They can be dynamically created -from developer-defined functions. For example, a large list of contacts -usually has a divider for each letter in the alphabet. Developers provide -their own custom function to be called on each record. The logic in the -custom function should determine whether to create the section template -and what data to provide to the template. The custom function should -return `null` if a template shouldn't be created. - -```html - - - {{ header }} - - - Item: {{ item }} - - -``` - -Below is an example of a custom function called on every record. It -gets passed the individual record, the record's index number, -and the entire array of records. In this example, after every 20 -records a header will be inserted. So between the 19th and 20th records, -between the 39th and 40th, and so on, a `` will -be created and the template's data will come from the function's -returned data. - -```ts -myHeaderFn(record, recordIndex, records) { - if (recordIndex % 20 === 0) { - return 'Header ' + recordIndex; - } - return null; -} -``` ### Approximate Widths and Heights If the height of items in the virtual scroll are not close to the -default size of 40px, it is extremely important to provide a value for -approxItemHeight height. An exact pixel-perfect size is not necessary, +default size of `40px`, it is extremely important to provide a value for +the `approxItemHeight` property. An exact pixel-perfect size is not necessary, but without an estimate the virtual scroll will not render correctly. The approximate width and height of each template is used to help @@ -98,34 +46,6 @@ renders whenever it wants which could be while the user is scrolling. However, `` is governed by the containing `ion-content` and does not render images while scrolling quickly. -```html - - - - - - {{ item.firstName }} {{ item.lastName }} - - -``` - -### Custom Components - -If a custom component is going to be used within Virtual Scroll, it's best -to wrap it with a good old `
` to ensure the component is rendered -correctly. Since each custom component's implementation and internals can be -quite different, wrapping within a `
` is a safe way to make sure -dimensions are measured correctly. - -```html - -
- - {{ item }} - -
-
-``` ## Virtual Scroll Performance Tips @@ -190,7 +110,7 @@ dataset, so please make sure they're performant.
- +
{{ item.name }} @@ -250,6 +170,75 @@ function getImgSrc() { let rotateImg = 0; ``` +### Basic + +The array of records should be passed to the `items` property on the `ion-virtual-scroll` element. +The data given to the `items` property must be an array. An item template with the `*virtualItem` property is required in the `ion-virtual-scroll`. The `*virtualItem` property can be added to any element. + +```html + + + {{ item }} + + +``` + +### Section Headers and Footers + +Section headers and footers are optional. They can be dynamically created +from developer-defined functions. For example, a large list of contacts +usually has a divider for each letter in the alphabet. Developers provide +their own custom function to be called on each record. The logic in the +custom function should determine whether to create the section template +and what data to provide to the template. The custom function should +return `null` if a template shouldn't be created. + +```html + + + {{ header }} + + + Item: {{ item }} + + +``` + +Below is an example of a custom function called on every record. It +gets passed the individual record, the record's index number, +and the entire array of records. In this example, after every 20 +records a header will be inserted. So between the 19th and 20th records, +between the 39th and 40th, and so on, a `` will +be created and the template's data will come from the function's +returned data. + +```ts +myHeaderFn(record, recordIndex, records) { + if (recordIndex % 20 === 0) { + return 'Header ' + recordIndex; + } + return null; +} +``` + + +### Custom Components + +If a custom component is going to be used within Virtual Scroll, it's best +to wrap it with a `
` to ensure the component is rendered correctly. Since +each custom component's implementation and internals can be quite different, wrapping +within a `
` is a safe way to make sure dimensions are measured correctly. + +```html + +
+ + {{ item }} + +
+
+``` + ### React diff --git a/core/src/components/virtual-scroll/usage/angular.md b/core/src/components/virtual-scroll/usage/angular.md index 2897a8e6ba..b2c18b5d42 100644 --- a/core/src/components/virtual-scroll/usage/angular.md +++ b/core/src/components/virtual-scroll/usage/angular.md @@ -3,7 +3,7 @@
- +
{{ item.name }} @@ -62,3 +62,72 @@ function getImgSrc() { let rotateImg = 0; ``` + +### Basic + +The array of records should be passed to the `items` property on the `ion-virtual-scroll` element. +The data given to the `items` property must be an array. An item template with the `*virtualItem` property is required in the `ion-virtual-scroll`. The `*virtualItem` property can be added to any element. + +```html + + + {{ item }} + + +``` + +### Section Headers and Footers + +Section headers and footers are optional. They can be dynamically created +from developer-defined functions. For example, a large list of contacts +usually has a divider for each letter in the alphabet. Developers provide +their own custom function to be called on each record. The logic in the +custom function should determine whether to create the section template +and what data to provide to the template. The custom function should +return `null` if a template shouldn't be created. + +```html + + + {{ header }} + + + Item: {{ item }} + + +``` + +Below is an example of a custom function called on every record. It +gets passed the individual record, the record's index number, +and the entire array of records. In this example, after every 20 +records a header will be inserted. So between the 19th and 20th records, +between the 39th and 40th, and so on, a `` will +be created and the template's data will come from the function's +returned data. + +```ts +myHeaderFn(record, recordIndex, records) { + if (recordIndex % 20 === 0) { + return 'Header ' + recordIndex; + } + return null; +} +``` + + +### Custom Components + +If a custom component is going to be used within Virtual Scroll, it's best +to wrap it with a `
` to ensure the component is rendered correctly. Since +each custom component's implementation and internals can be quite different, wrapping +within a `
` is a safe way to make sure dimensions are measured correctly. + +```html + +
+ + {{ item }} + +
+
+``` \ No newline at end of file