@yaireo/tagify
Advanced tools
Comparing version 4.23.0 to 4.24.0
/* | ||
Tagify v4.23.0 - tags input component | ||
Tagify v4.24.0 - tags input component | ||
By: Yair Even-Or <vsync.design@gmail.com> | ||
@@ -4,0 +4,0 @@ https://github.com/yairEO/tagify |
{ | ||
"name": "@yaireo/tagify", | ||
"version": "4.23.0", | ||
"version": "4.24.0", | ||
"homepage": "https://github.com/yairEO/tagify", | ||
@@ -5,0 +5,0 @@ "description": "lightweight, efficient Tags input component in Vanilla JS / React / Angular [super customizable, tiny size & top performance]", |
@@ -15,2 +15,3 @@ export default { | ||
userInput : true, // disable manually typing/pasting/editing tags (tags may only be added from the whitelist) | ||
focusable : true, // Allow the component as a whole to recieve focus. There are implementations of Tagify without external border and so 'focusability' causes unwanted behaviour | ||
keepInvalidTags : false, // if true, do not remove tags which did not pass validation | ||
@@ -86,3 +87,3 @@ createInvalidTags : true, // if false, do not create invalid tags from invalid user input | ||
escapeHTML : true, // escapes HTML entities in the suggestions' rendered text | ||
highlightFirst : true, // highlights first-matched item in the list | ||
highlightFirst : true, // highlights first-matched item in the list | ||
closeOnSelect : true, // closes the dropdown after selecting an item, if `enabled:0` (which means always show dropdown) | ||
@@ -89,0 +90,0 @@ clearOnSelect : true, // after selecting a suggetion, should the typed text input remain or be cleared |
@@ -5,7 +5,9 @@ import { extend, logger } from './helpers' | ||
// Create a DOM EventTarget object | ||
var target = document.createTextNode('') | ||
var target = document.createTextNode(''), | ||
// keep track of all binded events & their callbacks to be able to completely remove all listeners of a speicific type | ||
callbacksPerType = {} | ||
function addRemove(op, events, cb){ | ||
if( cb ) | ||
events.split(/\s+/g).forEach(name => target[op + 'EventListener'].call(target, name, cb)) | ||
events.split(/\s+/g).forEach(ev => target[op + 'EventListener'].call(target, ev, cb)) | ||
} | ||
@@ -15,4 +17,23 @@ | ||
return { | ||
// unbinds all events | ||
removeAllCustomListeners(){ | ||
Object.entries(callbacksPerType).forEach(([ev, cbArr]) => { | ||
cbArr.forEach(cb => addRemove('remove', ev, cb)) | ||
}) | ||
callbacksPerType = {} | ||
}, | ||
off(events, cb){ | ||
addRemove('remove', events, cb) | ||
if( events ) { | ||
if( cb ) | ||
addRemove('remove', events, cb) | ||
else | ||
// if `cb` argument was not specified then remove all listeners for the given event(s) types | ||
events.split(/\s+/g).forEach(ev => { | ||
callbacksPerType[ev]?.forEach(cb => addRemove('remove', ev, cb)) | ||
delete callbacksPerType[ev] | ||
}) | ||
} | ||
return this | ||
@@ -22,4 +43,14 @@ }, | ||
on(events, cb){ | ||
if(cb && typeof cb == 'function') | ||
if(cb && typeof cb == 'function') { | ||
//track events callbacks to be able to remove them altogehter | ||
events.split(/\s+/g).forEach(ev => { | ||
if (Array.isArray(callbacksPerType[ev]) ) | ||
callbacksPerType[ev].push(cb) | ||
else | ||
callbacksPerType[ev] = [cb] | ||
}) | ||
addRemove('add', events, cb) | ||
} | ||
return this | ||
@@ -26,0 +57,0 @@ }, |
@@ -212,8 +212,11 @@ import { decode, extend, getfirstTextNode, isChromeAndroidBrowser, isNodeTag, isWithinNodeTag, injectAtCaret, getSetTagData, fixCaretBetweenTags, placeCaretAfterNode } from './helpers' | ||
if( isFocused ){ | ||
if( !_s.focusable ) return; | ||
this.toggleFocusClass(true); | ||
this.trigger("focus", eventData) | ||
// e.target.classList.remove('placeholder'); | ||
if( (_s.dropdown.enabled === 0 || !_s.userInput) && !this.state.dropdown.visible ){ // && _s.mode != "select" | ||
if( (_s.dropdown.enabled === 0) && !this.state.dropdown.visible ){ // && _s.mode != "select" | ||
this.dropdown.show(this.value.length ? '' : undefined) | ||
} | ||
return | ||
@@ -766,3 +769,3 @@ } | ||
if( timeDiffFocus > 500 ){ | ||
if( timeDiffFocus > 500 || !_s.focusable ){ | ||
if( this.state.dropdown.visible ) | ||
@@ -899,3 +902,3 @@ this.dropdown.hide() | ||
// clicking those elements should not be considered a blur event | ||
if( isRelatedTargetNodeTag && e.relatedTarget.contains(e.target) ) { | ||
if( this.settings.mode == 'select' && isRelatedTargetNodeTag && e.relatedTarget.contains(e.target) ) { | ||
this.dropdown.hide() | ||
@@ -902,0 +905,0 @@ return |
@@ -97,25 +97,2 @@ import React, {useMemo, useEffect, useRef, useCallback} from "react" | ||
t.on("input" , onInput) | ||
.on("add" , onAdd) | ||
.on("remove" , onRemove) | ||
.on("invalid", onInvalid) | ||
.on("keydown", onKeydown) | ||
.on("focus" , onFocus) | ||
.on("blur" , onBlur) | ||
.on("click" , onClick) | ||
.on("change" , onChange) | ||
.on("edit:input" , onEditInput) | ||
.on("edit:beforeUpdate", onEditBeforeUpdate) | ||
.on("edit:updated" , onEditUpdated) | ||
.on("edit:start" , onEditStart) | ||
.on("edit:keydown" , onEditKeydown) | ||
.on("dropdown:show" , onDropdownShow) | ||
.on("dropdown:hide" , onDropdownHide) | ||
.on("dropdown:select" , onDropdownSelect) | ||
.on("dropdown:scroll" , onDropdownScroll) | ||
.on("dropdown:noMatch", onDropdownNoMatch) | ||
.on("dropdown:updated", onDropdownUpdated) | ||
// Bridge Tagify instance with parent component | ||
@@ -136,2 +113,27 @@ if (tagifyRef) { | ||
// event listeners updaters | ||
useEffect(() => { tagify.current.off('change').on('change' , onChange) }, [onChange]) | ||
useEffect(() => { tagify.current.off('input').on('input' , onInput) }, [onInput]) | ||
useEffect(() => { tagify.current.off('add').on('add' , onAdd) }, [onAdd]) | ||
useEffect(() => { tagify.current.off('remove').on('remove' , onRemove) }, [onRemove]) | ||
useEffect(() => { tagify.current.off('invalid').on('invalid' , onInvalid) }, [onInvalid]) | ||
useEffect(() => { tagify.current.off('keydown').on('keydown' , onKeydown) }, [onKeydown]) | ||
useEffect(() => { tagify.current.off('focus').on('focus' , onFocus) }, [onFocus]) | ||
useEffect(() => { tagify.current.off('blur').on('blur' , onBlur) }, [onBlur]) | ||
useEffect(() => { tagify.current.off('click').on('click' , onClick) }, [onClick]) | ||
useEffect(() => { tagify.current.off('edit:input').on('edit:input' , onEditInput) }, [onEditInput]) | ||
useEffect(() => { tagify.current.off('edit:beforeUpdate').on('edit:beforeUpdate' , onEditBeforeUpdate) }, [onEditBeforeUpdate]) | ||
useEffect(() => { tagify.current.off('edit:updated').on('edit:updated' , onEditUpdated) }, [onEditUpdated]) | ||
useEffect(() => { tagify.current.off('edit:start').on('edit:start' , onEditStart) }, [onEditStart]) | ||
useEffect(() => { tagify.current.off('edit:keydown').on('edit:keydown' , onEditKeydown) }, [onEditKeydown]) | ||
useEffect(() => { tagify.current.off('dropdown:show').on('dropdown:show' , onDropdownShow) }, [onDropdownShow]) | ||
useEffect(() => { tagify.current.off('dropdown:hide').on('dropdown:hide' , onDropdownHide) }, [onDropdownHide]) | ||
useEffect(() => { tagify.current.off('dropdown:select').on('dropdown:select' , onDropdownSelect) }, [onDropdownSelect]) | ||
useEffect(() => { tagify.current.off('dropdown:scroll').on('dropdown:scroll' , onDropdownScroll) }, [onDropdownScroll]) | ||
useEffect(() => { tagify.current.off('dropdown:noMatch').on('dropdown:noMatch' , onDropdownNoMatch) }, [onDropdownNoMatch]) | ||
useEffect(() => { tagify.current.off('dropdown:updated').on('dropdown:updated' , onDropdownUpdated) }, [onDropdownUpdated]) | ||
useEffect(() => { | ||
@@ -138,0 +140,0 @@ setFocus() |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
2899241
5162
1151
0