maskarajs 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -94,6 +94,89 @@ const cpf = useMaskara('cpf', { engine: appMaskara })
94
94
 
95
95
  The hook stores field state. The engine stores mask configuration.
96
96
 
97
+ ## Vue 3 adapter
98
+
99
+ The Vue adapter is optional and lives in `maskarajs/vue`. Its default export is a Vue 3 directive ready for `v-maskara`. Use it locally in a component or register it once as a plugin.
100
+
101
+ ### Local directive
102
+
103
+ ```vue
104
+ <script setup lang="ts">
105
+ import { maskaraDirective as vMaskara } from 'maskarajs/vue'
106
+
107
+ const pattern = '###[.]###[.]###[-]##'
108
+ </script>
109
+
110
+ <template>
111
+ <input v-maskara="pattern" inputmode="numeric" />
112
+ </template>
113
+ ```
114
+
115
+ ### With `v-model` and raw value callback
116
+
117
+ ```vue
118
+ <script setup lang="ts">
119
+ import { ref } from 'vue'
120
+ import { maskaraDirective as vMaskara } from 'maskarajs/vue'
121
+
122
+ const document = ref('')
123
+ const rawDocument = ref('')
124
+ </script>
125
+
126
+ <template>
127
+ <input
128
+ v-model="document"
129
+ v-maskara="{
130
+ pattern: '###[.]###[.]###[-]##',
131
+ onValue: value => rawDocument = value
132
+ }"
133
+ inputmode="numeric"
134
+ />
135
+ </template>
136
+ ```
137
+
138
+ The directive listens during the capture phase, so Vue's `v-model` receives the masked value during the same input event.
139
+
140
+ ### Register globally
141
+
142
+ ```ts
143
+ import { createApp } from 'vue'
144
+ import { createMaskaraPlugin } from 'maskarajs/vue'
145
+ import App from './App.vue'
146
+
147
+ createApp(App)
148
+ .use(createMaskaraPlugin())
149
+ .mount('#app')
150
+ ```
151
+
152
+ Then use it anywhere:
153
+
154
+ ```vue
155
+ <input v-maskara="'#####[-]###'" />
156
+ ```
157
+
158
+ ### Use an isolated engine
159
+
160
+ ```ts
161
+ import maskara from 'maskarajs'
162
+ import { createMaskaraPlugin } from 'maskarajs/vue'
163
+
164
+ const br = maskara.create({
165
+ cpf: { pattern: '###[.]###[.]###[-]##' },
166
+ phone: { pattern: ['[(]##[)] ####[-]####', '[(]##[)] #####[-]####'] },
167
+ })
168
+
169
+ app.use(createMaskaraPlugin({ engine: br }))
170
+ ```
171
+
172
+ You can also create a directive instance manually:
173
+
174
+ ```ts
175
+ import { createMaskaraDirective } from 'maskarajs/vue'
176
+
177
+ const vMaskara = createMaskaraDirective({ engine: br })
178
+ ```
179
+
97
180
  ## Examples
98
181
 
99
182
  ```js
package/package.json CHANGED
@@ -1,48 +1,49 @@
1
1
  {
2
2
  "name": "maskarajs",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Engine de máscaras declarativo — framework-agnostic, zero dependências, ~4kb",
5
- "main": "./mask.cjs.js",
6
- "module": "./mask.mjs",
7
- "types": "./mask.d.ts",
5
+ "main": "./src/core/mask.cjs.js",
6
+ "module": "./src/core/mask.mjs",
7
+ "types": "./src/core/mask.d.ts",
8
8
  "scripts": {
9
9
  "test": "node test/mask.test.mjs"
10
10
  },
11
11
  "exports": {
12
12
  ".": {
13
- "import": "./mask.mjs",
14
- "require": "./mask.cjs.js",
15
- "types": "./mask.d.ts"
13
+ "import": "./src/core/mask.mjs",
14
+ "require": "./src/core/mask.cjs.js",
15
+ "types": "./src/core/mask.d.ts"
16
16
  },
17
17
  "./react": {
18
- "import": "./react.mjs",
19
- "require": "./react.cjs.js",
20
- "types": "./react.d.ts"
18
+ "import": "./src/adapters/react/index.mjs",
19
+ "require": "./src/adapters/react/index.cjs.js",
20
+ "types": "./src/adapters/react/index.d.ts"
21
+ },
22
+ "./vue": {
23
+ "import": "./src/adapters/vue/index.mjs",
24
+ "require": "./src/adapters/vue/index.cjs.js",
25
+ "types": "./src/adapters/vue/index.d.ts"
21
26
  },
22
27
  "./presets/br": {
23
- "import": "./presets/br.mjs",
24
- "require": "./presets/br.cjs.js",
25
- "types": "./presets/br.d.ts"
28
+ "import": "./src/presets/br.mjs",
29
+ "require": "./src/presets/br.cjs.js",
30
+ "types": "./src/presets/br.d.ts"
26
31
  }
27
32
  },
28
33
  "files": [
29
34
  "src",
30
- "mask.js",
31
- "mask.mjs",
32
- "mask.cjs.js",
33
- "mask.d.ts",
34
- "react.mjs",
35
- "react.cjs.js",
36
- "react.d.ts",
37
- "presets",
38
35
  "README.md"
39
36
  ],
40
37
  "peerDependencies": {
41
- "react": ">=18"
38
+ "react": ">=18",
39
+ "vue": ">=3"
42
40
  },
43
41
  "peerDependenciesMeta": {
44
42
  "react": {
45
43
  "optional": true
44
+ },
45
+ "vue": {
46
+ "optional": true
46
47
  }
47
48
  },
48
49
  "sideEffects": false,
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const React = require('react')
4
- const maskara = require('./mask.cjs.js')
4
+ const maskara = require('../../core/mask.cjs.js')
5
5
 
6
6
  const MaskaraEngineContext = React.createContext(maskara)
7
7
 
@@ -1,5 +1,5 @@
1
1
  import type { ChangeEvent, InputHTMLAttributes, ReactNode } from 'react'
2
- import type { MaskaraInstance, MaskaraPattern } from './mask'
2
+ import type { MaskaraInstance, MaskaraPattern } from '../../core/mask'
3
3
 
4
4
  export type MaskaraInputChange = ChangeEvent<HTMLInputElement> | string | number | null | undefined
5
5
  export type MaskInputChange = MaskaraInputChange
@@ -7,7 +7,7 @@ export type MaskInputChange = MaskaraInputChange
7
7
  export interface UseMaskaraOptions<T = string> {
8
8
  value?: string | null | undefined
9
9
  defaultValue?: string | null | undefined
10
- engine?: MaskaraInstance | typeof import('./mask').default
10
+ engine?: MaskaraInstance | typeof import('../../core/mask').default
11
11
  onValue?: (value: T) => void
12
12
  onMaskara?: (masked: string) => void
13
13
  onMasked?: (masked: string) => void
@@ -33,7 +33,7 @@ export interface UseMaskaraResult<T = string> {
33
33
  export type UseMaskResult<T = string> = UseMaskaraResult<T>
34
34
 
35
35
  export interface MaskaraProviderProps {
36
- engine?: MaskaraInstance | typeof import('./mask').default
36
+ engine?: MaskaraInstance | typeof import('../../core/mask').default
37
37
  children?: ReactNode
38
38
  }
39
39
  export type MaskProviderProps = MaskaraProviderProps
@@ -41,8 +41,8 @@ export type MaskProviderProps = MaskaraProviderProps
41
41
  export declare function MaskaraProvider(props: MaskaraProviderProps): ReactNode
42
42
  export declare function MaskProvider(props: MaskProviderProps): ReactNode
43
43
 
44
- export declare function useMaskaraEngine(): MaskaraInstance | typeof import('./mask').default
45
- export declare function useMaskEngine(): MaskaraInstance | typeof import('./mask').default
44
+ export declare function useMaskaraEngine(): MaskaraInstance | typeof import('../../core/mask').default
45
+ export declare function useMaskEngine(): MaskaraInstance | typeof import('../../core/mask').default
46
46
 
47
47
  export declare function useMaskara<T = string>(
48
48
  pattern: MaskaraPattern,
@@ -1,5 +1,5 @@
1
1
  import { createContext, createElement, useCallback, useContext, useMemo, useState } from 'react'
2
- import maskara from '../../mask.mjs'
2
+ import maskara from '../../core/mask.mjs'
3
3
 
4
4
  const MaskaraEngineContext = createContext(maskara)
5
5
 
@@ -0,0 +1,151 @@
1
+ const maskara = require('../../core/mask.cjs.js')
2
+
3
+ const STATE = Symbol('maskaraDirectiveState')
4
+
5
+ function frame(callback) {
6
+ if (typeof requestAnimationFrame === 'function') {
7
+ requestAnimationFrame(callback)
8
+ return
9
+ }
10
+
11
+ callback()
12
+ }
13
+
14
+ function normalizeBinding(value, defaults = {}) {
15
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
16
+ return {
17
+ engine: value.engine ?? defaults.engine ?? maskara,
18
+ pattern: value.pattern ?? value.maskara ?? value.mask,
19
+ onValue: value.onValue,
20
+ onMaskara: value.onMaskara,
21
+ onMasked: value.onMasked,
22
+ }
23
+ }
24
+
25
+ return {
26
+ engine: defaults.engine ?? maskara,
27
+ pattern: value,
28
+ }
29
+ }
30
+
31
+ function applyMask(el, config, notify = false) {
32
+ if (!config.pattern) return
33
+
34
+ const current = el.value ?? ''
35
+ const masked = config.engine(config.pattern, current)
36
+ el.value = masked
37
+
38
+ if (!notify) return
39
+
40
+ config.onMaskara?.(masked)
41
+ config.onMasked?.(masked)
42
+ config.onValue?.(config.engine.raw(config.pattern, masked))
43
+ }
44
+
45
+ function bind(el, binding, defaults = {}) {
46
+ el[STATE]?.cleanup?.()
47
+
48
+ const config = normalizeBinding(binding.value, defaults)
49
+ if (!config.pattern) {
50
+ el[STATE] = { cleanup: null, bindingValue: binding.value }
51
+ return
52
+ }
53
+
54
+ function onKeydown(event) {
55
+ if (event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return
56
+ const rawLength = config.engine.rawLength(config.pattern, el.value)
57
+ const maxLength = config.engine.patternLength(config.pattern)
58
+ if (rawLength >= maxLength) event.preventDefault()
59
+ }
60
+
61
+ function onInput(event) {
62
+ const target = event.target
63
+ const raw = target.value ?? ''
64
+ const cursor = target.selectionStart ?? raw.length
65
+ const masked = config.engine(config.pattern, raw)
66
+ const diff = masked.length - raw.length
67
+
68
+ target.value = masked
69
+
70
+ frame(() => {
71
+ const position = Math.max(0, cursor + diff)
72
+ target.setSelectionRange?.(position, position)
73
+ })
74
+
75
+ config.onMaskara?.(masked)
76
+ config.onMasked?.(masked)
77
+ config.onValue?.(config.engine.raw(config.pattern, masked))
78
+ }
79
+
80
+ el.addEventListener('keydown', onKeydown)
81
+ el.addEventListener('input', onInput, true)
82
+ applyMask(el, config)
83
+
84
+ el[STATE] = {
85
+ bindingValue: binding.value,
86
+ cleanup() {
87
+ el.removeEventListener('keydown', onKeydown)
88
+ el.removeEventListener('input', onInput, true)
89
+ },
90
+ }
91
+ }
92
+
93
+ function sameBindingValue(previous, next) {
94
+ if (previous === next) return true
95
+ if (!previous || !next) return false
96
+ if (typeof previous !== 'object' || typeof next !== 'object') return false
97
+
98
+ return (
99
+ previous.pattern === next.pattern &&
100
+ previous.maskara === next.maskara &&
101
+ previous.mask === next.mask &&
102
+ previous.engine === next.engine &&
103
+ previous.onValue === next.onValue &&
104
+ previous.onMaskara === next.onMaskara &&
105
+ previous.onMasked === next.onMasked
106
+ )
107
+ }
108
+
109
+ function createMaskaraDirective(defaults = {}) {
110
+ return {
111
+ mounted(el, binding) {
112
+ bind(el, binding, defaults)
113
+ },
114
+ updated(el, binding) {
115
+ if (!sameBindingValue(el[STATE]?.bindingValue, binding.value)) {
116
+ bind(el, binding, defaults)
117
+ return
118
+ }
119
+
120
+ const config = normalizeBinding(binding.value, defaults)
121
+ applyMask(el, config)
122
+ },
123
+ beforeUnmount(el) {
124
+ el[STATE]?.cleanup?.()
125
+ delete el[STATE]
126
+ },
127
+ }
128
+ }
129
+
130
+ function createMaskaraPlugin(options = {}) {
131
+ const name = options.name ?? 'maskara'
132
+ const directive = createMaskaraDirective(options)
133
+
134
+ return {
135
+ install(app) {
136
+ app.directive(name, directive)
137
+ },
138
+ }
139
+ }
140
+
141
+ const maskaraDirective = createMaskaraDirective()
142
+ const vMaskara = maskaraDirective
143
+ const useMaskaraDirective = createMaskaraDirective
144
+
145
+ module.exports = maskaraDirective
146
+ module.exports.default = maskaraDirective
147
+ module.exports.maskaraDirective = maskaraDirective
148
+ module.exports.vMaskara = vMaskara
149
+ module.exports.createMaskaraDirective = createMaskaraDirective
150
+ module.exports.createMaskaraPlugin = createMaskaraPlugin
151
+ module.exports.useMaskaraDirective = useMaskaraDirective
@@ -0,0 +1,46 @@
1
+ import type { Directive, ObjectDirective, Plugin } from 'vue'
2
+ import type { MaskaraInstance, MaskaraOnOptions, MaskaraPattern } from '../../core/mask'
3
+
4
+ export type MaskaraDirectivePattern = MaskaraPattern | keyof Record<string, unknown>
5
+
6
+ export interface MaskaraDirectiveOptions<T = string> extends MaskaraOnOptions<T> {
7
+ pattern?: MaskaraPattern | string
8
+ maskara?: MaskaraPattern | string
9
+ mask?: MaskaraPattern | string
10
+ engine?: MaskaraInstance | typeof import('../../core/mask').default
11
+ }
12
+
13
+ export type MaskaraDirectiveValue<T = string> =
14
+ | MaskaraPattern
15
+ | string
16
+ | MaskaraDirectiveOptions<T>
17
+
18
+ export type MaskaraDirective<T = string> = ObjectDirective<
19
+ HTMLInputElement,
20
+ MaskaraDirectiveValue<T>
21
+ >
22
+
23
+ export interface CreateMaskaraDirectiveOptions {
24
+ engine?: MaskaraInstance | typeof import('../../core/mask').default
25
+ }
26
+
27
+ export interface CreateMaskaraPluginOptions extends CreateMaskaraDirectiveOptions {
28
+ name?: string
29
+ }
30
+
31
+ export declare function createMaskaraDirective<T = string>(
32
+ options?: CreateMaskaraDirectiveOptions
33
+ ): MaskaraDirective<T>
34
+
35
+ export declare function useMaskaraDirective<T = string>(
36
+ options?: CreateMaskaraDirectiveOptions
37
+ ): MaskaraDirective<T>
38
+
39
+ export declare function createMaskaraPlugin(
40
+ options?: CreateMaskaraPluginOptions
41
+ ): Plugin
42
+
43
+ export declare const maskaraDirective: MaskaraDirective
44
+ export declare const vMaskara: Directive<HTMLInputElement, MaskaraDirectiveValue>
45
+
46
+ export default maskaraDirective
@@ -0,0 +1,147 @@
1
+ import maskara from '../../core/mask.mjs'
2
+
3
+ const STATE = Symbol('maskaraDirectiveState')
4
+
5
+ function frame(callback) {
6
+ if (typeof requestAnimationFrame === 'function') {
7
+ requestAnimationFrame(callback)
8
+ return
9
+ }
10
+
11
+ callback()
12
+ }
13
+
14
+ function normalizeBinding(value, defaults = {}) {
15
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
16
+ return {
17
+ engine: value.engine ?? defaults.engine ?? maskara,
18
+ pattern: value.pattern ?? value.maskara ?? value.mask,
19
+ onValue: value.onValue,
20
+ onMaskara: value.onMaskara,
21
+ onMasked: value.onMasked,
22
+ }
23
+ }
24
+
25
+ return {
26
+ engine: defaults.engine ?? maskara,
27
+ pattern: value,
28
+ }
29
+ }
30
+
31
+ function applyMask(el, config, notify = false) {
32
+ if (!config.pattern) return
33
+
34
+ const current = el.value ?? ''
35
+ const masked = config.engine(config.pattern, current)
36
+ el.value = masked
37
+
38
+ if (!notify) return
39
+
40
+ config.onMaskara?.(masked)
41
+ config.onMasked?.(masked)
42
+ config.onValue?.(config.engine.raw(config.pattern, masked))
43
+ }
44
+
45
+ function bind(el, binding, defaults = {}) {
46
+ el[STATE]?.cleanup?.()
47
+
48
+ const config = normalizeBinding(binding.value, defaults)
49
+ if (!config.pattern) {
50
+ el[STATE] = { cleanup: null, bindingValue: binding.value }
51
+ return
52
+ }
53
+
54
+ function onKeydown(event) {
55
+ if (event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return
56
+ const rawLength = config.engine.rawLength(config.pattern, el.value)
57
+ const maxLength = config.engine.patternLength(config.pattern)
58
+ if (rawLength >= maxLength) event.preventDefault()
59
+ }
60
+
61
+ function onInput(event) {
62
+ const target = event.target
63
+ const raw = target.value ?? ''
64
+ const cursor = target.selectionStart ?? raw.length
65
+ const masked = config.engine(config.pattern, raw)
66
+ const diff = masked.length - raw.length
67
+
68
+ target.value = masked
69
+
70
+ frame(() => {
71
+ const position = Math.max(0, cursor + diff)
72
+ target.setSelectionRange?.(position, position)
73
+ })
74
+
75
+ config.onMaskara?.(masked)
76
+ config.onMasked?.(masked)
77
+ config.onValue?.(config.engine.raw(config.pattern, masked))
78
+ }
79
+
80
+ el.addEventListener('keydown', onKeydown)
81
+ el.addEventListener('input', onInput, true)
82
+ applyMask(el, config)
83
+
84
+ el[STATE] = {
85
+ bindingValue: binding.value,
86
+ cleanup() {
87
+ el.removeEventListener('keydown', onKeydown)
88
+ el.removeEventListener('input', onInput, true)
89
+ },
90
+ }
91
+ }
92
+
93
+ function sameBindingValue(previous, next) {
94
+ if (previous === next) return true
95
+ if (!previous || !next) return false
96
+ if (typeof previous !== 'object' || typeof next !== 'object') return false
97
+
98
+ return (
99
+ previous.pattern === next.pattern &&
100
+ previous.maskara === next.maskara &&
101
+ previous.mask === next.mask &&
102
+ previous.engine === next.engine &&
103
+ previous.onValue === next.onValue &&
104
+ previous.onMaskara === next.onMaskara &&
105
+ previous.onMasked === next.onMasked
106
+ )
107
+ }
108
+
109
+ export function createMaskaraDirective(defaults = {}) {
110
+ return {
111
+ mounted(el, binding) {
112
+ bind(el, binding, defaults)
113
+ },
114
+ updated(el, binding) {
115
+ if (!sameBindingValue(el[STATE]?.bindingValue, binding.value)) {
116
+ bind(el, binding, defaults)
117
+ return
118
+ }
119
+
120
+ const config = normalizeBinding(binding.value, defaults)
121
+ applyMask(el, config)
122
+ },
123
+ beforeUnmount(el) {
124
+ el[STATE]?.cleanup?.()
125
+ delete el[STATE]
126
+ },
127
+ }
128
+ }
129
+
130
+ export function createMaskaraPlugin(options = {}) {
131
+ const name = options.name ?? 'maskara'
132
+ const directive = createMaskaraDirective(options)
133
+
134
+ return {
135
+ install(app) {
136
+ app.directive(name, directive)
137
+ },
138
+ }
139
+ }
140
+
141
+ export const maskaraDirective = createMaskaraDirective()
142
+ export const vMaskara = maskaraDirective
143
+
144
+ const useMaskaraDirective = createMaskaraDirective
145
+
146
+ export { useMaskaraDirective }
147
+ export default maskaraDirective
@@ -994,7 +994,9 @@ mask.create = function (presets = {}) {
994
994
 
995
995
  // ─── Export ────────────────────────────────────────────────────────────────
996
996
 
997
- // export { mask }
997
+ const maskara = mask
998
+
999
+ // export { mask, maskara }
998
1000
  // export default mask
999
1001
 
1000
1002
  module.exports = mask
@@ -322,7 +322,7 @@ export declare namespace mask {
322
322
  * onValue: date => ... // date: Date | null ✓ (inferido)
323
323
  * })
324
324
  */
325
- function create<R extends Record<string, unknown> = Record<string, string>>(
325
+ function create<R extends Record<string, unknown> = {}>(
326
326
  presets?: { [K in keyof R]: MaskDefinition<R[K]> }
327
327
  ): MaskInstance<R>
328
328
  }
@@ -1,4 +1,4 @@
1
- import type { MaskaraDefinition } from '../mask'
1
+ import type { MaskaraDefinition } from '../core/mask'
2
2
 
3
3
  export interface BrazilPresetRegistry {
4
4
  cpf: string
package/mask.d.ts DELETED
@@ -1,333 +0,0 @@
1
- /**
2
- * mask.d.ts
3
- *
4
- * Tipagens com parâmetro de registry para autocomplete de nomes registrados.
5
- *
6
- * Uso básico (sem generics — funciona, sem autocomplete de nomes):
7
- * import maskara from './mask.js'
8
- * maskara('cpf', value)
9
- *
10
- * Uso tipado (com autocomplete de nomes):
11
- * const m = maskara.create<{ cpf: string; date: Date | null; money: number }>({
12
- * cpf: { pattern: '###[.]###[.]###[-]##' },
13
- * date: { pattern: '##[/]##[/]####', transform: ... },
14
- * money: { pattern: '########[,]##', transform: ... },
15
- * })
16
- * m('cpf', value) // ← autocomplete sugere 'cpf' | 'date' | 'money'
17
- * m.raw('date', value) // ← retorno inferido: Date | null
18
- * m.raw('money', value) // ← retorno inferido: number
19
- * m.raw('cpf', value) // ← retorno inferido: string
20
- */
21
-
22
- // ─── Primitivos ───────────────────────────────────────────────────────────
23
-
24
- /** Regra condicional para escolher um pattern a partir do raw digitado */
25
- export interface MaskPatternRule {
26
- pattern: string | string[]
27
- when?: (raw: string, value: string) => boolean
28
- }
29
- export type MaskaraPatternRule = MaskPatternRule
30
-
31
- /** Mapa de patterns usado por máscaras nomeadas condicionais */
32
- export type MaskPatternMap = Record<string, string | string[]>
33
- export type MaskaraPatternMap = MaskPatternMap
34
-
35
- /** Função que escolhe uma chave de patterns a partir do valor digitado */
36
- export type MaskSelect<K extends string = string> = (raw: string, value: string) => K
37
- export type MaskaraSelect<K extends string = string> = MaskSelect<K>
38
-
39
- /** String de padrão declarativo, array dinâmico ou array de regras condicionais */
40
- export type MaskPattern = string | string[] | MaskPatternRule[]
41
- export type MaskaraPattern = MaskPattern
42
-
43
- /** Função de transformação — recebe (raw, masked, complete) e retorna T */
44
- export type MaskTransform<T> = (raw: string, masked: string, complete: boolean) => T
45
- export type MaskaraTransform<T> = MaskTransform<T>
46
-
47
- /** Validação incremental — retorna false para recusar o próximo caractere */
48
- export type MaskValidate = (raw: string, masked: string, complete: boolean) => boolean
49
- export type MaskaraValidate = MaskValidate
50
-
51
- /** Predicado usado por um slot customizado */
52
- export type MaskSlotTest = (ch: string) => boolean
53
- export type MaskaraSlotTest = MaskSlotTest
54
-
55
- /** Definição completa de um slot customizado */
56
- export interface MaskSlotDefinition {
57
- test: MaskSlotTest
58
- hint?: string
59
- }
60
- export type MaskaraSlotDefinition = MaskSlotDefinition
61
-
62
- /** Formas aceitas para registrar um slot customizado */
63
- export type MaskSlotInput = MaskSlotTest | RegExp | MaskSlotDefinition
64
- export type MaskaraSlotInput = MaskSlotInput
65
-
66
- /** Definição de uma máscara nomeada com pattern único ou array dinâmico */
67
- export interface MaskPatternDefinition<T = string> {
68
- pattern: MaskPattern
69
- transform?: MaskTransform<T>
70
- validate?: MaskValidate
71
- }
72
- export type MaskaraPatternDefinition<T = string> = MaskPatternDefinition<T>
73
-
74
- /** Definição de uma máscara nomeada que seleciona um pattern por raw/value */
75
- export interface MaskConditionalDefinition<T = string, K extends string = string> {
76
- patterns: Record<K, MaskPattern>
77
- select: MaskSelect<K>
78
- transform?: MaskTransform<T>
79
- validate?: MaskValidate
80
- }
81
- export type MaskaraConditionalDefinition<T = string, K extends string = string> = MaskConditionalDefinition<T, K>
82
-
83
- /** Definição de uma máscara nomeada */
84
- export type MaskDefinition<T = string> = MaskPatternDefinition<T> | MaskConditionalDefinition<T>
85
- export type MaskaraDefinition<T = string> = MaskDefinition<T>
86
-
87
- /** Opções de mask.on */
88
- export interface MaskOnOptions<T> {
89
- /** Chamado a cada keystroke com o valor limpo / resultado do transform */
90
- onValue?: (value: T) => void
91
- /** Chamado a cada keystroke com o valor mascarado (display). Nome preferido. */
92
- onMaskara?: (masked: string) => void
93
- /** Chamado a cada keystroke com o valor mascarado (display) */
94
- onMasked?: (masked: string) => void
95
- }
96
- export type MaskaraOnOptions<T> = MaskOnOptions<T>
97
-
98
- // ─── Registry map ─────────────────────────────────────────────────────────
99
- //
100
- // R = Record dos nomes registrados com seus tipos de retorno do transform.
101
- //
102
- // Exemplo:
103
- // type MyRegistry = {
104
- // cpf: string // sem transform → string
105
- // date: Date | null // transform retorna Date | null
106
- // money: number // transform retorna number
107
- // }
108
- //
109
- // Usado para inferir o tipo de retorno de raw() a partir do nome.
110
-
111
- /** Extrai o tipo de retorno de raw() para um nome de máscara */
112
- type RawReturn<R extends Record<string, unknown>, K extends keyof R | MaskPattern> =
113
- K extends keyof R ? R[K] : string
114
-
115
- /** Union de nomes registrados + MaskPattern (para aceitar padrão literal também) */
116
- type PatternOrName<R extends Record<string, unknown>> = keyof R | MaskPattern
117
-
118
- // ─── MaskInstance ─────────────────────────────────────────────────────────
119
-
120
- /**
121
- * Instância tipada retornada por mask.create<R>(presets).
122
- *
123
- * R = mapa de nomes para tipos de retorno do transform.
124
- * Autocomplete sugere os nomes registrados em todos os métodos.
125
- */
126
- export interface MaskInstance<R extends Record<string, unknown> = Record<string, string>> {
127
-
128
- /**
129
- * Aplica máscara — retorna string formatada para exibição.
130
- * @param pattern nome registrado (autocomplete) ou padrão literal
131
- */
132
- <K extends PatternOrName<R>>(pattern: K, value: string | null | undefined): string
133
-
134
- /**
135
- * Retorna o raw value passado pelo transform.
136
- * O tipo de retorno é inferido automaticamente pelo nome registrado.
137
- *
138
- * @example
139
- * m.raw('date', v) // → Date | null (inferido do registry)
140
- * m.raw('money', v) // → number (inferido do registry)
141
- * m.raw('cpf', v) // → string (inferido do registry)
142
- */
143
- raw<K extends PatternOrName<R>>(
144
- pattern: K,
145
- value: string | null | undefined
146
- ): RawReturn<R, K>
147
-
148
- /**
149
- * Verifica se o valor preenche completamente o padrão.
150
- */
151
- is<K extends PatternOrName<R>>(pattern: K, value: string | null | undefined): boolean
152
-
153
- /**
154
- * Retorna o placeholder legível do padrão.
155
- * @example m.hint('cpf') // → '000.000.000-00'
156
- */
157
- hint<K extends PatternOrName<R>>(pattern: K): string
158
-
159
- /**
160
- * Formata um valor vindo da API para exibição. Alias semântico de apply.
161
- * @example m.format('cpf', user.cpf) // → '123.456.789-09'
162
- */
163
- format<K extends PatternOrName<R>>(pattern: K, value: string | null | undefined): string
164
-
165
- /**
166
- * Comprimento do raw atual — chars de input preenchidos (sem literais).
167
- * Nunca passa pelo transform. Útil para progress bars.
168
- * @example
169
- * const pct = m.rawLength('cpf', v) / m.patternLength('cpf') * 100
170
- */
171
- rawLength<K extends PatternOrName<R>>(pattern: K, value: string | null | undefined): number
172
-
173
- /**
174
- * Comprimento total do valor mascarado completo.
175
- * Conta slots como 1 caractere e literais pelo tamanho real.
176
- * Para arrays, retorna o maior valor mascarado possível.
177
- */
178
- patternLength<K extends PatternOrName<R>>(pattern: K): number
179
-
180
- /**
181
- * Registra uma nova máscara nesta instância.
182
- * Não afeta outras instâncias nem o registry global.
183
- */
184
- define<N extends string, T = string>(name: N, definition: MaskDefinition<T>): void
185
-
186
- /**
187
- * Remove uma máscara desta instância.
188
- */
189
- undefine<K extends keyof R>(name: K): void
190
-
191
- /**
192
- * Lista os nomes registrados nesta instância.
193
- */
194
- names(): Array<keyof R & string>
195
-
196
- /**
197
- * Cria ou sobrescreve um símbolo de slot apenas nesta instância.
198
- * Use [N] quando precisar tratar um símbolo registrado como literal.
199
- */
200
- defineSlot(symbol: string, definition: MaskSlotInput): void
201
-
202
- /**
203
- * Remove um slot desta instância.
204
- * Slots padrão (#, @, *) voltam ao comportamento original.
205
- */
206
- undefineSlot(symbol: string): void
207
-
208
- /** Lista os símbolos de slot disponíveis nesta instância */
209
- slots(): string[]
210
-
211
- /**
212
- * Vincula máscara a um input DOM. Retorna cleanup().
213
- * Framework-agnostic — funciona em React, Vue, Svelte, Vanilla.
214
- *
215
- * @example
216
- * // React
217
- * useEffect(() => m.on(ref.current, 'date', { onValue: setDate }), [])
218
- *
219
- * // Vue
220
- * onMounted(() => m.on(inputRef.value, 'phone', { onValue: v => emit('update:modelValue', v) }))
221
- *
222
- * // Svelte action
223
- * const maskAction = (node, name) => ({ destroy: m.on(node, name) })
224
- */
225
- on<K extends PatternOrName<R>>(
226
- input: HTMLInputElement,
227
- pattern: K,
228
- options?: MaskOnOptions<RawReturn<R, K>>
229
- ): () => void
230
-
231
- /** Cria uma sub-instância com registry próprio */
232
- create<S extends Record<string, unknown>>(
233
- presets?: { [K in keyof S]: MaskDefinition<S[K]> }
234
- ): MaskInstance<S>
235
- }
236
- export type MaskaraInstance<R extends Record<string, unknown> = Record<string, string>> = MaskInstance<R>
237
-
238
- // ─── Função principal (registry global, sem generics de nome) ─────────────
239
-
240
- /**
241
- * Aplica máscara a um valor.
242
- *
243
- * @example
244
- * mask('###[.]###[.]###[-]##', '12345678909') // → '123.456.789-09'
245
- * mask(['[(]##[)] ####[-]####', '[(]##[)] #####[-]####'], '11987654321')
246
- */
247
- export declare function mask(pattern: MaskPattern, value: string | null | undefined): string
248
-
249
- export declare namespace mask {
250
-
251
- /** Retorna o raw value / resultado do transform */
252
- function raw<T = string>(pattern: MaskPattern, value: string | null | undefined): T
253
-
254
- /** Verifica se o valor preenche completamente o padrão */
255
- function is(pattern: MaskPattern, value: string | null | undefined): boolean
256
-
257
- /** Retorna o placeholder legível do padrão */
258
- function hint(pattern: MaskPattern): string
259
-
260
- /** Alias semântico de mask() para formatar valores da API */
261
- function format(pattern: MaskPattern, value: string | null | undefined): string
262
-
263
- /** Chars de input preenchidos — sem literais, sem transform */
264
- function rawLength(pattern: MaskPattern, value: string | null | undefined): number
265
-
266
- /** Comprimento total do valor mascarado completo */
267
- function patternLength(pattern: MaskPattern): number
268
-
269
- /** Registra máscara nomeada no registry global */
270
- function define<T = string>(name: string, definition: MaskDefinition<T>): void
271
-
272
- /** Remove máscara do registry global */
273
- function undefine(name: string): void
274
-
275
- /** Lista nomes do registry global */
276
- function names(): string[]
277
-
278
- /**
279
- * Cria ou sobrescreve um símbolo de slot no engine global.
280
- * Use [N] quando precisar tratar um símbolo registrado como literal.
281
- */
282
- function defineSlot(symbol: string, definition: MaskSlotInput): void
283
-
284
- /**
285
- * Remove um slot global.
286
- * Slots padrão (#, @, *) voltam ao comportamento original.
287
- */
288
- function undefineSlot(symbol: string): void
289
-
290
- /** Lista os símbolos de slot disponíveis no engine global */
291
- function slots(): string[]
292
-
293
- /** Vincula máscara a input DOM — retorna cleanup() */
294
- function on<T = string>(
295
- input: HTMLInputElement,
296
- pattern: MaskPattern,
297
- options?: MaskOnOptions<T>
298
- ): () => void
299
-
300
- /**
301
- * Cria uma instância isolada com registry próprio e tipos inferidos.
302
- *
303
- * O generic R mapeia cada nome ao tipo de retorno do seu transform —
304
- * isso habilita autocomplete de nomes e inferência de tipo em raw().
305
- *
306
- * @example
307
- * const m = mask.create<{
308
- * cpf: string
309
- * date: Date | null
310
- * money: number
311
- * }>({
312
- * cpf: { pattern: '###[.]###[.]###[-]##' },
313
- * date: { pattern: '##[/]##[/]####', transform: (r,_,c) => c ? new Date(...) : null },
314
- * money: { pattern: '########[,]##', transform: r => parseInt(r||'0',10)/100 },
315
- * })
316
- *
317
- * m('cpf', v) // autocomplete: 'cpf' | 'date' | 'money'
318
- * m.raw('date', v) // → Date | null ✓
319
- * m.raw('money', v) // → number ✓
320
- * m.rawLength('cpf', v) // → number ✓
321
- * m.on(el, 'date', {
322
- * onValue: date => ... // date: Date | null ✓ (inferido)
323
- * })
324
- */
325
- function create<R extends Record<string, unknown> = Record<string, string>>(
326
- presets?: { [K in keyof R]: MaskDefinition<R[K]> }
327
- ): MaskInstance<R>
328
- }
329
-
330
- /** Preferred alias for the main engine. `mask` remains available for compatibility. */
331
- export declare const maskara: typeof mask
332
-
333
- export default mask
package/mask.js DELETED
@@ -1,2 +0,0 @@
1
- export { mask, maskara } from './src/core/mask.mjs'
2
- export { default } from './src/core/mask.mjs'
package/mask.mjs DELETED
@@ -1,2 +0,0 @@
1
- export { mask, maskara } from './src/core/mask.mjs'
2
- export { default } from './src/core/mask.mjs'
package/react.mjs DELETED
@@ -1,2 +0,0 @@
1
- export { MaskaraProvider, MaskProvider, useMaskara, useMask, useMaskaraEngine, useMaskEngine } from './src/react/useMask.mjs'
2
- export { default } from './src/react/useMask.mjs'
File without changes
File without changes