Skip to content

docs(input): input masking examples #2993

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8af4759
fix(tabs): correct router playground src (#2957)
thetaPC May 11, 2023
0e98782
docs(app-store): add reference to App Store Connect (#2198)
jstjnsn May 11, 2023
ba7a19f
docs(developing): update Java instructions to mention JDK 11 for late…
AustineA May 11, 2023
a27bbc4
docs(react): remove IonContent from tabs example (#2958)
liamdebeasi May 12, 2023
860713a
docs(vue): remove IonContent from tabs example (#2959)
liamdebeasi May 12, 2023
8dad7c3
docs(dark-mode): replace deprecated addListener() usage (#1908)
eyecatchup May 17, 2023
d0cf7e1
docs(quickstart): remove typescript for imports and tests (#2216)
praxxys May 17, 2023
c81e699
fix(CodeColor, LayeredColorsSelect): fix invalid DOM nesting (#2963)
averyjohnston May 18, 2023
374b2c0
docs(react): remove unopened closing tag (#2964)
mapsandapps May 18, 2023
3def4a7
fix: Ionic CLI links to latest docs page (#2961)
zakuru May 19, 2023
6e811ef
docs(tabs): angular usage does not use explicit ion-router-outlet (#2…
sean-perkins May 19, 2023
06b82b6
doc(CORS): update the native options (#2954)
kensodemann May 19, 2023
a209f34
feat(playground): inline dependencies per framework example (#2970)
sean-perkins May 23, 2023
016c429
wip: maskito docs
sean-perkins May 19, 2023
2dd0e3f
chore: use inline deps
sean-perkins May 23, 2023
6704bca
chore: bump version
sean-perkins May 25, 2023
44acaf5
fix(angular): async mask predicate
sean-perkins Jun 6, 2023
3c6444c
chore: react and vue examples
sean-perkins Jun 6, 2023
f06a4f0
docs: input masking examples
sean-perkins Jun 9, 2023
ab0076a
chore: cleanup
sean-perkins Jun 9, 2023
8e6c64c
Update docs/api/input.md
sean-perkins Jun 12, 2023
98231eb
Update static/usage/v7/input/mask/angular/example_component_html.md
sean-perkins Jun 12, 2023
271435b
Update static/usage/v7/input/mask/demo.html
sean-perkins Jun 12, 2023
d5bea93
chore: javascript respects mode selection
sean-perkins Jun 12, 2023
43da931
chore: angular respects mode selection
sean-perkins Jun 12, 2023
7777a37
chore: phone number casing
sean-perkins Jun 12, 2023
ff7da42
chore: relocate masking examples above theming
sean-perkins Jun 16, 2023
3241459
fix: use ion-content and padding for js example
sean-perkins Jun 16, 2023
04ed660
fix: react example maintains cursor position
sean-perkins Jun 16, 2023
4f6201a
fix: vue example uses async predicate
sean-perkins Jun 20, 2023
0367ecb
docs: install steps, bug reports/support
sean-perkins Jun 20, 2023
b5e7bba
Merge remote-tracking branch 'origin/feature-7.1' into sp/maskito
sean-perkins Jun 20, 2023
ec24dcf
chore: revert formatting
sean-perkins Jun 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/api/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,26 @@ import FilteringData from '@site/static/usage/v7/input/filtering/index.md';

<FilteringData />

## Input Masking

Input masks are expressions that constrain input to support valid input values. Ionic recommends using [Maskito](https://tinkoff.github.io/maskito/getting-started/what-is-maskito) for input masking. Maskito is a lightweight, dependency-free library for masking input fields. It supports a wide range of masks, including phone numbers, credit cards, dates, and more.

To get started with Maskito, install the library:

```bash
npm install @maskito/core @maskito/{angular,react,vue}
```

import Masking from '@site/static/usage/v7/input/mask/index.md';

<Masking />

:::note

Please submit bug reports with Maskito to the [Maskito Github repository](https://github.com/Tinkoff/maskito/issues). For technical support, please use the [Ionic Forum](https://forum.ionicframework.com/) or [Ionic Discord](http://chat.ionicframework.com/).

:::

## Theming

### Colors
Expand Down
22 changes: 20 additions & 2 deletions src/components/global/Playground/stackblitz.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ const openReactEditor = async (code: string, options?: EditorOptions) => {
options.version
);

const package_json = JSON.parse(defaultFiles[4]);

if (options?.dependencies) {
package_json.dependencies = {
...package_json.dependencies,
...options.dependencies,
};
}

const appTsx = 'src/App.tsx';
const files = {
'public/index.html': defaultFiles[6],
Expand All @@ -191,7 +200,7 @@ const openReactEditor = async (code: string, options?: EditorOptions) => {
'src/main.tsx': code,
'src/theme/variables.css': defaultFiles[2],
'tsconfig.json': defaultFiles[3],
'package.json': defaultFiles[4],
'package.json': JSON.stringify(package_json, null, 2),
'package-lock.json': defaultFiles[5],
...options?.files,
...options?.dependencies,
Expand Down Expand Up @@ -227,6 +236,15 @@ const openVueEditor = async (code: string, options?: EditorOptions) => {
options.version
);

const package_json = JSON.parse(defaultFiles[0]);

if (options?.dependencies) {
package_json.dependencies = {
...package_json.dependencies,
...options.dependencies,
};
}

const mainTs = 'src/main.ts';
const files = {
'src/App.vue': defaultFiles[6],
Expand All @@ -236,7 +254,7 @@ const openVueEditor = async (code: string, options?: EditorOptions) => {
'src/theme/variables.css': defaultFiles[3],
'index.html': defaultFiles[2],
'vite.config.ts': defaultFiles[4],
'package.json': defaultFiles[0],
'package.json': JSON.stringify(package_json, null, 2),
'package-lock.json': defaultFiles[1],
'tsconfig.json': defaultFiles[7],
'tsconfig.node.json': defaultFiles[8],
Expand Down
19 changes: 19 additions & 0 deletions static/usage/v7/input/mask/angular/app_module_ts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
```ts
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';

import { IonicModule } from '@ionic/angular';

import { AppComponent } from './app.component';
import { ExampleComponent } from './example.component';

import { MaskitoModule } from '@maskito/angular';

@NgModule({
imports: [BrowserModule, FormsModule, MaskitoModule, IonicModule.forRoot({})],
declarations: [AppComponent, ExampleComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
```
20 changes: 20 additions & 0 deletions static/usage/v7/input/mask/angular/example_component_html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
```html
<ion-list>
<ion-item>
<ion-input
label="Card number"
placeholder="0000 0000 0000 0000"
[maskito]="cardMask"
[maskitoElement]="maskPredicate"
></ion-input>
</ion-item>
<ion-item>
<ion-input
label="US phone number"
placeholder="+1 (xxx) xxx-xxxx"
[maskito]="phoneMask"
[maskitoElement]="maskPredicate"
></ion-input>
</ion-item>
</ion-list>
```
31 changes: 31 additions & 0 deletions static/usage/v7/input/mask/angular/example_component_ts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
```ts
import { Component } from '@angular/core';

import { MaskitoOptions, MaskitoElementPredicateAsync } from '@maskito/core';

@Component({
selector: 'app-example',
templateUrl: 'example.component.html',
})
export class ExampleComponent {
readonly phoneMask: MaskitoOptions = {
mask: ['+', '1', ' ', '(', /\d/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/],
};

readonly cardMask: MaskitoOptions = {
mask: [
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
],
};

readonly maskPredicate: MaskitoElementPredicateAsync = async (el) => (el as HTMLIonInputElement).getInputElement();
}
```
73 changes: 73 additions & 0 deletions static/usage/v7/input/mask/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Input</title>
<link rel="stylesheet" href="../../../common.css" />
<script src="../../../common.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@7/dist/ionic/ionic.esm.js"></script>
<script type="module">
import { Maskito } from 'https://cdn.jsdelivr.net/npm/@maskito/core/index.esm.js';
window.Maskito = Maskito;
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@7/css/ionic.bundle.css" />

<style>
ion-list {
width: 100%;
}
</style>
</head>

<body>
<ion-app>
<ion-content>
<div class="container">
<ion-list>
<ion-item>
<ion-input id="card" label="Card number" placeholder="0000 0000 0000 0000"></ion-input>
</ion-item>
<ion-item>
<ion-input id="phone" label="US phone number" placeholder="+1 (xxx) xxx-xxxx"></ion-input>
</ion-item>
</ion-list>
</div>
</ion-content>
</ion-app>
<script>
async function initPhoneMask() {
const ionInput = document.querySelector('#phone');
const nativeEl = await ionInput.getInputElement();

new window.Maskito(nativeEl, {
mask: ['+', '1', ' ', '(', /\d/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/],
});
}

async function initCardMask() {
const ionInput = document.querySelector('#card');
const nativeEl = await ionInput.getInputElement();

new window.Maskito(nativeEl, {
mask: [
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
],
});
}

window.addEventListener('appload', () => {
initCardMask();
initPhoneMask();
});
</script>
</body>
</html>
58 changes: 58 additions & 0 deletions static/usage/v7/input/mask/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Playground from '@site/src/components/global/Playground';

import javascript_index_html from './javascript/index_html.md';
import javascript_index_ts from './javascript/index_ts.md';

import react_main_tsx from './react.md';

import vue_example_vue from './vue.md';

import angular_app_module_ts from './angular/app_module_ts.md';
import angular_example_component_html from './angular/example_component_html.md';
import angular_example_component_ts from './angular/example_component_ts.md';

<Playground
version="7"
code={{
javascript: {
files: {
'index.html': javascript_index_html,
'index.ts': javascript_index_ts,
},
dependencies: {
'@maskito/core': '^0.16.0',
},
},
react: {
files: {
'src/main.tsx': react_main_tsx,
},
dependencies: {
'@maskito/react': '^0.16.0',
'@maskito/core': '^0.16.0',
},
},
vue: {
files: {
'src/components/Example.vue': vue_example_vue,
},
dependencies: {
'@maskito/vue': '^0.16.0',
'@maskito/core': '^0.16.0',
},
},
angular: {
files: {
'src/app/app.module.ts': angular_app_module_ts,
'src/app/example.component.html': angular_example_component_html,
'src/app/example.component.ts': angular_example_component_ts,
},
dependencies: {
'@maskito/angular': '^0.16.0',
'@maskito/core': '^0.16.0',
},
},
}}
src="usage/v7/input/mask/demo.html"
size="300px"
/>
58 changes: 58 additions & 0 deletions static/usage/v7/input/mask/javascript/index_html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
```html
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@7/css/core.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@7/css/ionic.bundle.css" />
</head>

<body>
<ion-app>
<ion-content class="ion-padding">
<ion-list>
<ion-item>
<ion-input id="card" label="Card number" placeholder="0000 0000 0000 0000"></ion-input>
</ion-item>
<ion-item>
<ion-input id="phone" label="US phone number" placeholder="+1 (xxx) xxx-xxxx"></ion-input>
</ion-item>
</ion-list>
</ion-content>

<script>
async function initPhoneMask() {
const ionInput = document.querySelector('#phone');
const nativeEl = await ionInput.getInputElement();

new window.Maskito(nativeEl, {
mask: ['+', '1', ' ', '(', /\d/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/],
});
}

async function initCardMask() {
const ionInput = document.querySelector('#card');
const nativeEl = await ionInput.getInputElement();

new window.Maskito(nativeEl, {
mask: [
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
' ',
...Array(4).fill(/\d/),
],
});
}

window.addEventListener('appload', () => {
initCardMask();
initPhoneMask();
});
</script>
</ion-app>
</body>
</html>
```
28 changes: 28 additions & 0 deletions static/usage/v7/input/mask/javascript/index_ts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
```ts
import { defineCustomElements } from '@ionic/core/loader';

import { Maskito } from '@maskito/core';

/* Core CSS required for Ionic components to work properly */
import '@ionic/core/css/core.css';

/* Basic CSS for apps built with Ionic */
import '@ionic/core/css/normalize.css';
import '@ionic/core/css/structure.css';
import '@ionic/core/css/typography.css';

/* Optional CSS utils that can be commented out */
import '@ionic/core/css/padding.css';
import '@ionic/core/css/float-elements.css';
import '@ionic/core/css/text-alignment.css';
import '@ionic/core/css/text-transformation.css';
import '@ionic/core/css/flex-utils.css';
import '@ionic/core/css/display.css';

/* Theme variables */
import './theme/variables.css';

defineCustomElements();

(window as any).Maskito = Maskito;
```
Loading