mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
chore(): sync vue tabs changes with master
This commit is contained in:
@@ -155,6 +155,59 @@ async function presentActionSheet() {
|
||||
### React
|
||||
|
||||
```tsx
|
||||
/* Using with useIonActionSheet Hook */
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
IonButton,
|
||||
IonContent,
|
||||
IonPage,
|
||||
useIonActionSheet,
|
||||
} from '@ionic/react';
|
||||
|
||||
const ActionSheetExample: React.FC = () => {
|
||||
const [present, dismiss] = useIonActionSheet();
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
buttons: [{ text: 'Ok' }, { text: 'Cancel' }],
|
||||
header: 'Action Sheet'
|
||||
})
|
||||
}
|
||||
>
|
||||
Show ActionSheet
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet')
|
||||
}
|
||||
>
|
||||
Show ActionSheet using params
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => {
|
||||
present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet');
|
||||
setTimeout(dismiss, 3000);
|
||||
}}
|
||||
>
|
||||
Show ActionSheet, hide after 3 seconds
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonActionSheet Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
|
||||
import { trash, share, caretForwardCircle, heart, close } from 'ionicons/icons';
|
||||
|
||||
@@ -1,4 +1,57 @@
|
||||
```tsx
|
||||
/* Using with useIonActionSheet Hook */
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
IonButton,
|
||||
IonContent,
|
||||
IonPage,
|
||||
useIonActionSheet,
|
||||
} from '@ionic/react';
|
||||
|
||||
const ActionSheetExample: React.FC = () => {
|
||||
const [present, dismiss] = useIonActionSheet();
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
buttons: [{ text: 'Ok' }, { text: 'Cancel' }],
|
||||
header: 'Action Sheet'
|
||||
})
|
||||
}
|
||||
>
|
||||
Show ActionSheet
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet')
|
||||
}
|
||||
>
|
||||
Show ActionSheet using params
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => {
|
||||
present([{ text: 'Ok' }, { text: 'Cancel' }], 'Action Sheet');
|
||||
setTimeout(dismiss, 3000);
|
||||
}}
|
||||
>
|
||||
Show ActionSheet, hide after 3 seconds
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonActionSheet Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
|
||||
import { trash, share, caretForwardCircle, heart, close } from 'ionicons/icons';
|
||||
|
||||
@@ -588,6 +588,48 @@ function presentAlertCheckbox() {
|
||||
### React
|
||||
|
||||
```tsx
|
||||
/* Using with useIonAlert Hook */
|
||||
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonAlert } from '@ionic/react';
|
||||
|
||||
const AlertExample: React.FC = () => {
|
||||
const [present] = useIonAlert();
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent fullscreen>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
cssClass: 'my-css',
|
||||
header: 'Alert',
|
||||
message: 'alert from hook',
|
||||
buttons: [
|
||||
'Cancel',
|
||||
{ text: 'Ok', handler: (d) => console.log('ok pressed') },
|
||||
],
|
||||
onDidDismiss: (e) => console.log('did dismiss'),
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Alert
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => present('hello with params', [{ text: 'Ok' }])}
|
||||
>
|
||||
Show Alert using params
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonAlert Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonAlert, IonButton, IonContent } from '@ionic/react';
|
||||
|
||||
|
||||
@@ -1,4 +1,46 @@
|
||||
```tsx
|
||||
/* Using with useIonAlert Hook */
|
||||
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonAlert } from '@ionic/react';
|
||||
|
||||
const AlertExample: React.FC = () => {
|
||||
const [present] = useIonAlert();
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent fullscreen>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
cssClass: 'my-css',
|
||||
header: 'Alert',
|
||||
message: 'alert from hook',
|
||||
buttons: [
|
||||
'Cancel',
|
||||
{ text: 'Ok', handler: (d) => console.log('ok pressed') },
|
||||
],
|
||||
onDidDismiss: (e) => console.log('did dismiss'),
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Alert
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => present('hello with params', [{ text: 'Ok' }])}
|
||||
>
|
||||
Show Alert using params
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonAlert Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonAlert, IonButton, IonContent } from '@ionic/react';
|
||||
|
||||
|
||||
@@ -169,3 +169,18 @@
|
||||
:host(.has-focus) button {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
|
||||
// Item Floating: Placeholder
|
||||
// ----------------------------------------------------------------
|
||||
// When used with a floating item the placeholder should hide
|
||||
|
||||
:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value)) {
|
||||
transition: opacity 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value).item-has-focus) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -190,15 +190,6 @@ export class Input implements ComponentInterface {
|
||||
*/
|
||||
@Prop({ mutable: true }) value?: string | number | null = '';
|
||||
|
||||
/**
|
||||
* Update the native input element when the value changes
|
||||
*/
|
||||
@Watch('value')
|
||||
protected valueChanged() {
|
||||
this.emitStyle();
|
||||
this.ionChange.emit({ value: this.value == null ? this.value : this.value.toString() });
|
||||
}
|
||||
|
||||
/**
|
||||
* Emitted when a keyboard input occurred.
|
||||
*/
|
||||
@@ -225,6 +216,23 @@ export class Input implements ComponentInterface {
|
||||
*/
|
||||
@Event() ionStyle!: EventEmitter<StyleEventDetail>;
|
||||
|
||||
/**
|
||||
* Update the item classes when the placeholder changes
|
||||
*/
|
||||
@Watch('placeholder')
|
||||
protected placeholderChanged() {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the native input element when the value changes
|
||||
*/
|
||||
@Watch('value')
|
||||
protected valueChanged() {
|
||||
this.emitStyle();
|
||||
this.ionChange.emit({ value: this.value == null ? this.value : this.value.toString() });
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = inheritAttributes(this.el, ['tabindex', 'title']);
|
||||
}
|
||||
|
||||
@@ -132,11 +132,11 @@
|
||||
<ion-label>Right</ion-label>
|
||||
<ion-input class="ion-text-right" value="Narrow input"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
</ion-content>
|
||||
|
||||
<script>
|
||||
document.querySelector('ion-input').addEventListener('ionBlur', (ev) => { console.log(ev)})
|
||||
document.querySelector('ion-input').addEventListener('ionBlur', (ev) => { console.log(ev)});
|
||||
|
||||
function toggleBoolean(id, prop) {
|
||||
var el = document.getElementById(id);
|
||||
|
||||
|
||||
@@ -13,27 +13,130 @@
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Input - Spec</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<h1>Floating Inputs</h1>
|
||||
|
||||
<div class="grid">
|
||||
<div class="column">
|
||||
<h2>Inactive</h2>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Label</ion-label>
|
||||
<ion-input placeholder="Placeholder Text"></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Focused</h2>
|
||||
<ion-item class="item-has-focus">
|
||||
<ion-label position="floating">Label</ion-label>
|
||||
<ion-input placeholder="Placeholder Text"></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Activated</h2>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Label</ion-label>
|
||||
<ion-input placeholder="Placeholder Text" value="Input Text"></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Hover</h2>
|
||||
<ion-item class="item-hovered">
|
||||
<ion-label position="floating">Label</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Disabled</h2>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Label</ion-label>
|
||||
<ion-input disabled></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Toggle Placeholder</h2>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Label</ion-label>
|
||||
<ion-input id="floatingToggle" type="password"></ion-input>
|
||||
<ion-button fill="clear" slot="end" onClick="togglePlaceholder('#floatingToggle')" class="ion-align-self-center">
|
||||
Toggle
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Stacked Inputs</h1>
|
||||
|
||||
<div class="grid">
|
||||
<div class="column">
|
||||
<h2>Inactive</h2>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Label</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Focused</h2>
|
||||
<ion-item class="item-has-focus">
|
||||
<ion-label position="stacked">Label</ion-label>
|
||||
<ion-input placeholder="Placeholder Text"></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Activated</h2>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Label</ion-label>
|
||||
<ion-input placeholder="Placeholder Text" value="Input Text"></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Hover</h2>
|
||||
<ion-item class="item-hovered">
|
||||
<ion-label position="stacked">Label</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Disabled</h2>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Label</ion-label>
|
||||
<ion-input disabled></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>Toggle Placeholder</h2>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Label</ion-label>
|
||||
<ion-input id="stackedToggle" type="password"></ion-input>
|
||||
<ion-button fill="clear" slot="end" onClick="togglePlaceholder('#stackedToggle')" class="ion-align-self-center">
|
||||
Toggle
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Stacked Div</h2>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Floating: input</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item class="item-has-focus">
|
||||
<ion-label position="floating">Floating: input focused value</ion-label>
|
||||
<ion-input value="value"></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked: input</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked: input value</ion-label>
|
||||
<ion-input value="value"></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked: div</ion-label>
|
||||
<ion-label position="stacked">Label</ion-label>
|
||||
<div>A div</div>
|
||||
</ion-item>
|
||||
|
||||
<ion-item class="ion-align-items-center">
|
||||
<ion-icon slot="start" name="planet"></ion-icon>
|
||||
<ion-label position="stacked">Align items: center</ion-label>
|
||||
@@ -68,8 +171,45 @@
|
||||
</ion-content>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 14px;
|
||||
color: #54575e;
|
||||
|
||||
margin: 25px 0 5px 25px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
|
||||
color: #a1a7b0;
|
||||
|
||||
margin-top: 10px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
hr {
|
||||
background: #eff1f3;
|
||||
|
||||
margin-top: 18px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
row-gap: 20px;
|
||||
column-gap: 20px;
|
||||
padding: 0 20px 20px;
|
||||
}
|
||||
|
||||
ion-item {
|
||||
--background: #f5f5f5;
|
||||
--background: #e0e0e0;
|
||||
--background-hover: #d3d3d3;
|
||||
}
|
||||
|
||||
.custom {
|
||||
@@ -84,6 +224,13 @@
|
||||
color: purple !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function togglePlaceholder(id) {
|
||||
const input = document.querySelector(id);
|
||||
input.placeholder = input.placeholder ? undefined : 'Placeholder Text';
|
||||
}
|
||||
</script>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -35,12 +35,10 @@
|
||||
}
|
||||
|
||||
:host-context(.item-has-focus).label-floating,
|
||||
:host-context(.item-has-placeholder).label-floating,
|
||||
:host-context(.item-has-value).label-floating {
|
||||
@include transform(translate3d(0, 0, 0), scale(.82));
|
||||
}
|
||||
|
||||
|
||||
// iOS Typography
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
}
|
||||
|
||||
:host-context(.item-has-focus).label-floating,
|
||||
:host-context(.item-has-placeholder).label-floating,
|
||||
:host-context(.item-has-value).label-floating {
|
||||
@include transform(translateY(50%), scale(.75));
|
||||
}
|
||||
|
||||
@@ -131,6 +131,43 @@ async function presentLoadingWithOptions() {
|
||||
### React
|
||||
|
||||
```tsx
|
||||
/* Using with useIonLoading Hook */
|
||||
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonLoading } from '@ionic/react';
|
||||
|
||||
interface LoadingProps {}
|
||||
|
||||
const LoadingExample: React.FC<LoadingProps> = () => {
|
||||
const [present] = useIonLoading();
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
duration: 3000,
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Loading
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => present('Loading', 2000, 'dots')}
|
||||
>
|
||||
Show Loading using params
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonLoading Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonLoading, IonButton, IonContent } from '@ionic/react';
|
||||
|
||||
|
||||
@@ -1,4 +1,41 @@
|
||||
```tsx
|
||||
/* Using with useIonLoading Hook */
|
||||
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonLoading } from '@ionic/react';
|
||||
|
||||
interface LoadingProps {}
|
||||
|
||||
const LoadingExample: React.FC<LoadingProps> = () => {
|
||||
const [present] = useIonLoading();
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
duration: 3000,
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Loading
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => present('Loading', 2000, 'dots')}
|
||||
>
|
||||
Show Loading using params
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonLoading Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonLoading, IonButton, IonContent } from '@ionic/react';
|
||||
|
||||
|
||||
@@ -46,7 +46,11 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
@State() isEndSide = false;
|
||||
|
||||
/**
|
||||
* The content's id the menu should use.
|
||||
* The `id` of the main content. When using
|
||||
* a router this is typically `ion-router-outlet`.
|
||||
* When not using a router, this is typically
|
||||
* your main view's `ion-content`. This is not the
|
||||
* id of the `ion-content` inside of your `ion-menu`.
|
||||
*/
|
||||
@Prop({ reflect: true }) contentId?: string;
|
||||
|
||||
|
||||
@@ -477,15 +477,15 @@ export default defineComponent({
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------ | --------------------- | ----------- |
|
||||
| `contentId` | `content-id` | The content's id the menu should use. | `string \| undefined` | `undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the menu is disabled. | `boolean` | `false` |
|
||||
| `maxEdgeStart` | `max-edge-start` | The edge threshold for dragging the menu open. If a drag/swipe happens over this value, the menu is not triggered. | `number` | `50` |
|
||||
| `menuId` | `menu-id` | An id for the menu. | `string \| undefined` | `undefined` |
|
||||
| `side` | `side` | Which side of the view the menu should be placed. | `"end" \| "start"` | `'start'` |
|
||||
| `swipeGesture` | `swipe-gesture` | If `true`, swiping the menu is enabled. | `boolean` | `true` |
|
||||
| `type` | `type` | The display type of the menu. Available options: `"overlay"`, `"reveal"`, `"push"`. | `string \| undefined` | `undefined` |
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ----------- |
|
||||
| `contentId` | `content-id` | The `id` of the main content. When using a router this is typically `ion-router-outlet`. When not using a router, this is typically your main view's `ion-content`. This is not the id of the `ion-content` inside of your `ion-menu`. | `string \| undefined` | `undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the menu is disabled. | `boolean` | `false` |
|
||||
| `maxEdgeStart` | `max-edge-start` | The edge threshold for dragging the menu open. If a drag/swipe happens over this value, the menu is not triggered. | `number` | `50` |
|
||||
| `menuId` | `menu-id` | An id for the menu. | `string \| undefined` | `undefined` |
|
||||
| `side` | `side` | Which side of the view the menu should be placed. | `"end" \| "start"` | `'start'` |
|
||||
| `swipeGesture` | `swipe-gesture` | If `true`, swiping the menu is enabled. | `boolean` | `true` |
|
||||
| `type` | `type` | The display type of the menu. Available options: `"overlay"`, `"reveal"`, `"push"`. | `string \| undefined` | `undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -332,6 +332,70 @@ modalElement.presentingElement = await modalController.getTop(); // Get the top-
|
||||
### React
|
||||
|
||||
```tsx
|
||||
/* Using with useIonModal Hook */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonModal } from '@ionic/react';
|
||||
|
||||
const Body: React.FC<{
|
||||
count: number;
|
||||
onDismiss: () => void;
|
||||
onIncrement: () => void;
|
||||
}> = ({ count, onDismiss, onIncrement }) => (
|
||||
<div>
|
||||
count: {count}
|
||||
<IonButton expand="block" onClick={() => onIncrement()}>
|
||||
Increment Count
|
||||
</IonButton>
|
||||
<IonButton expand="block" onClick={() => onDismiss()}>
|
||||
Close
|
||||
</IonButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ModalExample: React.FC = () => {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
const handleIncrement = () => {
|
||||
setCount(count + 1);
|
||||
};
|
||||
|
||||
const handleDismiss = () => {
|
||||
dismiss();
|
||||
};
|
||||
|
||||
/**
|
||||
* First parameter is the component to show, second is the props to pass
|
||||
*/
|
||||
const [present, dismiss] = useIonModal(Body, {
|
||||
count,
|
||||
onDismiss: handleDismiss,
|
||||
onIncrement: handleIncrement,
|
||||
});
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent fullscreen>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => {
|
||||
present({
|
||||
cssClass: 'my-class',
|
||||
});
|
||||
}}
|
||||
>
|
||||
Show Modal
|
||||
</IonButton>
|
||||
<div>Count: {count}</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonModal Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonModal, IonButton, IonContent } from '@ionic/react';
|
||||
|
||||
@@ -350,8 +414,6 @@ export const ModalExample: React.FC = () => {
|
||||
};
|
||||
```
|
||||
|
||||
> If you need a wrapper element inside of your modal component, we recommend using an `<IonPage>` so that the component dimensions are still computed properly.
|
||||
|
||||
### Swipeable Modals
|
||||
|
||||
Modals in iOS mode have the ability to be presented in a card-style and swiped to close. The card-style presentation and swipe to close gesture are not mutually exclusive, meaning you can pick and choose which features you want to use. For example, you can have a card-style modal that cannot be swiped or a full sized modal that can be swiped.
|
||||
|
||||
@@ -1,4 +1,68 @@
|
||||
```tsx
|
||||
/* Using with useIonModal Hook */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonModal } from '@ionic/react';
|
||||
|
||||
const Body: React.FC<{
|
||||
count: number;
|
||||
onDismiss: () => void;
|
||||
onIncrement: () => void;
|
||||
}> = ({ count, onDismiss, onIncrement }) => (
|
||||
<div>
|
||||
count: {count}
|
||||
<IonButton expand="block" onClick={() => onIncrement()}>
|
||||
Increment Count
|
||||
</IonButton>
|
||||
<IonButton expand="block" onClick={() => onDismiss()}>
|
||||
Close
|
||||
</IonButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ModalExample: React.FC = () => {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
const handleIncrement = () => {
|
||||
setCount(count + 1);
|
||||
};
|
||||
|
||||
const handleDismiss = () => {
|
||||
dismiss();
|
||||
};
|
||||
|
||||
/**
|
||||
* First parameter is the component to show, second is the props to pass
|
||||
*/
|
||||
const [present, dismiss] = useIonModal(Body, {
|
||||
count,
|
||||
onDismiss: handleDismiss,
|
||||
onIncrement: handleIncrement,
|
||||
});
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent fullscreen>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => {
|
||||
present({
|
||||
cssClass: 'my-class',
|
||||
});
|
||||
}}
|
||||
>
|
||||
Show Modal
|
||||
</IonButton>
|
||||
<div>Count: {count}</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonModal Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonModal, IonButton, IonContent } from '@ionic/react';
|
||||
|
||||
@@ -17,8 +81,6 @@ export const ModalExample: React.FC = () => {
|
||||
};
|
||||
```
|
||||
|
||||
> If you need a wrapper element inside of your modal component, we recommend using an `<IonPage>` so that the component dimensions are still computed properly.
|
||||
|
||||
### Swipeable Modals
|
||||
|
||||
Modals in iOS mode have the ability to be presented in a card-style and swiped to close. The card-style presentation and swipe to close gesture are not mutually exclusive, meaning you can pick and choose which features you want to use. For example, you can have a card-style modal that cannot be swiped or a full sized modal that can be swiped.
|
||||
|
||||
@@ -7,6 +7,95 @@ A Picker is a dialog that displays a row of buttons and columns underneath. It a
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
### React
|
||||
|
||||
```tsx
|
||||
/* Using with useIonPicker Hook */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonPicker } from '@ionic/react';
|
||||
|
||||
const PickerExample: React.FC = () => {
|
||||
const [present] = useIonPicker();
|
||||
const [value, setValue] = useState('');
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Confirm',
|
||||
handler: (selected) => {
|
||||
setValue(selected.animal.value)
|
||||
},
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'animal',
|
||||
options: [
|
||||
{ text: 'Dog', value: 'dog' },
|
||||
{ text: 'Cat', value: 'cat' },
|
||||
{ text: 'Bird', value: 'bird' },
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Picker
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present(
|
||||
[
|
||||
{
|
||||
name: 'animal',
|
||||
options: [
|
||||
{ text: 'Dog', value: 'dog' },
|
||||
{ text: 'Cat', value: 'cat' },
|
||||
{ text: 'Bird', value: 'bird' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'vehicle',
|
||||
options: [
|
||||
{ text: 'Car', value: 'car' },
|
||||
{ text: 'Truck', value: 'truck' },
|
||||
{ text: 'Bike', value: 'bike' },
|
||||
],
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
text: 'Confirm',
|
||||
handler: (selected) => {
|
||||
setValue(`${selected.animal.value}, ${selected.vehicle.value}`)
|
||||
},
|
||||
},
|
||||
]
|
||||
)
|
||||
}
|
||||
>
|
||||
Show Picker using params
|
||||
</IonButton>
|
||||
{value && (
|
||||
<div>Selected Value: {value}</div>
|
||||
)}
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
|
||||
82
core/src/components/picker/usage/react.md
Normal file
82
core/src/components/picker/usage/react.md
Normal file
@@ -0,0 +1,82 @@
|
||||
```tsx
|
||||
/* Using with useIonPicker Hook */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonPicker } from '@ionic/react';
|
||||
|
||||
const PickerExample: React.FC = () => {
|
||||
const [present] = useIonPicker();
|
||||
const [value, setValue] = useState('');
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
buttons: [
|
||||
{
|
||||
text: 'Confirm',
|
||||
handler: (selected) => {
|
||||
setValue(selected.animal.value)
|
||||
},
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'animal',
|
||||
options: [
|
||||
{ text: 'Dog', value: 'dog' },
|
||||
{ text: 'Cat', value: 'cat' },
|
||||
{ text: 'Bird', value: 'bird' },
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Picker
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present(
|
||||
[
|
||||
{
|
||||
name: 'animal',
|
||||
options: [
|
||||
{ text: 'Dog', value: 'dog' },
|
||||
{ text: 'Cat', value: 'cat' },
|
||||
{ text: 'Bird', value: 'bird' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'vehicle',
|
||||
options: [
|
||||
{ text: 'Car', value: 'car' },
|
||||
{ text: 'Truck', value: 'truck' },
|
||||
{ text: 'Bike', value: 'bike' },
|
||||
],
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
text: 'Confirm',
|
||||
handler: (selected) => {
|
||||
setValue(`${selected.animal.value}, ${selected.vehicle.value}`)
|
||||
},
|
||||
},
|
||||
]
|
||||
)
|
||||
}
|
||||
>
|
||||
Show Picker using params
|
||||
</IonButton>
|
||||
{value && (
|
||||
<div>Selected Value: {value}</div>
|
||||
)}
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
@@ -114,6 +114,59 @@ function presentPopover(ev) {
|
||||
### React
|
||||
|
||||
```tsx
|
||||
/* Using with useIonPopover Hook */
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
IonButton,
|
||||
IonContent,
|
||||
IonItem,
|
||||
IonList,
|
||||
IonListHeader,
|
||||
IonPage,
|
||||
useIonPopover,
|
||||
} from '@ionic/react';
|
||||
|
||||
const PopoverList: React.FC<{
|
||||
onHide: () => void;
|
||||
}> = ({ onHide }) => (
|
||||
<IonList>
|
||||
<IonListHeader>Ionic</IonListHeader>
|
||||
<IonItem button>Learn Ionic</IonItem>
|
||||
<IonItem button>Documentation</IonItem>
|
||||
<IonItem button>Showcase</IonItem>
|
||||
<IonItem button>GitHub Repo</IonItem>
|
||||
<IonItem lines="none" detail={false} button onClick={onHide}>
|
||||
Close
|
||||
</IonItem>
|
||||
</IonList>
|
||||
);
|
||||
|
||||
const PopoverExample: React.FC = () => {
|
||||
const [present, dismiss] = useIonPopover(PopoverList, { onHide: () => dismiss() });
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={(e) =>
|
||||
present({
|
||||
event: e.nativeEvent,
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Popover
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonPopover Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonPopover, IonButton } from '@ionic/react';
|
||||
|
||||
|
||||
@@ -1,4 +1,57 @@
|
||||
```tsx
|
||||
/* Using with useIonPopover Hook */
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
IonButton,
|
||||
IonContent,
|
||||
IonItem,
|
||||
IonList,
|
||||
IonListHeader,
|
||||
IonPage,
|
||||
useIonPopover,
|
||||
} from '@ionic/react';
|
||||
|
||||
const PopoverList: React.FC<{
|
||||
onHide: () => void;
|
||||
}> = ({ onHide }) => (
|
||||
<IonList>
|
||||
<IonListHeader>Ionic</IonListHeader>
|
||||
<IonItem button>Learn Ionic</IonItem>
|
||||
<IonItem button>Documentation</IonItem>
|
||||
<IonItem button>Showcase</IonItem>
|
||||
<IonItem button>GitHub Repo</IonItem>
|
||||
<IonItem lines="none" detail={false} button onClick={onHide}>
|
||||
Close
|
||||
</IonItem>
|
||||
</IonList>
|
||||
);
|
||||
|
||||
const PopoverExample: React.FC = () => {
|
||||
const [present, dismiss] = useIonPopover(PopoverList, { onHide: () => dismiss() });
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={(e) =>
|
||||
present({
|
||||
event: e.nativeEvent,
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Popover
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using with IonPopover Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonPopover, IonButton } from '@ionic/react';
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
// Progress bar
|
||||
// --------------------------------------------------
|
||||
// Host has no background by default - this will be added to the progress-buffer-bar
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Host has no background by default - this will be added to the progress-buffer-bar
|
||||
:host {
|
||||
/**
|
||||
* @prop --background: Same as --buffer-background when using a determinate progress bar, otherwise it styles the background of the ion-progress-bar itself.
|
||||
* @prop --progress-background: Color of the progress bar
|
||||
* @prop --buffer-background: Color of the buffer bar
|
||||
*/
|
||||
* @prop --background: Background of the progress track, or the buffer bar if `buffer` is set
|
||||
* @prop --progress-background: Background of the progress bar representing the current value
|
||||
* @prop --buffer-background: DEPRECATED, use `--background` instead
|
||||
*/
|
||||
--background: #{ion-color(primary, base, 0.3)};
|
||||
--progress-background: #{ion-color(primary, base)};
|
||||
--buffer-background: var(--background);
|
||||
|
||||
display: block;
|
||||
|
||||
position: relative;
|
||||
@@ -25,16 +26,6 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:host(.ion-color) {
|
||||
--progress-background: #{current-color(base)};
|
||||
--buffer-background: #{current-color(base, 0.3)};
|
||||
}
|
||||
|
||||
// indeterminate has no progress-buffer-bar, so it will be added to the host
|
||||
:host(.progress-bar-indeterminate) {
|
||||
background: var(--buffer-background);
|
||||
}
|
||||
|
||||
.progress,
|
||||
.progress-indeterminate,
|
||||
.indeterminate-bar-primary,
|
||||
@@ -128,27 +119,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Buffer style
|
||||
// --------------------------------------------------
|
||||
// Progress Bar: Buffer Circles
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
.buffer-circles {
|
||||
background: radial-gradient(ellipse at center, var(--buffer-background) 0%, var(--buffer-background) 30%, transparent 30%) repeat-x 5px center;
|
||||
background-image: radial-gradient(ellipse at center, var(--buffer-background) 0%, var(--buffer-background) 30%, transparent 30%);
|
||||
|
||||
/* stylelint-disable property-blacklist */
|
||||
background-repeat: repeat-x;
|
||||
background-position: 5px center;
|
||||
background-size: 10px 10px;
|
||||
/* stylelint-enable property-blacklist */
|
||||
|
||||
z-index: 0;
|
||||
animation: buffering 450ms infinite linear;
|
||||
}
|
||||
|
||||
// Progress Bar: Reversed
|
||||
// ------------------------------------------------------------------------
|
||||
// If reversed is set to true, the animation will be reversed
|
||||
// and the bars starting at the top right
|
||||
// --------------------------------------------------
|
||||
// and the bar will start at the top right
|
||||
|
||||
:host(.progress-bar-reversed) {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
// Progress paused
|
||||
// --------------------------------------------------
|
||||
// Progress Bar: Paused
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
:host(.progress-paused) {
|
||||
.indeterminate-bar-secondary,
|
||||
@@ -158,8 +155,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Animation Keyframes
|
||||
// --------------------------------------------------
|
||||
// Progress Bar: Color
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
:host(.ion-color) .progress-buffer-bar {
|
||||
background: #{current-color(base, 0.3)};
|
||||
}
|
||||
|
||||
:host(.ion-color) .buffer-circles {
|
||||
background-image: radial-gradient(ellipse at center, #{current-color(base, 0.3)} 0%, #{current-color(base, 0.3)} 30%, transparent 30%);
|
||||
}
|
||||
|
||||
:host(.ion-color) {
|
||||
.progress,
|
||||
.progress-indeterminate {
|
||||
background: #{current-color(base)};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Progress Bar: Animation Keyframes
|
||||
// ------------------------------------------------------------------------
|
||||
// Source: https://github.com/material-components/material-components-web/blob/master/packages/mdc-linear-progress/_keyframes.scss
|
||||
|
||||
@keyframes primary-indeterminate-translate {
|
||||
@@ -259,3 +275,4 @@
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,11 @@ import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
*
|
||||
* @part progress - The progress bar that shows the current value when `type` is `"determinate"` and slides back and forth when `type` is `"indeterminate"`.
|
||||
* @part stream - The animated circles that appear while buffering. This only shows when `buffer` is set and `type` is `"determinate"`.
|
||||
* @part track - The track bar behind the progress bar. If the `buffer` property is set and `type` is `"determinate"` the track will be the
|
||||
* width of the `buffer` value.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-progress-bar',
|
||||
@@ -77,10 +82,12 @@ export class ProgressBar implements ComponentInterface {
|
||||
}
|
||||
|
||||
const renderIndeterminate = () => {
|
||||
return [
|
||||
<div class="indeterminate-bar-primary"><span class="progress-indeterminate"></span></div>,
|
||||
<div class="indeterminate-bar-secondary"><span class="progress-indeterminate"></span></div>
|
||||
];
|
||||
return (
|
||||
<div part="track" class="progress-buffer-bar">
|
||||
<div class="indeterminate-bar-primary"><span part="progress" class="progress-indeterminate"></span></div>
|
||||
<div class="indeterminate-bar-secondary"><span part="progress" class="progress-indeterminate"></span></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderProgress = (value: number, buffer: number) => {
|
||||
@@ -88,7 +95,7 @@ const renderProgress = (value: number, buffer: number) => {
|
||||
const finalBuffer = clamp(0, buffer, 1);
|
||||
|
||||
return [
|
||||
<div class="progress" style={{ transform: `scaleX(${finalValue})` }}></div>,
|
||||
<div part="progress" class="progress" style={{ transform: `scaleX(${finalValue})` }}></div>,
|
||||
/**
|
||||
* Buffer circles with two container to move
|
||||
* the circles behind the buffer progress
|
||||
@@ -98,9 +105,9 @@ const renderProgress = (value: number, buffer: number) => {
|
||||
*/
|
||||
<div class={{ 'buffer-circles-container': true, 'ion-hide': finalBuffer === 1 }} style={{ transform: `translateX(${finalBuffer * 100}%)` }}>
|
||||
<div class="buffer-circles-container" style={{ transform: `translateX(-${finalBuffer * 100}%)` }}>
|
||||
<div class="buffer-circles"></div>
|
||||
<div part="stream" class="buffer-circles"></div>
|
||||
</div>
|
||||
</div>,
|
||||
<div class="progress-buffer-bar" style={{ transform: `scaleX(${finalBuffer})` }}></div>,
|
||||
<div part="track" class="progress-buffer-bar" style={{ transform: `scaleX(${finalBuffer})` }}></div>,
|
||||
];
|
||||
};
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
# ion-progress-bar
|
||||
|
||||
ion-progress-bar is a horizontal progress bar to visualize the progression of an operation and activity. You can choose between two types: `determinate` and `indeterminate`.
|
||||
Progress bars inform users about the status of ongoing processes, such as loading an app, submitting a form, or saving updates. There are two types of progress bars: `determinate` and `indeterminate`.
|
||||
|
||||
## Progress Type
|
||||
|
||||
### Determinate
|
||||
|
||||
If the percentage of an operation is known, you should use the determinate type. This is the default type and the progress is represented by the `value` property.
|
||||
Determinate is the default type. It should be used when the percentage of an operation is known. The progress is represented by setting the `value` property. This can be used to show the progress increasing from 0 to 100% of the track.
|
||||
|
||||
A buffer shows circles as animation to indicate some activity. If the `buffer` property is smaller than 1 you can show the additional buffering progress.
|
||||
If the `buffer` property is set, a buffer stream will show with animated circles to indicate activity. The value of the `buffer` property will also be represented by how much visible track there is. If the value of `buffer` is less than the `value` property, there will be no visible track. If `buffer` is equal to `1` then the buffer stream will be hidden.
|
||||
|
||||
### Indeterminate
|
||||
|
||||
If an operation is in progress and it's not necessary to indicate how long it will take.
|
||||
|
||||
If you add `reversed="true"`, you receive a query which is used to indicate pre-loading.
|
||||
The indeterminate type should be used when it is unknown how long the process will take. The progress bar is not tied to the `value`, instead it continually slides along the track until the process is complete.
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
@@ -144,13 +142,22 @@ export default defineComponent({
|
||||
| `value` | `value` | The value determines how much of the active bar should display when the `type` is `"determinate"`. The value should be between [0, 1]. | `number` | `0` |
|
||||
|
||||
|
||||
## Shadow Parts
|
||||
|
||||
| Part | Description |
|
||||
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `"progress"` | The progress bar that shows the current value when `type` is `"determinate"` and slides back and forth when `type` is `"indeterminate"`. |
|
||||
| `"stream"` | The animated circles that appear while buffering. This only shows when `buffer` is set and `type` is `"determinate"`. |
|
||||
| `"track"` | The track bar behind the progress bar. If the `buffer` property is set and `type` is `"determinate"` the track will be the width of the `buffer` value. |
|
||||
|
||||
|
||||
## CSS Custom Properties
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--background` | Same as --buffer-background when using a determinate progress bar, otherwise it styles the background of the ion-progress-bar itself. |
|
||||
| `--buffer-background` | Color of the buffer bar |
|
||||
| `--progress-background` | Color of the progress bar |
|
||||
| Name | Description |
|
||||
| ----------------------- | ---------------------------------------------------------------------- |
|
||||
| `--background` | Background of the progress track, or the buffer bar if `buffer` is set |
|
||||
| `--buffer-background` | DEPRECATED, use `--background` instead |
|
||||
| `--progress-background` | Background of the progress bar representing the current value |
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
10
core/src/components/progress-bar/test/standalone/e2e.ts
Normal file
10
core/src/components/progress-bar/test/standalone/e2e.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('progress-bar: standalone', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/progress-bar/test/standalone?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
@@ -12,19 +12,171 @@
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
|
||||
|
||||
<body>
|
||||
<h1>Default Progress Bar</h1>
|
||||
<h1>Default Progress Bars</h1>
|
||||
<ion-progress-bar></ion-progress-bar>
|
||||
|
||||
<h1>Default Progress Bar with 50% width</h1>
|
||||
<ion-progress-bar value="0.5"></ion-progress-bar>
|
||||
|
||||
<h1>Colorize Progress Bar</h1>
|
||||
<ion-progress-bar color="primary" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="secondary" value="0.5"></ion-progress-bar>
|
||||
|
||||
<h1>Other types</h1>
|
||||
<ion-progress-bar type="indeterminate"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Progress Bar: Colors</h1>
|
||||
<ion-progress-bar color="primary" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="secondary" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="tertiary" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="success" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="warning" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="danger" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="dark" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar color="light" value="0.5"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Default Types</h1>
|
||||
<ion-progress-bar></ion-progress-bar>
|
||||
<ion-progress-bar value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar color="warning" reversed="true" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar buffer="0"></ion-progress-bar>
|
||||
<ion-progress-bar color="danger" type="indeterminate"></ion-progress-bar>
|
||||
<ion-progress-bar type="indeterminate" reversed="true"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Custom: colors by part</h1>
|
||||
<ion-progress-bar class="custom-color-parts"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" buffer="0.9"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" color="warning" reversed="true" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" buffer="0"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" color="danger" type="indeterminate"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-parts" type="indeterminate" reversed="true"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Custom: colors by css variable</h1>
|
||||
<ion-progress-bar class="custom-color-variables"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" color="warning" reversed="true" value="0.20" buffer="0.4"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" buffer="0"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" color="danger" type="indeterminate"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-color-variables" type="indeterminate" reversed="true"></ion-progress-bar>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Custom border radius</h1>
|
||||
<ion-progress-bar class="custom-border-radius"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-border-radius" value="0.5"></ion-progress-bar>
|
||||
<ion-progress-bar class="custom-border-radius" type="indeterminate"></ion-progress-bar>
|
||||
|
||||
<h1>Custom transition</h1>
|
||||
<ion-progress-bar class="random-value" max="100"></ion-progress-bar>
|
||||
<ion-progress-bar class="random-value custom-transition" max="100"></ion-progress-bar>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
let randomValues = document.querySelectorAll('.random-value');
|
||||
|
||||
setInterval(() => {
|
||||
let value = Math.random();
|
||||
|
||||
for (let i = 0; i < randomValues.length; i++) {
|
||||
randomValues[i].value = value;
|
||||
}
|
||||
}, 100);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
|
||||
color: #a1a7b0;
|
||||
|
||||
margin-top: 10px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
hr {
|
||||
background: #eff1f3;
|
||||
border: none;
|
||||
|
||||
height: 1px;
|
||||
|
||||
margin-top: 18px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
ion-progress-bar {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom progress bar color using parts
|
||||
* ------------------------------------------------------
|
||||
* Note: in these examples setting the background on
|
||||
* each element should override the color prop
|
||||
*/
|
||||
|
||||
/* determinate buffer / track and indeterminate track */
|
||||
.custom-color-parts::part(track) {
|
||||
background:rgb(158, 157, 36, 0.2);
|
||||
}
|
||||
|
||||
/* determinate and indeterminate progress background */
|
||||
.custom-color-parts::part(progress) {
|
||||
background: #9e9d24;
|
||||
}
|
||||
|
||||
/* buffer stream (animated circles) */
|
||||
.custom-color-parts::part(stream) {
|
||||
background-image: radial-gradient(ellipse at center, rgb(158, 157, 36, 0.2) 0%, rgb(158, 157, 36, 0.2) 30%, transparent 30%);
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom progress bar color using css variables
|
||||
* ------------------------------------------------------
|
||||
* Note: in this example setting the background via
|
||||
* CSS variables should NOT override the color prop
|
||||
*/
|
||||
.custom-color-variables {
|
||||
--background: rgb(158, 157, 36, 0.2);
|
||||
--progress-background: #9e9d24;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom progress bar border radius using parts
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
.custom-border-radius {
|
||||
border-radius: 10px;
|
||||
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.custom-border-radius::part(progress) {
|
||||
border-radius: 0 50% 50% 0;
|
||||
}
|
||||
|
||||
.custom-border-radius[type="indeterminate"]::part(progress) {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom transition for fast value changes
|
||||
* ------------------------------------------------------
|
||||
* The first progress bar in the example has the default
|
||||
* transition, while the second has none. This is
|
||||
* apparent because they use the same values.
|
||||
*/
|
||||
.custom-transition::part(progress) {
|
||||
transition: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -187,11 +187,11 @@ export default defineComponent({
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ----------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------- |
|
||||
| `contentId` | `content-id` | The content `id` of the split-pane's main content. | `string \| undefined` | `undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the split pane will be hidden. | `boolean` | `false` |
|
||||
| `when` | `when` | When the split-pane should be shown. Can be a CSS media query expression, or a shortcut expression. Can also be a boolean expression. | `boolean \| string` | `QUERY['lg']` |
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ----------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------- |
|
||||
| `contentId` | `content-id` | The `id` of the main content. When using a router this is typically `ion-router-outlet`. When not using a router, this is typically your main view's `ion-content`. This is not the id of the `ion-content` inside of your `ion-menu`. | `string \| undefined` | `undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the split pane will be hidden. | `boolean` | `false` |
|
||||
| `when` | `when` | When the split-pane should be shown. Can be a CSS media query expression, or a shortcut expression. Can also be a boolean expression. | `boolean \| string` | `QUERY['lg']` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
@@ -29,7 +29,11 @@ export class SplitPane implements ComponentInterface {
|
||||
@State() visible = false;
|
||||
|
||||
/**
|
||||
* The content `id` of the split-pane's main content.
|
||||
* The `id` of the main content. When using
|
||||
* a router this is typically `ion-router-outlet`.
|
||||
* When not using a router, this is typically
|
||||
* your main view's `ion-content`. This is not the
|
||||
* id of the `ion-content` inside of your `ion-menu`.
|
||||
*/
|
||||
@Prop({ reflect: true }) contentId?: string;
|
||||
|
||||
|
||||
@@ -111,6 +111,48 @@ async function presentToastWithOptions() {
|
||||
### React
|
||||
|
||||
```tsx
|
||||
/* Using the useIonToast Hook */
|
||||
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonToast } from '@ionic/react';
|
||||
|
||||
const ToastExample: React.FC = () => {
|
||||
const [present, dismiss] = useIonToast();
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
buttons: [{ text: 'hide', handler: () => dismiss() }],
|
||||
message: 'toast from hook, click hide to dismiss',
|
||||
onDidDismiss: () => console.log('dismissed'),
|
||||
onWillDismiss: () => console.log('will dismiss'),
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Toast
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => present('hello from hook', 3000)}
|
||||
>
|
||||
Show Toast using params, closes in 3 secs
|
||||
</IonButton>
|
||||
<IonButton expand="block" onClick={dismiss}>
|
||||
Hide Toast
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using the IonToast Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonToast, IonContent, IonButton } from '@ionic/react';
|
||||
|
||||
|
||||
@@ -1,4 +1,46 @@
|
||||
```tsx
|
||||
/* Using the useIonToast Hook */
|
||||
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, useIonToast } from '@ionic/react';
|
||||
|
||||
const ToastExample: React.FC = () => {
|
||||
const [present, dismiss] = useIonToast();
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() =>
|
||||
present({
|
||||
buttons: [{ text: 'hide', handler: () => dismiss() }],
|
||||
message: 'toast from hook, click hide to dismiss',
|
||||
onDidDismiss: () => console.log('dismissed'),
|
||||
onWillDismiss: () => console.log('will dismiss'),
|
||||
})
|
||||
}
|
||||
>
|
||||
Show Toast
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand="block"
|
||||
onClick={() => present('hello from hook', 3000)}
|
||||
>
|
||||
Show Toast using params, closes in 3 secs
|
||||
</IonButton>
|
||||
<IonButton expand="block" onClick={dismiss}>
|
||||
Hide Toast
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* Using the IonToast Component */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IonToast, IonContent, IonButton } from '@ionic/react';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user