mirror of
https://github.com/tenrok/maska.git
synced 2026-05-15 11:59:38 +03:00
docs: updated docs for v3
This commit is contained in:
@@ -32,14 +32,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
cmd: 'jq .total.statements.pct packages/maska/coverage/coverage-summary.json'
|
cmd: 'jq .total.statements.pct packages/maska/coverage/coverage-summary.json'
|
||||||
|
|
||||||
- name: Build demo
|
|
||||||
run: npm run build --workspace=docs
|
|
||||||
|
|
||||||
- name: Upload demo artifact
|
|
||||||
uses: actions/upload-pages-artifact@v1
|
|
||||||
with:
|
|
||||||
path: ./packages/docs/docs
|
|
||||||
|
|
||||||
badge:
|
badge:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
@@ -70,6 +62,11 @@ jobs:
|
|||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@v3
|
||||||
|
with:
|
||||||
|
path: ./docs
|
||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v1
|
uses: actions/deploy-pages@v4
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
## Support ☕️
|
## Support ☕️
|
||||||
|
|
||||||
Do you like **Maska**? Please support me via [Boosty](https://boosty.to/beholdr).
|
> ❤️ [Please support](https://boosty.to/beholdr) Maska future development!
|
||||||
|
|
||||||
## Features ✨
|
## Features ✨
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ tasks:
|
|||||||
dev:maska-build-watch: npm run build:watch --workspace=packages/maska
|
dev:maska-build-watch: npm run build:watch --workspace=packages/maska
|
||||||
dev:svelte: npm run dev --workspace=packages/svelte
|
dev:svelte: npm run dev --workspace=packages/svelte
|
||||||
dev:vue: npm run dev --workspace=packages/vue
|
dev:vue: npm run dev --workspace=packages/vue
|
||||||
|
dev:docs:
|
||||||
|
dir: docs
|
||||||
|
cmd: http-server
|
||||||
|
|
||||||
code:test: npm run test --workspaces
|
code:test: npm run test --workspaces
|
||||||
code:coverage: npm run test:coverage --workspaces
|
code:coverage: npm run test:coverage --workspaces
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="refresh" content="0;URL=/v3" />
|
||||||
|
</head>
|
||||||
|
</html>
|
||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -1,8 +1,8 @@
|
|||||||
<object data="/maska.svg" type="image/svg+xml" style="max-width: 90%"></object>
|
<object data="../maska.svg" type="image/svg+xml" style="max-width: 90%"></object>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Maska {{versionLabel}}
|
# Maska
|
||||||
|
|
||||||
Do you like **Maska**? Please support me via [Boosty](https://boosty.to/beholdr).
|
Do you like **Maska**? Please support me via [Boosty](https://boosty.to/beholdr).
|
||||||
|
|
||||||
@@ -11,9 +11,6 @@ Do you like **Maska**? Please support me via [Boosty](https://boosty.to/beholdr)
|
|||||||
Here are several examples of basic masks that you could create with **Maska**.
|
Here are several examples of basic masks that you could create with **Maska**.
|
||||||
This demo is interactive: feel free to edit the examples.
|
This demo is interactive: feel free to edit the examples.
|
||||||
|
|
||||||
<div id="demo-app"></div>
|
|
||||||
<script type="module" src="dist/demo.js"></script>
|
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
|
|
||||||
<!-- tabs:start -->
|
<!-- tabs:start -->
|
||||||
@@ -4,17 +4,15 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, shrink-to-fit=no, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, shrink-to-fit=no, viewport-fit=cover">
|
||||||
<title>maska v3 docs</title>
|
<title>maska v2 docs</title>
|
||||||
|
|
||||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%220.9em%22 font-size=%22128%22>*️⃣</text></svg>">
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%220.9em%22 font-size=%22120%22>*️⃣</text></svg>">
|
||||||
|
|
||||||
<!-- Themes (light + dark) -->
|
<!-- Themes (light + dark) -->
|
||||||
<link rel="stylesheet" media="(prefers-color-scheme: dark)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css">
|
<link rel="stylesheet" media="(prefers-color-scheme: dark)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css">
|
||||||
<link rel="stylesheet" media="(prefers-color-scheme: light)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css">
|
<link rel="stylesheet" media="(prefers-color-scheme: light)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-versioned-plugin@0.0.1/styles.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-versioned-plugin@0.0.1/styles.css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="dist/style.css">
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--theme-hue: 281;
|
--theme-hue: 281;
|
||||||
@@ -55,8 +53,8 @@
|
|||||||
maxLevel: 2,
|
maxLevel: 2,
|
||||||
versionSelectorLabel: 'Version',
|
versionSelectorLabel: 'Version',
|
||||||
versions: [
|
versions: [
|
||||||
{ folder: '#', label: 'v3.x', default: true },
|
{ folder: 'v3', label: 'v3', default: true },
|
||||||
{ folder: 'v2', label: 'v2.x', default: false }
|
{ folder: 'v2', label: 'v2', default: false }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -70,6 +68,5 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/docsify@4/lib/plugins/search.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/docsify@4/lib/plugins/search.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/docsify-tabs@1"></script>
|
<script src="https://cdn.jsdelivr.net/npm/docsify-tabs@1"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/docsify-copy-code@2"></script>
|
<script src="https://cdn.jsdelivr.net/npm/docsify-copy-code@2"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/docsify/lib/plugins/external-script.min.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<object data="../maska.svg" type="image/svg+xml" style="max-width: 90%"></object>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Maska** is a simple zero-dependency input mask library.
|
||||||
|
|
||||||
|
You can use it with vanilla javascript or with your favorite framework. Out of the box there is integration with Vue 2/3, Svelte and Alpine.js, but you can integrate it into any framework.
|
||||||
|
|
||||||
|
> ❤️ [Please support](https://boosty.to/beholdr) Maska future development!
|
||||||
|
|
||||||
|
## Main components
|
||||||
|
|
||||||
|
- `Mask` — class for mask processing (can be used to mask any string)
|
||||||
|
- `MaskInput` — handles interaction with the `<input>` element
|
||||||
|
- Directives `vMaska` for Vue, `xMaska` for Alpine.js and `maska` action for Svelte
|
||||||
|
|
||||||
|
## Live Demo
|
||||||
|
|
||||||
|
<iframe height="300" style="width: 100%;" scrolling="no" title="Maska demo" src="https://codepen.io/beholdr/embed/QWREEMY?default-tab=html%2Cresult&editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
||||||
|
See the Pen <a href="https://codepen.io/beholdr/pen/QWREEMY">
|
||||||
|
Maska demo</a> by Alexander (<a href="https://codepen.io/beholdr">@beholdr</a>)
|
||||||
|
on <a href="https://codepen.io">CodePen</a>.
|
||||||
|
</iframe>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
- [Introduction](/)
|
||||||
|
- [Upgrade from v2](/upgrade)
|
||||||
|
- Usage
|
||||||
|
- [Vanilla](/vanilla)
|
||||||
|
- [Vue](/vue)
|
||||||
|
- [Alpine](/alpine)
|
||||||
|
- [Svelte](/svelte)
|
||||||
|
- Details
|
||||||
|
- [Options](/options)
|
||||||
|
- [Tokens](/tokens)
|
||||||
|
- [Hooks & Events](/hooks)
|
||||||
|
- [Known Issues](/issues)
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# Usage with Alpine.js
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **With NPM**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install @maskajs/alpine@3
|
||||||
|
```
|
||||||
|
|
||||||
|
And then register it:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Alpine from 'alpinejs'
|
||||||
|
import { xMaska } from '@maskajs/alpine'
|
||||||
|
|
||||||
|
Alpine.plugin(xMaska)
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### **From CDN**
|
||||||
|
|
||||||
|
You can use Maska directly from CDN using simple script tag with `data-init` attribute, just make sure to include it BEFORE Alpine's core JS file:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Maska Plugin -->
|
||||||
|
<script data-init src="https://cdn.jsdelivr.net/npm/@maskajs/alpine@3/dist/maska.umd.js"></script>
|
||||||
|
<!-- Alpine Core -->
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
This will automatically register Maska plugin inside Alpine.
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
|
||||||
|
## Directive signature
|
||||||
|
|
||||||
|
Maska provides custom Alpine.js directive for use with input:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input x-maska:argument.modifier="options">
|
||||||
|
```
|
||||||
|
|
||||||
|
- `argument` is a name of the bound variable (see example below)
|
||||||
|
- `modifier` modifier for bound variable value, could be one of:
|
||||||
|
- `masked` (default): variable will get a masked value (as in v-model)
|
||||||
|
- `unmasked`: variable will get an unmasked (raw) value
|
||||||
|
- `completed`: variable will be boolean, showing that mask is completed
|
||||||
|
- `options` is object with default options
|
||||||
|
|
||||||
|
|
||||||
|
## Minimal example
|
||||||
|
|
||||||
|
Apply `xMaska` directive to the input along with `data-maska` attribite:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input x-maska data-maska="#-#">
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Set mask options
|
||||||
|
|
||||||
|
To set default [options](/options) for the mask, pass options via **directive value**:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div x-data="{ options: { mask: '#-#', eager: true }}">
|
||||||
|
<input x-maska="options" data-maska-reversed>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can override default options with `data-maska-` attributes on the input. In the example above we set **eager** mode using options and **reversed** mode using `data-maska-reversed` attribute.
|
||||||
|
|
||||||
|
|
||||||
|
## Bind value
|
||||||
|
|
||||||
|
To get masked value you can use standard `x-model` directive on the input. But if you want to access an unmasked (raw) value or get to know when mask is completed, you can use **directive argument** and (optionally) **directive modifier**:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div x-data="{ maskedvalue: '', unmaskedvalue: '' }">
|
||||||
|
<input x-maska:unmaskedvalue.unmasked data-maska="#-#" x-model="maskedvalue">
|
||||||
|
|
||||||
|
Masked value: <span x-text="maskedvalue"></span>
|
||||||
|
Unmasked value: <span x-text="unmaskedvalue"></span>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
!> For correct work as directive argument, name of the bounded variable should be in **lower case**. So instead of `unmaskedValue` use `unmaskedvalue` or `unmasked_value`.
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
# Hooks & Events
|
||||||
|
|
||||||
|
## Hooks
|
||||||
|
|
||||||
|
Use hooks to transform masking value:
|
||||||
|
|
||||||
|
- `preProcess` hook is called before the mask processing
|
||||||
|
- `postProcess` hook is called after the mask processing, but before the input's value is set
|
||||||
|
|
||||||
|
For example, you can use it to check for a maximum length of a masked string:
|
||||||
|
|
||||||
|
```js
|
||||||
|
new MaskInput("input", {
|
||||||
|
postProcess: (value: string) => value.slice(0, 5)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
You can subscribe to `maska` event that fires after each mask processing.
|
||||||
|
Event will contain `detail` property with a given structure:
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Description**
|
||||||
|
|
||||||
|
- `masked`: masked value
|
||||||
|
- `unmasked`: unmasked value
|
||||||
|
- `completed`: flag that current mask is completed
|
||||||
|
|
||||||
|
### **Types**
|
||||||
|
```typescript
|
||||||
|
interface MaskaDetail {
|
||||||
|
masked: string
|
||||||
|
unmasked: string
|
||||||
|
completed: boolean
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
```js
|
||||||
|
const onMaska = (event: CustomEvent<MaskaDetail>) => {
|
||||||
|
console.log({
|
||||||
|
masked: event.detail.masked,
|
||||||
|
unmasked: event.detail.unmasked,
|
||||||
|
completed: event.detail.completed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
## **Vanilla JS**
|
||||||
|
|
||||||
|
```js
|
||||||
|
document.querySelector("input").addEventListener("maska", onMaska)
|
||||||
|
```
|
||||||
|
|
||||||
|
## **Vue**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<input v-maska data-maska="#-#" @maska="onMaska" />
|
||||||
|
```
|
||||||
|
|
||||||
|
## **Alpine**
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input x-maska data-maska="#-#" x-on:maska="onMaska" />
|
||||||
|
```
|
||||||
|
|
||||||
|
## **Svelte**
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<input use:maska data-maska="#-#" on:maska={onMaska} />
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
Alternatively, you can pass a callback function directly using the `onMaska` option:
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Vanilla JS**
|
||||||
|
```js
|
||||||
|
new MaskInput("input", {
|
||||||
|
onMaska: (detail: MaskaDetail) => console.log(detail.completed)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Vue**
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
const options = {
|
||||||
|
onMaska: (detail: MaskaDetail) => console.log(detail.completed)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska="options">
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Alpine**
|
||||||
|
```html
|
||||||
|
<div x-data="{ options: { onMaska: (detail) => console.log(detail.completed) }}">
|
||||||
|
<input x-maska="options">
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Svelte**
|
||||||
|
```svelte
|
||||||
|
<script lang="ts">
|
||||||
|
const options = {
|
||||||
|
onMaska: (detail: MaskaDetail) => console.log(detail.completed)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input use:maska={options}>
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
@@ -4,16 +4,15 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, shrink-to-fit=no, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, shrink-to-fit=no, viewport-fit=cover">
|
||||||
<title>maska v2 docs</title>
|
<title>maska v3 docs</title>
|
||||||
|
|
||||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%220.9em%22 font-size=%22128%22>*️⃣</text></svg>">
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%220.9em%22 font-size=%22120%22>*️⃣</text></svg>">
|
||||||
|
|
||||||
<!-- Themes (light + dark) -->
|
<!-- Themes (light + dark) -->
|
||||||
<link rel="stylesheet" media="(prefers-color-scheme: dark)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css">
|
<link rel="stylesheet" media="(prefers-color-scheme: dark)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css">
|
||||||
<link rel="stylesheet" media="(prefers-color-scheme: light)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css">
|
<link rel="stylesheet" media="(prefers-color-scheme: light)" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-versioned-plugin@0.0.1/styles.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-versioned-plugin@0.0.1/styles.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mingchyuanko/docsify-plugin-page-toc/dist/toc.css">
|
||||||
<link rel="stylesheet" href="../dist/style.css">
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
@@ -26,15 +25,20 @@
|
|||||||
.sidebar > .app-name {
|
.sidebar > .app-name {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.sidebar-nav li.active {
|
.sidebar-nav > ul > li:has(ul) {
|
||||||
background: #990bdb;
|
margin-top: 18px;
|
||||||
color: #fff;
|
font-size: 0.8em;
|
||||||
margin-left: -10px;
|
text-transform: uppercase;
|
||||||
padding-left: 10px;
|
letter-spacing: 0.1ex;
|
||||||
border-radius: 2px;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.sidebar-nav li.active a {
|
.sidebar-nav > ul > li > ul {
|
||||||
color: #fff;
|
margin-left: 0;
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-transform: none;
|
||||||
|
letter-spacing: normal;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 500px) {
|
@media screen and (max-width: 500px) {
|
||||||
@@ -53,10 +57,12 @@
|
|||||||
name: 'maska',
|
name: 'maska',
|
||||||
repo: 'beholdr/maska',
|
repo: 'beholdr/maska',
|
||||||
maxLevel: 2,
|
maxLevel: 2,
|
||||||
|
auto2top: true,
|
||||||
|
loadSidebar: true,
|
||||||
versionSelectorLabel: 'Version',
|
versionSelectorLabel: 'Version',
|
||||||
versions: [
|
versions: [
|
||||||
{ folder: '#', label: 'v3.x', default: true },
|
{ folder: 'v3', label: 'v3', default: true },
|
||||||
{ folder: 'v2', label: 'v2.x', default: false }
|
{ folder: 'v2', label: 'v2', default: false }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -70,8 +76,6 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/docsify@4/lib/plugins/search.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/docsify@4/lib/plugins/search.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/docsify-tabs@1"></script>
|
<script src="https://cdn.jsdelivr.net/npm/docsify-tabs@1"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/docsify-copy-code@2"></script>
|
<script src="https://cdn.jsdelivr.net/npm/docsify-copy-code@2"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/docsify/lib/plugins/external-script.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@mingchyuanko/docsify-plugin-page-toc/dist/toc.min.js"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/maska@2/dist/maska.umd.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Known issues
|
||||||
|
|
||||||
|
## Unsupported input types
|
||||||
|
|
||||||
|
Please use Maska only for inputs of the following types: `text`, `search`, `URL`, `tel` and `password`.
|
||||||
|
If you need a numeric keyboard, use `type="text"` with attribute `inputmode="numeric"`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input type="text" inputmode="numeric">
|
||||||
|
```
|
||||||
|
|
||||||
|
## Vuetify and other UI frameworks
|
||||||
|
|
||||||
|
Some frameworks with custom components may not pass `data-` attributes to native input elements. In such cases, you will need to set the mask and other options using directive value:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
const options = { mask: '#-#' }
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input v-maska="options">
|
||||||
|
```
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
# Options
|
||||||
|
|
||||||
|
There are two main components that you can customize: the `Mask` class and the `MaskInput` class. You typically work directly with the latter, but since `MaskInput` options extend `Mask` options, you can configure both using a single object.
|
||||||
|
|
||||||
|
## `Mask` options
|
||||||
|
|
||||||
|
To set options for a `Mask` class you can pass an object when creating the class:
|
||||||
|
|
||||||
|
```js
|
||||||
|
new Mask({ mask: "#-#", eager: true, number: { locale: 'de' }})
|
||||||
|
```
|
||||||
|
|
||||||
|
Options passed in this way will be used as default values and can be overridden by `data-maska-` attributes of a given input element.
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Description**
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Option / data-attribute</th>
|
||||||
|
<th>Default</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>mask</code><br><code>data-maska</code></td>
|
||||||
|
<td><code>—</code></td>
|
||||||
|
<td>Mask to apply (string, array of strings or function). If you pass an empty string or <code>null</code> it will disable a mask</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>tokens</code><br><code>data-maska-tokens</code></td>
|
||||||
|
<td><code>—</code></td>
|
||||||
|
<td>Custom tokens object. See tokens page</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>tokensReplace</code><br><code>data-maska-tokens-replace</code></td>
|
||||||
|
<td><code>false</code></td>
|
||||||
|
<td>If custom tokens should replace default tokens (if not set, they will merge)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>eager</code><br><code>data-maska-eager</code></td>
|
||||||
|
<td><code>false</code></td>
|
||||||
|
<td>Eager mode will show static characters before you type them, e.g. when you type <code>1</code>, eager mask <code>#-#</code> will show <code>1-</code> and non-eager will show <code>1</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>reversed</code><br><code>data-maska-reversed</code></td>
|
||||||
|
<td><code>false</code></td>
|
||||||
|
<td>In reversed mode mask will grow backwards, e.g. for numbers</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>number.locale</code><br><code>data-maska-number-locale</code></td>
|
||||||
|
<td><code>en</code></td>
|
||||||
|
<td>Locale for number mode. Determine the national format for the number</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>number.fraction</code><br><code>data-maska-number-fraction</code></td>
|
||||||
|
<td><code>0</code></td>
|
||||||
|
<td>Fraction digits for the number (<code>0</code> allows only integer numbers)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>number.unsigned</code><br><code>data-maska-number-unsigned</code></td>
|
||||||
|
<td><code>false</code></td>
|
||||||
|
<td>Unsigned mode for the number: if you want to accept only positive numbers</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
### **Types**
|
||||||
|
```typescript
|
||||||
|
interface MaskOptions {
|
||||||
|
mask?: MaskType
|
||||||
|
tokens?: MaskTokens
|
||||||
|
tokensReplace?: boolean
|
||||||
|
eager?: boolean
|
||||||
|
reversed?: boolean
|
||||||
|
number?: MaskNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
type MaskType = string | string[] | ((input: string) => string) | null
|
||||||
|
|
||||||
|
interface MaskToken {
|
||||||
|
pattern: RegExp
|
||||||
|
multiple?: boolean
|
||||||
|
optional?: boolean
|
||||||
|
repeated?: boolean
|
||||||
|
transform?: (char: string) => string
|
||||||
|
}
|
||||||
|
|
||||||
|
type MaskTokens = Record<string, MaskToken>
|
||||||
|
|
||||||
|
interface MaskNumber {
|
||||||
|
locale?: string
|
||||||
|
fraction?: number
|
||||||
|
unsigned?: boolean
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
|
||||||
|
## `MaskInput` options
|
||||||
|
|
||||||
|
`MaskInput` options can only be set when creating a class, as they are too complex to use `data-maska-` attributes for them. Along with `MaskInput` options you can also pass any `Mask` class options (or set them using `data-maska-` attributes):
|
||||||
|
|
||||||
|
```js
|
||||||
|
new MaskInput("input", {
|
||||||
|
onMaska: (detail) => console.log(detail.completed)
|
||||||
|
mask: "#-#",
|
||||||
|
reversed: true,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Description**
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Option</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>onMaska</code></td>
|
||||||
|
<td>Сallback (event analog), called after every mask processing</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>preProcess</code></td>
|
||||||
|
<td>Hook called before mask processing</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>postProcess</code></td>
|
||||||
|
<td>Hook called after mask processing</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
### **Types**
|
||||||
|
```typescript
|
||||||
|
interface MaskInputOptions extends MaskOptions {
|
||||||
|
onMaska?: (detail: MaskaDetail) => void
|
||||||
|
preProcess?: (value: string) => string
|
||||||
|
postProcess?: (value: string) => string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MaskaDetail {
|
||||||
|
masked: string
|
||||||
|
unmasked: string
|
||||||
|
completed: boolean
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
?> Examples on this page use vanilla version of Maska. The framework specific versions have the same options, but should be passed in a different way: for example, as a directive value.
|
||||||
|
|
||||||
|
|
||||||
|
## Number mask
|
||||||
|
|
||||||
|
Number mode makes it easy to format numbers according to the selected locale.
|
||||||
|
|
||||||
|
You can enable the number mode using `number` option or `data-maska-number-` attributes.
|
||||||
|
In that case you don't need to set `mask` or any other options. All number options are optional:
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **By data-attributes**
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Minimal example -->
|
||||||
|
<input data-maska-number>
|
||||||
|
|
||||||
|
<!-- Full example -->
|
||||||
|
<input
|
||||||
|
data-maska-number-locale="ru"
|
||||||
|
data-maska-number-fraction="2"
|
||||||
|
data-maska-number-unsigned
|
||||||
|
>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **By option**
|
||||||
|
|
||||||
|
```js
|
||||||
|
// minimal example
|
||||||
|
new MaskInput("input", {
|
||||||
|
number: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
// full example
|
||||||
|
new MaskInput("input", {
|
||||||
|
number: {
|
||||||
|
locale: "ru",
|
||||||
|
fraction: 2,
|
||||||
|
unsigned: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
?> Under the hood Maska uses [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) for number formatting.
|
||||||
|
|
||||||
|
|
||||||
|
## Dynamic masks
|
||||||
|
|
||||||
|
Pass `mask` as **array** or **function** to make it dynamic:
|
||||||
|
|
||||||
|
- With **array** a suitable mask will be chosen by length (smallest first)
|
||||||
|
- With **function** you can select mask with custom logic using value
|
||||||
|
|
||||||
|
```js
|
||||||
|
new MaskInput("input", {
|
||||||
|
mask: (value: string) => value.startsWith('1') ? '#-#' : '##-##'
|
||||||
|
})
|
||||||
|
```
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# Usage with Svelte
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You can install Maska with following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install @maskajs/svelte@3
|
||||||
|
```
|
||||||
|
|
||||||
|
And then use it in your `.svelte` component:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
import { maska } from '@maskajs/svelte'
|
||||||
|
|
||||||
|
<input use:maska data-maska="#-#" />
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Action signature
|
||||||
|
|
||||||
|
Maska provides simple Svelte action for use with input:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input use:maska={options}>
|
||||||
|
```
|
||||||
|
|
||||||
|
- `options` is object with default options
|
||||||
|
|
||||||
|
|
||||||
|
## Minimal example
|
||||||
|
|
||||||
|
Apply `maska` action to the input along with `data-maska` attribite:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { maska } from '@maskajs/svelte'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input use:maska data-maska="#-#">
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Set mask options
|
||||||
|
|
||||||
|
To set default [options](/options) for the mask, pass options via **directive value**:
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<script>
|
||||||
|
import { maska } from '@maskajs/svelte'
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
mask: "#-#",
|
||||||
|
eager: true
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input use:maska={options} data-maska-reversed>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can override default options with `data-maska-` attributes on the input. In the example above we set **eager** mode using options and **reversed** mode using `data-maska-reversed` attribute.
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Tokens
|
||||||
|
|
||||||
|
## Default tokens
|
||||||
|
|
||||||
|
There are 3 tokens defined by default:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
'#': { pattern: /[0-9]/ }, // digits
|
||||||
|
'@': { pattern: /[a-zA-Z]/ }, // letters
|
||||||
|
'*': { pattern: /[a-zA-Z0-9]/ }, // letters & digits
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
?> Use `!` before token to escape symbol. For example `!#` will render `#` instead of a digit.
|
||||||
|
|
||||||
|
|
||||||
|
## Custom tokens
|
||||||
|
|
||||||
|
Add custom tokens via `data-maska-tokens` attribute or by `tokens` option:
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **By data-attributes**
|
||||||
|
|
||||||
|
When using `data-maska-tokens`, there are two possible formats:
|
||||||
|
|
||||||
|
- **JSON form** should be a valid JSON-string (but can use both single and double quotes) with pattern in a string format without delimiters
|
||||||
|
- **Simple form** should be a string in format: `T:P:M|...` where:
|
||||||
|
- `T` is token
|
||||||
|
- `P` is pattern in string form
|
||||||
|
- `M` is optional modifier (see below)
|
||||||
|
- `|` is separator for multiple tokens
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input data-maska="Z-Z" data-maska-tokens="{ 'Z': { 'pattern': '[A-Z]' }}">
|
||||||
|
<input data-maska="Z-Z" data-maska-tokens="Z:[A-Z]">
|
||||||
|
<input data-maska="Z-z" data-maska-tokens="Z:[A-Z]|z:[a-z]:multiple">
|
||||||
|
```
|
||||||
|
|
||||||
|
?> You can’t set the `transform` function for a token using `data-maska-tokens` attribute.
|
||||||
|
If you need to do this, you should use the `tokens` option instead.
|
||||||
|
|
||||||
|
### **By option**
|
||||||
|
|
||||||
|
```js
|
||||||
|
new MaskInput("[data-maska]", {
|
||||||
|
mask: "A-A",
|
||||||
|
tokens: {
|
||||||
|
A: { pattern: /[A-Z]/, transform: (chr: string) => chr.toUpperCase() }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
!> When using `tokens` option, pattern should be a valid regular expression object.
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
|
||||||
|
## Token modifiers
|
||||||
|
|
||||||
|
Every token can have a modifier, for example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
0: { pattern: /[0-9]/, optional: true },
|
||||||
|
9: { pattern: /[0-9]/, repeated: true },
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `optional` for optional token
|
||||||
|
- `multiple` for token that can match multiple characters till the next token starts
|
||||||
|
- `repeated` for token that should be repeated. This token will match only one character, but the token itself (or group of such tokens) can be repeated any number of times
|
||||||
|
|
||||||
|
| Modifier | Example usage | Mask | Tokens
|
||||||
|
| --- | --- | --- | ---
|
||||||
|
| `optional` | IP address | `#00.#00.#00.#00` | `0:[0-9]:optional`
|
||||||
|
| `multiple` | CARDHOLDER NAME | `A A` | `A:[A-Z]:multiple`
|
||||||
|
| `repeated` | Money (1 234,56) | `9 99#,##` <small>reversed</small> | `9:[0-9]:repeated`
|
||||||
|
|
||||||
|
|
||||||
|
## Transform tokens
|
||||||
|
|
||||||
|
For custom tokens you can define `transform` function, applied to a character before masking.
|
||||||
|
For example, transforming letters to uppercase on input:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
A: { pattern: /[A-Z]/, transform: (chr: string) => chr.toUpperCase() }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
?> You can also use [hooks](/hooks) for transforming whole value before/after masking.
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Upgrade from v2
|
||||||
|
|
||||||
|
## New package for Vue
|
||||||
|
|
||||||
|
Maska v2 was a universal package for both vanilla JS and Vue version. Maska v3 is separated to several different packages:
|
||||||
|
|
||||||
|
- package `maska` is for vanilla version
|
||||||
|
- package `@maskajs/vue` is for Vue version
|
||||||
|
|
||||||
|
If you used Maska with Vue you need to delete `maska` package and install `@maskajs/vue` package.
|
||||||
|
|
||||||
|
?> If you used Maska without a framework, just upgrade package to `maska@3` version.
|
||||||
|
|
||||||
|
## New directive format
|
||||||
|
|
||||||
|
### Bind value
|
||||||
|
|
||||||
|
To bind a masked value with Maska v2 you used the **directive value** with a bound variable as an object:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
const boundObject = reactive({
|
||||||
|
masked: '',
|
||||||
|
unmasked: '',
|
||||||
|
completed: false
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska="boundObject">
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
With v3, you need to use a **directive argument** and (optionally) a **directive modifier**:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
const boundobject = ref('')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska:boundobject.unmasked>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mask options
|
||||||
|
|
||||||
|
To pass mask options with v2 you have used the **directive argument**:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
const options = reactive({
|
||||||
|
mask: "#-#",
|
||||||
|
eager: true
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska:[options]>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
With v3, you need to use for this a **directive value**:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
const options = reactive({
|
||||||
|
mask: "#-#",
|
||||||
|
eager: true
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska="options">
|
||||||
|
</template>
|
||||||
|
```
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
# Usage without a framework
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **With NPM**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install maska@3
|
||||||
|
```
|
||||||
|
|
||||||
|
And then import it in your code:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Mask, MaskInput } from 'maska'
|
||||||
|
|
||||||
|
new MaskInput("[data-maska]") // for masked input
|
||||||
|
const mask = new Mask({ mask: "#-#" }) // for programmatic use
|
||||||
|
```
|
||||||
|
|
||||||
|
### **From CDN / UMD**
|
||||||
|
|
||||||
|
You can use Maska directly from CDN with simple script tag. Library API will be exposed on the global `Maska` object:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/maska@3/dist/maska.umd.js"></script>
|
||||||
|
<script>
|
||||||
|
const { Mask, MaskInput } = Maska
|
||||||
|
|
||||||
|
new MaskInput("[data-maska]") // for masked input
|
||||||
|
const mask = new Mask({ mask: "#-#" }) // for programmatic use
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **From CDN / ES**
|
||||||
|
|
||||||
|
For modern browsers you can use ES modules build with (optional) [import maps](https://caniuse.com/import-maps):
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"maska": "https://cdn.jsdelivr.net/npm/maska@3/dist/maska.mjs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { Mask, MaskInput } from 'maska'
|
||||||
|
|
||||||
|
new MaskInput("[data-maska]") // for masked input
|
||||||
|
const mask = new Mask({ mask: "#-#" }) // for programmatic use
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
?> Notice that we are using `<script type="module">` in this case.
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
|
||||||
|
## Minimal example
|
||||||
|
|
||||||
|
Add to your input element `data-maska` attribute:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input data-maska="#-#">
|
||||||
|
```
|
||||||
|
|
||||||
|
Then import and initialize `MaskInput`, passing input element(s) or `querySelector` expression as first argument:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { MaskInput } from "maska"
|
||||||
|
|
||||||
|
// init with query selector
|
||||||
|
new MaskInput("[data-maska]")
|
||||||
|
|
||||||
|
// or with element
|
||||||
|
const input = document.querySelector('[data-maska]')
|
||||||
|
new MaskInput(input)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Set mask options
|
||||||
|
|
||||||
|
Usually you set mask via `data-maska` attribute. But you can pass mask and other [options](/options) via second argument. It will be a default options that can be overriden by `data-maska-` attributes:
|
||||||
|
|
||||||
|
```js
|
||||||
|
new MaskInput(input, { mask: "#-#" })
|
||||||
|
```
|
||||||
|
|
||||||
|
## Programmatic use
|
||||||
|
|
||||||
|
You can use mask function programmatically by importing `Mask` class.
|
||||||
|
There are three methods available:
|
||||||
|
|
||||||
|
- `masked(value)` returns masked version of given value
|
||||||
|
- `unmasked(value)` returns unmasked version of given value
|
||||||
|
- `completed(value)` returns `true` if given value makes mask completed
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Mask } from "maska"
|
||||||
|
|
||||||
|
const mask = new Mask({ mask: "#-#" })
|
||||||
|
|
||||||
|
mask.masked("12") // = 1-2
|
||||||
|
mask.unmasked("12") // = 12
|
||||||
|
mask.completed("12") // = true
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Destroy mask
|
||||||
|
|
||||||
|
To destroy mask use `destroy()` method:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const mask = new MaskInput(input)
|
||||||
|
mask.destroy()
|
||||||
|
```
|
||||||
+252
@@ -0,0 +1,252 @@
|
|||||||
|
# Usage with Vue
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **With NPM**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install @maskajs/vue@3
|
||||||
|
```
|
||||||
|
|
||||||
|
And then import it in your `.vue` component:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { vMaska } from '@maskajs/vue'
|
||||||
|
```
|
||||||
|
|
||||||
|
### **From CDN / UMD**
|
||||||
|
|
||||||
|
You can use Maska directly from CDN with simple script tag. Library API will be exposed on the global `Maska` object:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@maskajs/vue@3/dist/maska.umd.js"></script>
|
||||||
|
<script>
|
||||||
|
const { vMaska } = Maska
|
||||||
|
|
||||||
|
Vue.createApp({ directives: { maska: vMaska }}).mount('#app')
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **From CDN / ES**
|
||||||
|
|
||||||
|
For modern browsers you can use ES modules build with (optional) [import maps](https://caniuse.com/import-maps):
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"maska": "https://cdn.jsdelivr.net/npm/@maskajs/vue@3/dist/maska.mjs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { vMaska } from 'maska'
|
||||||
|
|
||||||
|
Vue.createApp({ directives: { maska: vMaska }}).mount('#app')
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
?> Notice that we are using `<script type="module">` in this case.
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
|
||||||
|
## Directive signature
|
||||||
|
|
||||||
|
Maska provides custom Vue directive for use with input:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input v-maska:argument.modifier="options">
|
||||||
|
```
|
||||||
|
|
||||||
|
- `argument` is a name of the bound variable (see example below)
|
||||||
|
- `modifier` modifier for bound variable value, could be one of:
|
||||||
|
- `masked` (default): variable will get a masked value (as in v-model)
|
||||||
|
- `unmasked`: variable will get an unmasked (raw) value
|
||||||
|
- `completed`: variable will be boolean, showing that mask is completed
|
||||||
|
- `options` is object with default options
|
||||||
|
|
||||||
|
## Minimal example
|
||||||
|
|
||||||
|
Import `vMaska` directive and apply it to the input along with `data-maska` attribite:
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Composition API**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska data-maska="#-#">
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Options API**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script>
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
directives: { maska: vMaska }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska data-maska="#-#">
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
|
||||||
|
## Set mask options
|
||||||
|
|
||||||
|
To set default [options](/options) for the mask, pass options via **directive value**:
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Composition API**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { reactive } from "vue"
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
// could be plain object too
|
||||||
|
const options = reactive({
|
||||||
|
mask: "#-#",
|
||||||
|
eager: true
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska="options" data-maska-reversed>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Options API**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script>
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
directives: { maska: vMaska },
|
||||||
|
data: () => ({
|
||||||
|
options: {
|
||||||
|
mask: "#-#",
|
||||||
|
eager: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska="options" data-maska-reversed>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
You can override default options with `data-maska-` attributes on the input. In the example above we set **eager** mode using options and **reversed** mode using `data-maska-reversed` attribute.
|
||||||
|
|
||||||
|
?> Sometimes using directive value is the only way to configure a mask, because you don't have access to the input element: for example, when using Maska with Vuetify.
|
||||||
|
|
||||||
|
|
||||||
|
## Bind value
|
||||||
|
|
||||||
|
To get masked value you can use standard `v-model` directive on the input. But if you want to access an unmasked (raw) value or get to know when mask is completed, you can use **directive argument** and (optionally) **directive modifier**:
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Composition API**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue"
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
const maskedvalue = ref('')
|
||||||
|
const unmaskedvalue = ref('')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska:unmaskedvalue.unmasked data-maska="#-#" v-model="maskedvalue">
|
||||||
|
|
||||||
|
Masked value: {{ maskedvalue }}
|
||||||
|
Unmasked value: {{ unmaskedvalue }}
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Options API**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script>
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
directives: { maska: vMaska },
|
||||||
|
data: () => ({
|
||||||
|
maskedvalue: "",
|
||||||
|
unmaskedvalue: ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input v-maska:unmaskedvalue.unmasked data-maska="#-#" v-model="maskedvalue">
|
||||||
|
|
||||||
|
Masked value: {{ maskedvalue }}
|
||||||
|
Unmasked value: {{ unmaskedvalue }}
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
|
|
||||||
|
!> For correct work as directive argument, name of the bounded variable should be in **lower case**. So instead of `unmaskedValue` use `unmaskedvalue` or `unmasked_value`.
|
||||||
|
|
||||||
|
|
||||||
|
## Usage with Nuxt
|
||||||
|
|
||||||
|
To use Maska in Nuxt 3 you can make a simple plugin. Create file `maska.ts` in `plugins` folder:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
export default defineNuxtPlugin((nuxtApp) => {
|
||||||
|
nuxtApp.vueApp.directive("maska", vMaska)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can use v-maska directive in your app:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input v-model="value" v-maska data-maska="#-#" />
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Global registration of directive
|
||||||
|
|
||||||
|
<!-- tabs:start -->
|
||||||
|
### **Vue 3**
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { createApp } from "vue"
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
createApp({}).directive("maska", vMaska)
|
||||||
|
|
||||||
|
// or in case of CDN load
|
||||||
|
Vue.createApp({}).directive("maska", Maska.vMaska)
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Vue 2**
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Vue from "vue"
|
||||||
|
import { vMaska } from "maska"
|
||||||
|
|
||||||
|
Vue.directive("maska", vMaska)
|
||||||
|
|
||||||
|
// or in case of CDN load
|
||||||
|
Vue.directive("maska", Maska.vMaska)
|
||||||
|
```
|
||||||
|
<!-- tabs:end -->
|
||||||
+1
-2
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*",
|
"packages/*"
|
||||||
"packages/docs"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,572 +0,0 @@
|
|||||||
<object data="/maska.svg" type="image/svg+xml" style="max-width: 90%"></object>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Maska {{versionLabel}}
|
|
||||||
|
|
||||||
Do you like **Maska**? Please support me via [Boosty](https://boosty.to/beholdr).
|
|
||||||
|
|
||||||
# Live Demo
|
|
||||||
|
|
||||||
Here are several examples of basic masks that you could create with **Maska**.
|
|
||||||
This demo is interactive: feel free to edit the examples.
|
|
||||||
|
|
||||||
<div id="demo-app"></div>
|
|
||||||
<script type="module" src="../dist/demo_v2.js"></script>
|
|
||||||
|
|
||||||
# Install
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
## **Via npm**
|
|
||||||
|
|
||||||
```
|
|
||||||
npm i maska
|
|
||||||
```
|
|
||||||
|
|
||||||
## **CDN / Global build**
|
|
||||||
|
|
||||||
You can use **Maska** directly from CDN with simple script tag.
|
|
||||||
Library API will be exposed on the global `Maska` object:
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/maska@2/dist/maska.umd.js"></script>
|
|
||||||
<script>
|
|
||||||
const { Mask, MaskInput, vMaska } = Maska
|
|
||||||
|
|
||||||
new MaskInput("[data-maska]") // for masked input
|
|
||||||
const mask = new Mask({ mask: "#-#" }) // for programmatic use
|
|
||||||
Vue.createApp({ directives: { maska: vMaska }}).mount('#app') // Vue directive
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
## **CDN / ES modules**
|
|
||||||
|
|
||||||
For modern browsers you can use ES modules build with (optional) [import maps](https://caniuse.com/import-maps):
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script type="importmap">
|
|
||||||
{
|
|
||||||
"imports": {
|
|
||||||
"maska": "https://cdn.jsdelivr.net/npm/maska@2/dist/maska.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script type="module">
|
|
||||||
import { Mask, MaskInput, vMaska } from 'maska'
|
|
||||||
|
|
||||||
new MaskInput("[data-maska]") // for masked input
|
|
||||||
const mask = new Mask({ mask: "#-#" }) // for programmatic use
|
|
||||||
Vue.createApp({ directives: { maska: vMaska }}).mount('#app') // Vue directive
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
Notice that we are using `<script type="module">` in this case.
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
**Maska** library consists of three main components:
|
|
||||||
|
|
||||||
- `Mask` class to mask string values
|
|
||||||
- `MaskInput` class to apply `Mask` processing to `<input>`
|
|
||||||
- `vMaska` directive to simplify using of library within Vue components
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
## **Vanilla JS**
|
|
||||||
|
|
||||||
Start with simple input element and `data-maska` attribute:
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<input data-maska="#-#">
|
|
||||||
```
|
|
||||||
|
|
||||||
Then import and init `MaskInput`, passing input element(s) or `querySelector` expression as first argument:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
import { MaskInput } from "maska"
|
|
||||||
new MaskInput("[data-maska]")
|
|
||||||
```
|
|
||||||
|
|
||||||
Usually you set mask via `data-maska` attribute. But you can pass mask and other [options](#options) via second argument (it will be a default options that can be overriden by `data-maska-` attributes):
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
new MaskInput("input", { mask: "#-#" })
|
|
||||||
```
|
|
||||||
|
|
||||||
To destroy mask use `destroy()` method:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
const mask = new MaskInput(...)
|
|
||||||
mask.destroy()
|
|
||||||
```
|
|
||||||
|
|
||||||
## **Vue**
|
|
||||||
|
|
||||||
Import `vMaska` directive and apply it to the input along with `data-maska` attribite:
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Composition API**
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script setup>
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input v-maska data-maska="#-#">
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Options API**
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script>
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
directives: { maska: vMaska }
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input v-maska data-maska="#-#">
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
### Bind value
|
|
||||||
|
|
||||||
To get masked value you can use standard `v-model` directive.
|
|
||||||
But if you want to access an unmasked (raw) value, you can pass a variable as `v-maska` directive value.
|
|
||||||
This variable should be a reactive object that will contains three fields after mask processing:
|
|
||||||
|
|
||||||
- `masked`: string with masked result
|
|
||||||
- `unmasked`: string with unmasked result
|
|
||||||
- `completed`: boolean flag indicating that mask is completed
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Composition API**
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script setup>
|
|
||||||
import { reactive, ref } from "vue"
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
const maskedValue = ref('')
|
|
||||||
const boundObject = reactive({})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input v-maska="boundObject" v-model="maskedValue">
|
|
||||||
|
|
||||||
Masked value: {{ maskedValue }} or {{ boundObject.masked }}
|
|
||||||
Unmasked value: {{ boundObject.unmasked }}
|
|
||||||
<span v-if="boundObject.completed">✅ Mask completed</span>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Options API**
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script>
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
directives: { maska: vMaska },
|
|
||||||
data: () => ({
|
|
||||||
maskedValue: "",
|
|
||||||
boundObject: {
|
|
||||||
masked: "",
|
|
||||||
unmasked: "",
|
|
||||||
completed: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input v-maska="boundObject" v-model="maskedValue">
|
|
||||||
|
|
||||||
Masked value: {{ maskedValue }} or {{ boundObject.masked }}
|
|
||||||
Unmasked value: {{ boundObject.unmasked }}
|
|
||||||
<span v-if="boundObject.completed">✅ Mask completed</span>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
### Set mask options
|
|
||||||
|
|
||||||
To set default options for the mask you could use directive *argument* (part after `v-maska:`). It can be plain or reactive object and should be wrapped in `[]`:
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Composition API**
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script setup>
|
|
||||||
import { reactive } from "vue"
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
const options = reactive({
|
|
||||||
mask: "#-#",
|
|
||||||
eager: true
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input v-maska:[options]>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Options API**
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<script>
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
directives: { maska: vMaska },
|
|
||||||
data: () => ({
|
|
||||||
options: {
|
|
||||||
mask: "#-#",
|
|
||||||
eager: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input v-maska:[options]>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
?> Please see [issue#149](https://github.com/beholdr/maska/issues/149): options object should be assigned in the current file.
|
|
||||||
|
|
||||||
You can set options and bind to an object at the same time:
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<input v-maska:[options]="boundObject">
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Global registration of directive
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Vue 3**
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
import { createApp } from "vue"
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
createApp({}).directive("maska", vMaska)
|
|
||||||
|
|
||||||
// or in case of CDN load
|
|
||||||
Vue.createApp({}).directive("maska", Maska.vMaska)
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Vue 2**
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
import Vue from "vue"
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
Vue.directive("maska", vMaska)
|
|
||||||
|
|
||||||
// or in case of CDN load
|
|
||||||
Vue.directive("maska", Maska.vMaska)
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
## **Nuxt 3**
|
|
||||||
|
|
||||||
To use Maska in Nuxt 3 you can make a simple plugin. Create file `maska.ts` in `plugins` folder:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
import { vMaska } from "maska"
|
|
||||||
|
|
||||||
export default defineNuxtPlugin((nuxtApp) => {
|
|
||||||
nuxtApp.vueApp.directive("maska", vMaska)
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you can use `v-maska` directive in your app:
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<input v-model="value" v-maska data-maska="#-#" />
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
# Options
|
|
||||||
|
|
||||||
## `Mask` options
|
|
||||||
|
|
||||||
Every option of `Mask` class can be set via `data-maska-` attributes or by passing on init.
|
|
||||||
Options passed on init will be used as defaults and could be overriden by `data-maska-` attributes.
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Description**
|
|
||||||
|
|
||||||
- `mask / data-maska` — mask to apply (**string**, **array of strings** or **function**). If you pass empty string or `null` it will disable a mask
|
|
||||||
- `tokens / data-maska-tokens` — custom tokens object
|
|
||||||
- `tokensReplace / data-maska-tokens-replace` — if custom tokens should replace default tokens (if not set, they will merge)
|
|
||||||
- `eager / data-maska-eager` — eager mode will show static characters before you type them, e.g. when you type `1`, eager mask `#-#` will show `1-` and non-eager will show `1`
|
|
||||||
- `reversed / data-maska-reversed` — in reversed mode mask will grow backwards, e.g. for numbers
|
|
||||||
|
|
||||||
### **Types**
|
|
||||||
``` ts
|
|
||||||
interface MaskOptions {
|
|
||||||
mask?: MaskType
|
|
||||||
tokens?: MaskTokens
|
|
||||||
tokensReplace?: boolean
|
|
||||||
eager?: boolean
|
|
||||||
reversed?: boolean
|
|
||||||
}
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<input data-maska="A-A" data-maska-tokens="A:[A-Z]" data-maska-eager>
|
|
||||||
```
|
|
||||||
|
|
||||||
## `MaskInput` options
|
|
||||||
|
|
||||||
`MaskInput` options could be set only by passing second argument on init.
|
|
||||||
Along with `MaskInput` options you could pass any `Mask` options as well (or set them via `data-maska-` attributes).
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Description**
|
|
||||||
|
|
||||||
- `onMaska` — [callback](#events) on every mask processing
|
|
||||||
- `preProcess` — [hook](#hooks) before mask processing
|
|
||||||
- `postProcess` — [hook](#hooks) after mask processing
|
|
||||||
|
|
||||||
### **Types**
|
|
||||||
``` ts
|
|
||||||
interface MaskInputOptions extends MaskOptions {
|
|
||||||
onMaska?: (detail: MaskaDetail) => void
|
|
||||||
preProcess?: (value: string) => string
|
|
||||||
postProcess?: (value: string) => string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
new MaskInput("input", {
|
|
||||||
mask: "#-#",
|
|
||||||
reversed: true,
|
|
||||||
onMaska: (detail: MaskaDetail) => console.log(detail.completed)
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
# Tokens
|
|
||||||
|
|
||||||
There are 3 tokens defined by default:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
{
|
|
||||||
'#': { pattern: /[0-9]/ }, // digits
|
|
||||||
'@': { pattern: /[a-zA-Z]/ }, // letters
|
|
||||||
'*': { pattern: /[a-zA-Z0-9]/ }, // letters & digits
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
?> Use `!` before token to escape symbol. For example `!#` will render `#` instead of a digit.
|
|
||||||
|
|
||||||
## Custom tokens
|
|
||||||
|
|
||||||
Add custom tokens via `data-maska-tokens` attribute or by `tokens` option:
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **By data-attr**
|
|
||||||
|
|
||||||
When using `data-maska-tokens`, there are two possible formats:
|
|
||||||
|
|
||||||
- **Full form** should be a valid JSON-string (but can use both single and double quotes) with pattern in string format without delimiters
|
|
||||||
- **Simple form** should be a string in format: `T:P:M|T:P:M` where:
|
|
||||||
- `T` is token
|
|
||||||
- `P` is pattern in string form
|
|
||||||
- `M` is optional modifier (see below)
|
|
||||||
- `|` is separator for multiple tokens
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<input data-maska="Z-Z" data-maska-tokens="{ 'Z': { 'pattern': '[A-Z]' }}">
|
|
||||||
<input data-maska="Z-Z" data-maska-tokens="Z:[A-Z]">
|
|
||||||
<input data-maska="Z-z" data-maska-tokens="Z:[A-Z]|z:[a-z]:multiple">
|
|
||||||
```
|
|
||||||
|
|
||||||
?> You can’t set `transform` function for token via `data-maska-tokens`.
|
|
||||||
If you need this, use `tokens` option instead.
|
|
||||||
|
|
||||||
### **By option**
|
|
||||||
|
|
||||||
When using `tokens` option, pattern should be a valid regular expression object:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
new MaskInput("[data-maska]", {
|
|
||||||
mask: "A-A",
|
|
||||||
tokens: {
|
|
||||||
A: { pattern: /[A-Z]/, transform: (chr: string) => chr.toUpperCase() }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
## Token modifiers
|
|
||||||
|
|
||||||
Every token can have a modifier, for example:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
{
|
|
||||||
0: { pattern: /[0-9]/, optional: true },
|
|
||||||
9: { pattern: /[0-9]/, repeated: true },
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `optional` for optional token
|
|
||||||
- `multiple` for token that can match multiple characters till the next token starts
|
|
||||||
- `repeated` for tokens that should be repeated. This token will match only one character, but the token itself (or group of such tokens) can be repeated any number of times
|
|
||||||
|
|
||||||
| Modifier | Example usage | Mask | Tokens
|
|
||||||
| --- | --- | --- | ---
|
|
||||||
| `optional` | IP address | `#00.#00.#00.#00` | `0:[0-9]:optional`
|
|
||||||
| `multiple` | CARDHOLDER NAME | `A A` | `A:[A-Z]:multiple`
|
|
||||||
| `repeated` | Money (1 234,56) | `9 99#,##` <small>reversed</small> | `9:[0-9]:repeated`
|
|
||||||
|
|
||||||
## Transform tokens
|
|
||||||
|
|
||||||
For custom tokens you can define `transform` function, applied to a character before masking.
|
|
||||||
For example, transforming letters to uppercase on input:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
{
|
|
||||||
A: { pattern: /[A-Z]/, transform: (chr: string) => chr.toUpperCase() }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
?> You can also use [hooks](#hooks) for transforming whole value before/after masking.
|
|
||||||
|
|
||||||
# Dynamic masks
|
|
||||||
|
|
||||||
Pass `mask` as **array** or **function** to make it dynamic:
|
|
||||||
|
|
||||||
- With **array** a suitable mask will be chosen by length (smallest first)
|
|
||||||
- With **function** you can select mask with custom logic using value
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
new MaskInput("input", {
|
|
||||||
mask: (value: string) => value.startsWith('1') ? '#-#' : '##-##'
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
# Hooks
|
|
||||||
|
|
||||||
Use hooks for transforming whole value:
|
|
||||||
|
|
||||||
- `preProcess` hook called before mask processing
|
|
||||||
- `postProcess` hook called after mask processing, but before setting input's value
|
|
||||||
|
|
||||||
For example, you can use it to check for a maximum length of masked string:
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
new MaskInput("input", {
|
|
||||||
postProcess: (value: string) => value.slice(0, 5)
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
# Events
|
|
||||||
|
|
||||||
There are two events you can subscribe to get the masking result:
|
|
||||||
|
|
||||||
- `maska` event
|
|
||||||
- `input` event
|
|
||||||
|
|
||||||
They are essentially the same, but the `input` event could be fired by any input logic, and the `maska` event is library specific.
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
## **Vanilla JS**
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
document.querySelector("input").addEventListener("maska", onMaska)
|
|
||||||
```
|
|
||||||
|
|
||||||
## **Vue**
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<input v-maska data-maska="#-#" @maska="onMaska" />
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
Both events contains `detail` property with given structure:
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Description**
|
|
||||||
|
|
||||||
- `masked`: masked value
|
|
||||||
- `unmasked`: unmasked value
|
|
||||||
- `completed`: flag that current mask is completed
|
|
||||||
|
|
||||||
### **Types**
|
|
||||||
``` ts
|
|
||||||
interface MaskaDetail {
|
|
||||||
masked: string
|
|
||||||
unmasked: string
|
|
||||||
completed: boolean
|
|
||||||
}
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
const onMaska = (event: CustomEvent<MaskaDetail>) => {
|
|
||||||
console.log({
|
|
||||||
masked: event.detail.masked,
|
|
||||||
unmasked: event.detail.unmasked,
|
|
||||||
completed: event.detail.completed
|
|
||||||
})
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively, you can pass callback function directly with `MaskInput` option `onMaska`:
|
|
||||||
|
|
||||||
<!-- tabs:start -->
|
|
||||||
### **Vanilla JS**
|
|
||||||
``` ts
|
|
||||||
new MaskInput("input", {
|
|
||||||
onMaska: (detail: MaskaDetail) => console.log(detail.completed)
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Vue**
|
|
||||||
``` html
|
|
||||||
<script setup>
|
|
||||||
const options = {
|
|
||||||
onMaska: (detail: MaskaDetail) => console.log(detail.completed)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<input v-maska:[options]>
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
<!-- tabs:end -->
|
|
||||||
|
|
||||||
# Programmatic use
|
|
||||||
|
|
||||||
You can use mask function programmatically by importing `Mask` class.
|
|
||||||
There are three methods available:
|
|
||||||
|
|
||||||
- `masked(value)` returns masked version of given value
|
|
||||||
- `unmasked(value)` returns unmasked version of given value
|
|
||||||
- `completed(value)` returns `true` if given value makes mask complete
|
|
||||||
|
|
||||||
``` ts
|
|
||||||
import { Mask } from "maska"
|
|
||||||
|
|
||||||
const mask = new Mask({ mask: "#-#" })
|
|
||||||
|
|
||||||
mask.masked("12") // = 1-2
|
|
||||||
mask.unmasked("12") // = 12
|
|
||||||
mask.completed("12") // = true
|
|
||||||
```
|
|
||||||
|
|
||||||
# Known issues
|
|
||||||
|
|
||||||
When used on input of type `number`, could have inconsistent behavior in different browsers. Use attribute `inputmode="numeric"` with `type="text"` if you need a numeric keyboard.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "vite build",
|
|
||||||
"test": "echo 'No tests, skip'",
|
|
||||||
"test:coverage": "echo 'No tests, skip'",
|
|
||||||
"lint": "echo 'No linting, skip'",
|
|
||||||
"lint:fix": "echo 'No linting, skip'",
|
|
||||||
"version": "echo 'No version, skip'"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^20.12.7",
|
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
|
||||||
"typescript": "^5.4.5",
|
|
||||||
"vite": "^5.2.8",
|
|
||||||
"vue": "^3.2.45",
|
|
||||||
"vue-live": "^2.5.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed, ref } from 'vue'
|
|
||||||
|
|
||||||
import { VueLive } from 'vue-live'
|
|
||||||
import 'vue-live/style.css'
|
|
||||||
|
|
||||||
const props = defineProps(['examples'])
|
|
||||||
|
|
||||||
const selectedExample = ref(0)
|
|
||||||
const code = computed(() => props.examples[selectedExample.value].code)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="demo-select">
|
|
||||||
<label for="demo-example-select">Choose mask example:</label>
|
|
||||||
<select v-model="selectedExample" id="demo-example-select">
|
|
||||||
<option v-for="(example, idx) in examples" :value="idx">
|
|
||||||
{{ example.label }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<VueLive :code="code" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.demo-select {
|
|
||||||
border: 1px solid var(--docsifytabs-border-color);
|
|
||||||
padding: 1rem var(--docsifytabs-content-padding) 1.5rem;
|
|
||||||
border-bottom: none;
|
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
}
|
|
||||||
.demo-select > label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
color: var(--search-input-placeholder-color);
|
|
||||||
}
|
|
||||||
.demo-select > select {
|
|
||||||
width: 100%;
|
|
||||||
padding: 7px;
|
|
||||||
border-radius: 4px;
|
|
||||||
color: var(--search-input-color);
|
|
||||||
border: 1px solid var(--search-input-border-color);
|
|
||||||
background-color: var(--search-input-background-color);
|
|
||||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
|
|
||||||
appearance: none;
|
|
||||||
background-position: right 0.5rem center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 1.5em 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VueLive-container {
|
|
||||||
border: 1px solid var(--docsifytabs-border-color);
|
|
||||||
margin: var(--docsifytabs-margin);
|
|
||||||
margin-top: 0;
|
|
||||||
border-radius: 0 0 5px 5px;
|
|
||||||
}
|
|
||||||
.VueLive-container .VueLive-editor {
|
|
||||||
padding: 2.3rem var(--docsifytabs-content-padding);
|
|
||||||
background-color: var(--code-theme-background);
|
|
||||||
border-radius: 0 0 0 5px;
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.VueLive-container .VueLive-editor::after {
|
|
||||||
content: 'Сode';
|
|
||||||
position: absolute;
|
|
||||||
top: 0.75em;
|
|
||||||
right: 0.75em;
|
|
||||||
opacity: 0.6;
|
|
||||||
color: inherit;
|
|
||||||
font-size: var(--font-size-s);
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.VueLive-container .VueLive-editor .prism-editor__editor,
|
|
||||||
.VueLive-container .VueLive-editor .prism-editor__textarea {
|
|
||||||
font-family: var(--code-font-family);
|
|
||||||
}
|
|
||||||
.VueLive-container .VueLivePreview {
|
|
||||||
padding: 2rem var(--docsifytabs-content-padding);
|
|
||||||
border-radius: 0 0 5px 0;
|
|
||||||
background-color: transparent;
|
|
||||||
position: relative;
|
|
||||||
width: 45%;
|
|
||||||
}
|
|
||||||
.VueLive-container .VueLivePreview::after {
|
|
||||||
content: 'Result';
|
|
||||||
position: absolute;
|
|
||||||
top: 0.75em;
|
|
||||||
right: var(--docsifytabs-content-padding);
|
|
||||||
opacity: 0.6;
|
|
||||||
color: inherit;
|
|
||||||
font-size: var(--font-size-s);
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.VueLive-container .VueLivePreview input {
|
|
||||||
font-size: var(--modular-scale-1);
|
|
||||||
padding: 8px 10px;
|
|
||||||
border: 1px solid var(--search-input-border-color);
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: var(--search-input-background-color);
|
|
||||||
color: var(--search-input-color);
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 999px) {
|
|
||||||
.VueLive-container {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.VueLive-container .VueLive-editor,
|
|
||||||
.VueLive-container .VueLivePreview {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import { createApp } from 'vue'
|
|
||||||
|
|
||||||
import { vMaska } from '../../vue/src'
|
|
||||||
import App from './App.vue'
|
|
||||||
|
|
||||||
const examples = [
|
|
||||||
{
|
|
||||||
label: 'Simple mask',
|
|
||||||
code: `<input v-maska data-maska="#-#" value="12">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Phone mask',
|
|
||||||
code: `<input v-maska data-maska="+1 ### ###-##-##">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'HEX-color',
|
|
||||||
code: `<input\n v-maska\n data-maska="!#HHHHHH"\n data-maska-tokens="H:[0-9a-fA-F]"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'IP address with optional digits',
|
|
||||||
code: `<input\n v-maska\n data-maska="#00.#00.#00.#00"\n data-maska-tokens="0:[0-9]:optional"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Dynamic mask: CPF/CNPJ',
|
|
||||||
code: `<input\n v-maska\n data-maska="[\n '###.###.###-##',\n '##.###.###/####-##'\n ]"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Cardholder name: via hook',
|
|
||||||
code: `const options = {\n preProcess: val => val.toUpperCase()\n}\n\n<input\n v-maska="options"\n data-maska="A A"\n data-maska-tokens="A:[A-Z]:multiple"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Cardholder name: via token transform',
|
|
||||||
code: `const options = {\n tokens: {\n A: {\n pattern: /[A-Z]/,\n multiple: true,\n transform: chr => chr.toUpperCase()\n }\n }\n}\n\n<input v-maska="options" data-maska="A A">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Year: with current year as a limit',
|
|
||||||
code: `const options = {\n postProcess: val => {\n const max = "" + new Date().getFullYear()\n return val > max ? max : val\n }\n}\n\n<input v-maska="options" data-maska="####">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Money format: simple',
|
|
||||||
code: `<input\n v-maska\n data-maska="0.99"\n data-maska-tokens="0:\\d:multiple|9:\\d:optional"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Money format: full via hooks',
|
|
||||||
code: `const options = {\n preProcess: val => val.replace(/[$,]/g, ''),\n postProcess: val => {\n if (!val) return ''\n\n const sub = 3 - (val.includes('.') ? val.length - val.indexOf('.') : 0)\n\n return Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD'\n }).format(val)\n .slice(0, sub ? -sub : undefined)\n }\n}\n\n<input\n v-maska="options"\n data-maska="0.99"\n data-maska-tokens="0:\\d:multiple|9:\\d:optional"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Reversed number format with thousand separators',
|
|
||||||
code: `<input\n v-maska\n data-maska="9 99#.##"\n data-maska-tokens="9:[0-9]:repeated"\n data-maska-reversed\n>`
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
createApp(App, { examples })
|
|
||||||
.directive('maska', vMaska)
|
|
||||||
.mount('#demo-app')
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import { createApp } from 'vue'
|
|
||||||
|
|
||||||
import App from '../App.vue'
|
|
||||||
|
|
||||||
const examples = [
|
|
||||||
{
|
|
||||||
label: 'Simple mask',
|
|
||||||
code: `<input v-maska data-maska="#-#" value="12">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Phone mask',
|
|
||||||
code: `<input v-maska data-maska="+1 ### ###-##-##">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'HEX-color',
|
|
||||||
code: `<input\n v-maska\n data-maska="!#HHHHHH"\n data-maska-tokens="H:[0-9a-fA-F]"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'IP address with optional digits',
|
|
||||||
code: `<input\n v-maska\n data-maska="#00.#00.#00.#00"\n data-maska-tokens="0:[0-9]:optional"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Dynamic mask: CPF/CNPJ',
|
|
||||||
code: `<input\n v-maska\n data-maska="[\n '###.###.###-##',\n '##.###.###/####-##'\n ]"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Cardholder name: via hook',
|
|
||||||
code: `const options = {\n preProcess: val => val.toUpperCase()\n}\n\n<input\n v-maska:[options]\n data-maska="A A"\n data-maska-tokens="A:[A-Z]:multiple"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Cardholder name: via token transform',
|
|
||||||
code: `const options = {\n tokens: {\n A: {\n pattern: /[A-Z]/,\n multiple: true,\n transform: chr => chr.toUpperCase()\n }\n }\n}\n\n<input v-maska:[options] data-maska="A A">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Year: with current year as a limit',
|
|
||||||
code: `const options = {\n postProcess: val => {\n const max = "" + new Date().getFullYear()\n return val > max ? max : val\n }\n}\n\n<input v-maska:[options] data-maska="####">`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Money format: simple',
|
|
||||||
code: `<input\n v-maska\n data-maska="0.99"\n data-maska-tokens="0:\\d:multiple|9:\\d:optional"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Money format: full via hooks',
|
|
||||||
code: `const options = {\n preProcess: val => val.replace(/[$,]/g, ''),\n postProcess: val => {\n if (!val) return ''\n\n const sub = 3 - (val.includes('.') ? val.length - val.indexOf('.') : 0)\n\n return Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD'\n }).format(val)\n .slice(0, sub ? -sub : undefined)\n }\n}\n\n<input\n v-maska:[options]\n data-maska="0.99"\n data-maska-tokens="0:\\d:multiple|9:\\d:optional"\n>`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Reversed number format with thousand separators',
|
|
||||||
code: `<input\n v-maska\n data-maska="9 99#.##"\n data-maska-tokens="9:[0-9]:repeated"\n data-maska-reversed\n>`
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
createApp(App, { examples })
|
|
||||||
.directive('maska', Maska.vMaska)
|
|
||||||
.mount('#demo-app')
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { defineConfig } from 'vite'
|
|
||||||
import vue from '@vitejs/plugin-vue'
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
base: '',
|
|
||||||
build: {
|
|
||||||
outDir: 'docs/dist',
|
|
||||||
cssCodeSplit: false,
|
|
||||||
rollupOptions: {
|
|
||||||
input: {
|
|
||||||
demo: 'src/index.ts',
|
|
||||||
demo_v2: 'src/v2/index.ts'
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
entryFileNames: '[name].js',
|
|
||||||
assetFileNames: '[name][extname]'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: [vue()]
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user