Fixed #6503 - New KeyFilter directive

pull/6275/head^2
tugcekucukoglu 2024-10-01 12:35:06 +03:00
parent 21ae03bfce
commit b88a144979
7 changed files with 319 additions and 0 deletions

View File

@ -0,0 +1,8 @@
import BaseDirective from '@primevue/core/basedirective';
import KeyFilterStyle from 'primevue/keyfilter/style';
const BaseKeyFilter = BaseDirective.extend({
style: KeyFilterStyle
});
export default BaseKeyFilter;

View File

@ -0,0 +1,153 @@
/**
*
* KeyFilter is a built-in feature of InputText to restrict user input based on a regular expression.
*
* [Live Demo](https://primevue.org/keyfilter)
*
* @module keyfilter
*
*/
import type { DesignToken, PassThrough } from '@primevue/core';
import type { DirectiveHooks } from '@primevue/core/basedirective';
import type { PassThroughOptions } from 'primevue/passthrough';
import { DirectiveBinding, ObjectDirective } from 'vue';
export declare type KeyFilterDirectivePassThroughOptionType = KeyFilterDirectivePassThroughAttributes | null | undefined;
/**
* Defines options of KeyFilter.
*/
export interface KeyFilterOptions {
/**
* Sets the pattern for key filtering.
* @defaultValue null
*/
pattern?: RegExp | undefined;
/**
* When enabled, instead of blocking keys, input is validated internally to test against the regular expression.
* @defaultValue false
*/
validateOnly?: boolean;
/**
* It generates scoped CSS variables using design tokens for the component.
*/
dt?: DesignToken<any>;
/**
* Used to pass attributes to DOM elements inside the component.
* @type {KeyFilterDirectivePassThroughOptions}
*/
pt?: PassThrough<KeyFilterDirectivePassThroughOptions>;
/**
* Used to configure passthrough(pt) options of the component.
* @type {PassThroughOptions}
*/
ptOptions?: PassThroughOptions;
/**
* When enabled, it removes component related styles in the core.
* @defaultValue false
*/
unstyled?: boolean;
}
/**
* Custom passthrough(pt) options.
* @see {@link KeyFilterOptions.pt}
*/
export interface KeyFilterDirectivePassThroughOptions {
/**
* Used to pass attributes to the root's DOM element.
*/
root?: KeyFilterDirectivePassThroughOptionType;
/**
* Used to manage all lifecycle hooks.
* @see {@link BaseDirective.DirectiveHooks}
*/
hooks?: DirectiveHooks;
}
/**
* Custom passthrough attributes for each DOM elements
*/
export interface KeyFilterDirectivePassThroughAttributes {
[key: string]: any;
}
/**
* Defines modifiers of KeyFilter directive.
*/
export interface KeyFilterModifiers {
/**
* Positive integer pattern for KeyFilter directive.
* @defaultValue false
*/
pint?: RegExp | undefined;
/**
* Integer pattern for KeyFilter directive.
* @defaultValue false
*/
int?: RegExp | undefined;
/**
* Positive number pattern for KeyFilter directive.
* @defaultValue false
*/
pnum?: RegExp | undefined;
/**
* Money pattern for KeyFilter directive.
* @defaultValue false
*/
money?: RegExp | undefined;
/**
* Number pattern for KeyFilter directive.
* @defaultValue false
*/
num?: RegExp | undefined;
/**
* Hexadecimal pattern for KeyFilter directive.
* @defaultValue false
*/
hex?: RegExp | undefined;
/**
* Email pattern for KeyFilter directive.
* @defaultValue false
*/
email?: RegExp | undefined;
/**
* Alphabetic pattern for KeyFilter directive.
* @defaultValue false
*/
alpha?: RegExp | undefined;
/**
* Alphanumeric pattern for KeyFilter directive.
* @defaultValue false
*/
alphanum?: RegExp | undefined;
}
/**
* Binding of KeyFilter directive.
*/
export interface KeyFilterDirectiveBinding extends Omit<DirectiveBinding, 'modifiers' | 'value'> {
/**
* Value of the KeyFilter.
*/
value?: string | KeyFilterOptions | undefined;
/**
* Modifiers of the KeyFilter.
* @type {KeyFilterModifiers}
*/
modifiers?: KeyFilterModifiers | undefined;
}
/**
* **PrimeVue - KeyFilter**
*
* _KeyFilter is a built-in feature of InputText to restrict user input based on a regular expression._
*
* [Live Demo](https://www.primevue.org/keyfilter/)
* --- ---
* ![PrimeVue](https://primefaces.org/cdn/primevue/images/logo-100.png)
*
*/
declare const KeyFilter: ObjectDirective;
export default KeyFilter;

View File

@ -0,0 +1,128 @@
import { isAttributeEquals } from '@primeuix/utils/dom';
import BaseKeyFilter from './BaseKeyFilter';
const KeyFilter = BaseKeyFilter.extend('keyfilter', {
beforeMount(el, options) {
let target = this.getTarget(el);
if (!target) return;
target.$_pkeyfilterModifier = this.getModifiers(options);
if (typeof options.value) {
target.$_pkeyfilterPattern = options.value?.pattern || options.value;
target.$_pkeyfilterValidateOnly = options.value?.validateOnly || false;
}
this.bindEvents(target);
target.setAttribute('data-pd-keyfilter', true);
},
updated(el, options) {
let target = this.getTarget(el);
if (!target) return;
target.$_pkeyfilterModifier = this.getModifiers(options);
this.unbindEvents(el, options);
if (typeof options.value) {
target.$_pkeyfilterPattern = options.value?.pattern || options.value;
target.$_pkeyfilterValidateOnly = options.value?.validateOnly || false;
}
this.bindEvents(target);
},
unmounted(el, options) {
this.unbindEvents(el, options);
},
DEFAULT_PATTERNS: {
pint: /[\d]/,
int: /[\d\-]/,
pnum: /[\d\.]/,
money: /[\d\.\s,]/,
num: /[\d\-\.]/,
hex: /[0-9a-f]/i,
email: /[a-z0-9_\.\-@]/i,
alpha: /[a-z_]/i,
alphanum: /[a-z0-9_]/i
},
methods: {
getTarget(el) {
return isAttributeEquals(el, 'data-pc-name', 'inputtext') || isAttributeEquals(el, 'data-pc-name', 'textarea') ? el : null;
},
getModifiers(options) {
if (options.modifiers && Object.keys(options.modifiers).length) {
return Object.keys(options.modifiers)[Object.keys.length - 1];
}
return '';
},
getRegex(target) {
return target.$_pkeyfilterPattern ? target.$_pkeyfilterPattern : target.$_pkeyfilterModifier ? this.DEFAULT_PATTERNS[target.$_pkeyfilterModifier] : /./;
},
bindEvents(el) {
el.$_keyfilterKeydownEvent = (event) => this.onKeydown(event, el);
el.$_keyfilterPasteEvent = (event) => this.onPaste(event, el);
el.addEventListener('keypress', el.$_keyfilterKeydownEvent);
el.addEventListener('paste', el.$_keyfilterPasteEvent);
},
unbindEvents(el) {
el.removeEventListener('keypress', el.$_keyfilterKeydownEvent);
el.removeEventListener('paste', el.$_keyfilterPasteEvent);
el.$_keyfilterKeydownEvent = null;
el.$_keyfilterPasteEvent = null;
},
onKeydown(event, target) {
if (event.ctrlKey || event.altKey || event.metaKey || event.key === 'Tab') {
return;
}
let regex = this.getRegex(target);
if (regex === '') {
return;
}
let testKey = `${event.key}`;
if (target.$_pkeyfilterValidateOnly) {
testKey = `${event.target.value}${event.key}`;
}
if (!regex.test(testKey)) {
// runs before @update:modelValue emit
event.preventDefault();
}
},
onPaste(event, target) {
let regex = this.getRegex(target);
if (regex === '') {
return;
}
const clipboard = event.clipboardData.getData('text');
let testKey = '';
// loop over each letter pasted and if any fail prevent the paste
[...clipboard].forEach((c) => {
if (target.$_pkeyfilterValidateOnly) {
testKey += c;
} else {
testKey = c;
}
if (!regex.test(testKey)) {
event.preventDefault();
return false;
}
});
}
}
});
export default KeyFilter;

View File

@ -0,0 +1,5 @@
{
"main": "./KeyFilter.js",
"module": "./KeyFilter.js",
"types": "./KeyFilter.d.ts"
}

View File

@ -0,0 +1,14 @@
/**
*
* KeyFilter is a built-in feature of InputText to restrict user input based on a regular expression.
*
* [Live Demo](https://primevue.org/keyfilter)
*
* @module keyfilterstyle
*
*/
import type { BaseStyle } from '@primevue/core/base/style';
export enum KeyFilterClasses {}
export interface KeyFilterStyle extends BaseStyle {}

View File

@ -0,0 +1,5 @@
import BaseStyle from '@primevue/core/base/style';
export default BaseStyle.extend({
name: 'keyfilter-directive'
});

View File

@ -0,0 +1,6 @@
{
"main": "./KeyFilterStyle.js",
"module": "./KeyFilterStyle.js",
"types": "./KeyFilterStyle.d.ts",
"sideEffects": false
}