-
Notifications
You must be signed in to change notification settings - Fork 341
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* raw * feat(masks): remove junk * feat(masks): add docs * feat(masks): improve suggestion when option group * feat(masks): add static tokens if only one possible solution is left * docs(masks): improve phone extended demo * feat(masks): correct suggestion when only one possible solution is left
- Loading branch information
Showing
22 changed files
with
1,597 additions
and
0 deletions.
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
packages/docs/page-config/composables/input-mask/examples/CreditCard.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<template> | ||
<VaInput v-model="text" ref="vaInput" placeholder="#### #### #### ####" /> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { VaInput, useInputMask, createMaskFromRegex } from 'vuestic-ui' | ||
const text = ref('') | ||
const vaInput = ref() | ||
useInputMask(createMaskFromRegex(/\d\d\d\d \d\d\d\d \d\d\d\d \d\d\d\d/), vaInput) | ||
</script> |
13 changes: 13 additions & 0 deletions
13
packages/docs/page-config/composables/input-mask/examples/Date.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<template> | ||
<VaInput v-model="text" ref="vaInput" placeholder="YYYY/MM/DD" /> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { VaInput, useInputMask, createMaskDate } from 'vuestic-ui' | ||
const text = ref('') | ||
const vaInput = ref() | ||
useInputMask(createMaskDate(), vaInput) | ||
</script> |
13 changes: 13 additions & 0 deletions
13
packages/docs/page-config/composables/input-mask/examples/DefaultRegex.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<template> | ||
<VaInput v-model="text" ref="vaInput" placeholder="Vuestic - 0000 - Vue" /> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { VaInput, useInputMask, createMaskFromRegex } from 'vuestic-ui' | ||
const text = ref('') | ||
const vaInput = ref() | ||
useInputMask(createMaskFromRegex(/Vuestic - \d\d\d\d - Vue/), vaInput) | ||
</script> |
15 changes: 15 additions & 0 deletions
15
packages/docs/page-config/composables/input-mask/examples/Ipv6Regex.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<template> | ||
<VaInput v-model="text" ref="vaInput" placeholder="0000:0000:0000:0000:0000:0000:0000:0000" class="w-full" /> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { VaInput, useInputMask, createMaskFromRegex } from 'vuestic-ui' | ||
const text = ref('') | ||
const vaInput = ref() | ||
const ipv6Regex = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))/ | ||
useInputMask(createMaskFromRegex(ipv6Regex), vaInput) | ||
</script> |
13 changes: 13 additions & 0 deletions
13
packages/docs/page-config/composables/input-mask/examples/Numeral.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<template> | ||
<VaInput v-model="text" ref="vaInput" placeholder="12304.4213" /> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { VaInput, useInputMask, createNumeralMask } from 'vuestic-ui' | ||
const text = ref('') | ||
const vaInput = ref() | ||
useInputMask(createNumeralMask(), vaInput) | ||
</script> |
13 changes: 13 additions & 0 deletions
13
packages/docs/page-config/composables/input-mask/examples/Phone.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<template> | ||
<VaInput v-model="text" ref="vaInput" placeholder="+380 (93) 000-00-00" /> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { VaInput, useInputMask, createMaskFromRegex } from 'vuestic-ui' | ||
const text = ref('') | ||
const vaInput = ref() | ||
useInputMask(createMaskFromRegex(/(\+380 \(\d{2}\)|\d{3}) (\d){3}-\d\d-\d\d/), vaInput) | ||
</script> |
49 changes: 49 additions & 0 deletions
49
packages/docs/page-config/composables/input-mask/examples/PhoneExtended.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<template> | ||
<VaInput ref="vaInput" v-model="text" placeholder="+380 (93) 000-00-00" /> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { VaInput, useInputMask, createMaskFromRegex } from 'vuestic-ui' | ||
const text = ref('') | ||
const vaInput = ref() | ||
const ukrPhoneMask = createMaskFromRegex(/\+380 \(\d{2}\) (\d){3}-\d\d-\d\d/) | ||
const usPhoneMask = createMaskFromRegex(/\+1 \(\d{3}\) (\d){3}-\d\d-\d\d/) | ||
const nationalPhoneMask = createMaskFromRegex(/\+(380|1) /) | ||
useInputMask({ | ||
format(text) { | ||
if (text.startsWith('+380')) { | ||
return ukrPhoneMask.format(text) | ||
} | ||
if (text.startsWith('+1')) { | ||
return usPhoneMask.format(text) | ||
} | ||
return nationalPhoneMask.format(text) | ||
}, | ||
unformat(text, tokens) { | ||
if (text.startsWith('+380')) { | ||
return ukrPhoneMask.unformat(text, tokens) | ||
} | ||
if (text.startsWith('+1')) { | ||
return usPhoneMask.unformat(text, tokens) | ||
} | ||
return nationalPhoneMask.unformat(text, tokens) | ||
}, | ||
handleCursor(selectionStart, selectionEnd, oldTokens, newTokens, text, data) { | ||
if (text.startsWith('+380')) { | ||
return ukrPhoneMask.handleCursor(selectionStart, selectionEnd, oldTokens, newTokens, text, data) | ||
} | ||
if (text.startsWith('+1')) { | ||
return usPhoneMask.handleCursor(selectionStart, selectionEnd, oldTokens, newTokens, text, data) | ||
} | ||
return nationalPhoneMask.handleCursor(selectionStart, selectionEnd, oldTokens, newTokens, text, data) | ||
}, | ||
reverse: false, | ||
}, vaInput) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
export default definePageConfig({ | ||
blocks: [ | ||
block.title('Input Mask'), | ||
block.paragraph('Masks are used to format the input value. Instead of having built-in masks we provide a composable, that you can use with any input.'), | ||
block.paragraph('Vuestic UI comes with a few predefined masks. You need to manually import them and use with `useInputMask` composable.'), | ||
block.paragraph('`useInputMask` composable is designed to work with Regex based masks. It is a flexible solution that allows you to create any mask you need.'), | ||
|
||
block.subtitle('Examples'), | ||
|
||
block.example('DefaultRegex', { | ||
title: 'Regex mask', | ||
description: 'When creating a mask we use regex syntax, that allows you to deeply customize the mask.', | ||
}), | ||
|
||
block.collapse('Regex basic syntax', [ | ||
block.paragraph('Here is a list of regex tokens that you can use to create a mask:'), | ||
|
||
block.list([ | ||
'`\\d` - any digit', | ||
'`\\w` - any word character', | ||
'`.` - any character', | ||
'`[a-z]` - any character from a to z. Notice, can be also `[a-f]` - any character from a to f', | ||
'`[0-9]` - any digit', | ||
]), | ||
|
||
block.paragraph('Mask support quantifiers syntax, allowing you to specify how many times the character should appear. Here are some examples:'), | ||
|
||
block.list([ | ||
'`\\d?` - any digit or nothing', | ||
'`\\d*` - any number of digits', | ||
'`\\d+` - at least one digit', | ||
'`\\d{3}` - exactly 3 digits', | ||
'`\\d{3,}` - at least 3 digits', | ||
'`\\d{3,5}` - from 3 to 5 digits', | ||
]), | ||
|
||
block.paragraph('Obviously, you can replace `\\d` with any token. You can also use groups to group characters, for example `(\\d - \\d)?`'), | ||
block.alert('Notice that maximum repetition is 10.', 'warning'), | ||
|
||
block.paragraph('In case you need to use brackets in the mask, you need to escape them: `\\(\\d{3}\\)`'), | ||
|
||
block.paragraph('You can also use `|` to separate different options: `\\d{3}|\\w{3}`'), | ||
]), | ||
|
||
block.example('CreditCard', { | ||
title: 'Credit card', | ||
description: 'You can easily define credit card mask with regex', | ||
}), | ||
|
||
block.example('Date', { | ||
title: 'Date mask', | ||
description: 'Date mask is a predefined mask that allows you to format the date input.', | ||
}), | ||
|
||
block.example('Numeral', { | ||
title: 'Numeral mask', | ||
description: 'Numeral mask is a predefined mask that allows you to format the number input. You can decide if decimal is allowed and how many decimal places are allowed.', | ||
}), | ||
|
||
block.example('Phone', { | ||
title: 'Phone mask', | ||
description: 'There is no predefined phone mask. You can create your own mask using regex syntax. This is an example for Ukrainian phone number in internationl', | ||
}), | ||
|
||
block.paragraph('You can also create regex masks for any other phone format and use format functions based on user input. You can also write format function in plain JS and we will handle the rest for you.'), | ||
|
||
block.example('PhoneExtended') | ||
] | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { MaskToken } from './mask' | ||
|
||
export enum CursorPosition { | ||
BeforeChar = -1, | ||
Any = 0, | ||
AfterChar = 1 | ||
} | ||
|
||
export class Cursor<Token extends MaskToken> extends Number { | ||
constructor (public position: number, private tokens: Token[], private reversed: boolean = false) { | ||
super(position) | ||
} | ||
|
||
private move (direction: -1 | 1, amount: number, cursorPosition = CursorPosition.Any) { | ||
if (this.tokens.every((t) => t.static)) { | ||
if (direction === 1) { | ||
this.position = this.tokens.length | ||
return this.position | ||
} else { | ||
this.position = 0 | ||
return this.position | ||
} | ||
} | ||
|
||
for (let i = this.position; i <= this.tokens.length && i >= -1; i += direction) { | ||
const current = this.tokens[i] | ||
const next = this.tokens[i + direction] | ||
const prev = this.tokens[i - direction] | ||
|
||
if (amount < 0) { | ||
this.position = i | ||
return this.position | ||
} | ||
|
||
if (!current?.static) { | ||
amount-- | ||
} | ||
|
||
if (cursorPosition <= CursorPosition.Any) { | ||
if (direction === -1 && !next?.static && current?.static) { | ||
amount-- | ||
} | ||
if (direction === 1 && !prev?.static && current?.static) { | ||
amount-- | ||
} | ||
} | ||
|
||
if (cursorPosition >= CursorPosition.Any) { | ||
if (direction === 1 && !prev?.static && current === undefined) { | ||
amount-- | ||
} else if (direction === 1 && current === undefined && next?.static) { | ||
amount-- | ||
} else if (direction === 1 && current === undefined && next === undefined) { | ||
amount-- | ||
} | ||
} | ||
|
||
if (amount < 0) { | ||
this.position = i | ||
return this.position | ||
} | ||
} | ||
|
||
return this.position | ||
} | ||
|
||
moveBack (amount: number, cursorPosition = CursorPosition.Any) { | ||
return this.move(-1, amount, cursorPosition) | ||
} | ||
|
||
moveForward (amount: number, cursorPosition = CursorPosition.Any) { | ||
return this.move(1, amount, cursorPosition) | ||
} | ||
|
||
updateTokens (newTokens: Token[], fromEnd: boolean = false) { | ||
if (fromEnd) { | ||
// When reversed, we need to update position from the end | ||
this.position = this.tokens.length - this.position | ||
this.tokens = newTokens | ||
this.position = this.tokens.length - this.position | ||
} else { | ||
this.tokens = newTokens | ||
} | ||
} | ||
|
||
valueOf () { | ||
if (this.position < 0) { | ||
return 0 | ||
} | ||
|
||
if (this.position > this.tokens.length) { | ||
return this.tokens.length | ||
} | ||
|
||
return this.position | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export { useInputMask } from './useInputMask' | ||
export { createMaskFromRegex, compareWithMask } from './masks/regex' | ||
export { createNumeralMask } from './masks/numeral' | ||
export { createMaskDate } from './masks/date' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Cursor } from './cursor' | ||
|
||
export type MaskToken = { | ||
static: boolean, | ||
} | ||
|
||
export type Mask<Token extends MaskToken = MaskToken, Data = any> = { | ||
format: (text: string) => { | ||
text: string, | ||
tokens: Token[] | ||
data?: Data, | ||
}, | ||
handleCursor: (selectionStart: Cursor<Token>, selectionEnd: Cursor<Token>, oldTokens: Token[], newTokens: Token[], text: string, data?: Data) => any, | ||
unformat: (text: string, tokens: Token[]) => string, | ||
reverse: boolean | ||
} |
Oops, something went wrong.