Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@szhsin/react-autocomplete

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@szhsin/react-autocomplete - npm Package Compare versions

Comparing version 0.5.3 to 0.6.0

dist/esm/common.js

161

dist/cjs/index.js

@@ -6,19 +6,21 @@ 'use strict';

const useAutocomplete = ({
feature,
feature: useFeature = () => ({}),
items = [],
onChange = () => {}
}) => {
const inputRef = react.useRef();
const [inputValue, setInputValue] = react.useState('');
const [isOpen, setOpen] = react.useState(false);
const inputRef = react.useRef(null);
const [open, setOpen] = react.useState(false);
const [focusIndex, setFocusIndex] = react.useState(-1);
const [instance] = react.useState({
b: inputValue
b: ''
});
const setInputValue = react.useCallback(value => {
const input = inputRef.current;
if (input) input.value = value;
}, []);
const state = {
inputValue,
setInputValue,
focusIndex,
setFocusIndex,
isOpen,
open,
setOpen

@@ -31,17 +33,16 @@ };

onKeyDown,
onItemClick
} = (feature == null ? void 0 : feature({
onItemClick,
...actions
} = useFeature({
_: instance,
items,
onChange,
inputRef,
...state
})) || {};
});
const getInputProps = () => ({
value: inputValue,
ref: inputRef,
onChange: e => onInputChange == null ? void 0 : onInputChange({
value: e.target.value
}),
onClick: () => onInputClick == null ? void 0 : onInputClick(),
onBlur: () => !instance.a && (onBlur == null ? void 0 : onBlur()),
onChange: onInputChange,
onClick: onInputClick,
onBlur: e => !instance.a && (onBlur == null ? void 0 : onBlur(e)),
onKeyDown: e => {

@@ -52,5 +53,3 @@ const {

if (items.length && (key === 'ArrowUp' || key === 'ArrowDown')) e.preventDefault();
onKeyDown == null || onKeyDown({
key
});
onKeyDown == null || onKeyDown(e);
}

@@ -62,5 +61,5 @@ });

onMouseDown: () => instance.a = 1,
onClick: () => {
onClick: e => {
var _inputRef$current;
onItemClick == null || onItemClick({
onItemClick == null || onItemClick(e, {
index

@@ -82,26 +81,30 @@ });

getProps,
...state
...state,
...actions
};
};
const autocomplete = () => ({
_,
const autocomplete = ({
rovingInput
} = {}) => ({
_: cxInstance,
items,
onChange,
inputValue,
setInputValue,
focusIndex,
setFocusIndex,
isOpen,
open,
setOpen
}) => {
const updateValue = value => {
_.b = value;
const updateValue = (value, type) => {
cxInstance.b = value;
setInputValue(value);
onChange(value);
onChange(value, {
type
});
};
const updateAndCloseList = value => {
if (isOpen) {
const updateAndCloseList = (value, type) => {
if (open) {
if (value != null) {
updateValue(value);
updateValue(value, type);
}

@@ -112,4 +115,5 @@ setOpen(false);

};
const traverseItems = (isUp, baseIndex = -1) => {
const traverseItems = isUp => {
var _items$nextIndex;
const baseIndex = rovingInput ? -1 : 0;
let nextIndex = focusIndex;

@@ -123,17 +127,15 @@ const itemLength = items.length;

setFocusIndex(nextIndex);
setInputValue((_items$nextIndex = items[nextIndex]) != null ? _items$nextIndex : _.b);
rovingInput && setInputValue((_items$nextIndex = items[nextIndex]) != null ? _items$nextIndex : cxInstance.b);
};
return {
onItemClick: ({
onItemClick: (_, {
index
}) => updateAndCloseList(items[index]),
onInputChange: ({
value
}) => {
updateValue(value);
}) => updateAndCloseList(items[index], 'submit'),
onInputChange: e => {
setFocusIndex(-1);
setOpen(true);
updateValue(e.target.value, 'input');
},
onInputClick: () => setOpen(true),
onBlur: () => updateAndCloseList(inputValue),
onBlur: () => updateAndCloseList(items[focusIndex], 'blur'),
onKeyDown: ({

@@ -144,3 +146,3 @@ key

case 'ArrowUp':
if (isOpen) {
if (open) {
traverseItems(true);

@@ -152,3 +154,3 @@ } else {

case 'ArrowDown':
if (isOpen) {
if (open) {
traverseItems(false);

@@ -160,6 +162,6 @@ } else {

case 'Enter':
updateAndCloseList(items[focusIndex]);
updateAndCloseList(items[focusIndex], 'submit');
break;
case 'Escape':
updateAndCloseList(inputValue);
updateAndCloseList(cxInstance.b, 'esc');
break;

@@ -171,3 +173,72 @@ }

const supercomplete = () => {
const base = autocomplete({
rovingInput: true
});
return ({
setFocusIndex: _setFocusIndex,
onChange: _onChange,
...cx
}) => {
const [instance] = react.useState({
a: []
});
const setFocusIndex = react.useCallback(value => {
instance.b = value;
_setFocusIndex(value);
}, [instance, _setFocusIndex]);
const onChange = (value, meta) => {
if (meta.type !== 'input') {
instance.c = false;
instance.a = [];
}
_onChange(value, meta);
};
const baseFeature = base({
...cx,
setFocusIndex,
onChange
});
const {
inputRef,
setInputValue,
_: cxInstance
} = cx;
return {
...baseFeature,
onInputChange: e => {
instance.c = e.nativeEvent.inputType === 'insertText';
if (!instance.c) instance.a = [];
baseFeature.onInputChange(e);
},
onKeyDown: e => {
baseFeature.onKeyDown(e);
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
const [index, action] = instance.a;
if (instance.b === index) action == null || action();
}
},
inlineComplete: react.useCallback(({
index,
value
}) => {
if (instance.c) {
const action = () => {
var _inputRef$current;
setFocusIndex(index);
const valueLength = cxInstance.b.length;
const newValue = cxInstance.b + value.slice(valueLength);
setInputValue(newValue);
(_inputRef$current = inputRef.current) == null || _inputRef$current.setSelectionRange(valueLength, value.length);
};
action();
instance.a = [index, action];
}
}, [cxInstance, instance, inputRef, setFocusIndex, setInputValue])
};
};
};
exports.autocomplete = autocomplete;
exports.supercomplete = supercomplete;
exports.useAutocomplete = useAutocomplete;

@@ -1,21 +0,24 @@

const autocomplete = () => ({
_,
const autocomplete = ({
rovingInput
} = {}) => ({
_: cxInstance,
items,
onChange,
inputValue,
setInputValue,
focusIndex,
setFocusIndex,
isOpen,
open,
setOpen
}) => {
const updateValue = value => {
_.b = value;
const updateValue = (value, type) => {
cxInstance.b = value;
setInputValue(value);
onChange(value);
onChange(value, {
type
});
};
const updateAndCloseList = value => {
if (isOpen) {
const updateAndCloseList = (value, type) => {
if (open) {
if (value != null) {
updateValue(value);
updateValue(value, type);
}

@@ -26,4 +29,5 @@ setOpen(false);

};
const traverseItems = (isUp, baseIndex = -1) => {
const traverseItems = isUp => {
var _items$nextIndex;
const baseIndex = rovingInput ? -1 : 0;
let nextIndex = focusIndex;

@@ -37,17 +41,15 @@ const itemLength = items.length;

setFocusIndex(nextIndex);
setInputValue((_items$nextIndex = items[nextIndex]) != null ? _items$nextIndex : _.b);
rovingInput && setInputValue((_items$nextIndex = items[nextIndex]) != null ? _items$nextIndex : cxInstance.b);
};
return {
onItemClick: ({
onItemClick: (_, {
index
}) => updateAndCloseList(items[index]),
onInputChange: ({
value
}) => {
updateValue(value);
}) => updateAndCloseList(items[index], 'submit'),
onInputChange: e => {
setFocusIndex(-1);
setOpen(true);
updateValue(e.target.value, 'input');
},
onInputClick: () => setOpen(true),
onBlur: () => updateAndCloseList(inputValue),
onBlur: () => updateAndCloseList(items[focusIndex], 'blur'),
onKeyDown: ({

@@ -58,3 +60,3 @@ key

case 'ArrowUp':
if (isOpen) {
if (open) {
traverseItems(true);

@@ -66,3 +68,3 @@ } else {

case 'ArrowDown':
if (isOpen) {
if (open) {
traverseItems(false);

@@ -74,6 +76,6 @@ } else {

case 'Enter':
updateAndCloseList(items[focusIndex]);
updateAndCloseList(items[focusIndex], 'submit');
break;
case 'Escape':
updateAndCloseList(inputValue);
updateAndCloseList(cxInstance.b, 'esc');
break;

@@ -80,0 +82,0 @@ }

@@ -1,21 +0,23 @@

import { useRef, useState } from 'react';
import { useRef, useState, useCallback } from 'react';
const useAutocomplete = ({
feature,
feature: useFeature = () => ({}),
items = [],
onChange = () => {}
}) => {
const inputRef = useRef();
const [inputValue, setInputValue] = useState('');
const [isOpen, setOpen] = useState(false);
const inputRef = useRef(null);
const [open, setOpen] = useState(false);
const [focusIndex, setFocusIndex] = useState(-1);
const [instance] = useState({
b: inputValue
b: ''
});
const setInputValue = useCallback(value => {
const input = inputRef.current;
if (input) input.value = value;
}, []);
const state = {
inputValue,
setInputValue,
focusIndex,
setFocusIndex,
isOpen,
open,
setOpen

@@ -28,17 +30,16 @@ };

onKeyDown,
onItemClick
} = (feature == null ? void 0 : feature({
onItemClick,
...actions
} = useFeature({
_: instance,
items,
onChange,
inputRef,
...state
})) || {};
});
const getInputProps = () => ({
value: inputValue,
ref: inputRef,
onChange: e => onInputChange == null ? void 0 : onInputChange({
value: e.target.value
}),
onClick: () => onInputClick == null ? void 0 : onInputClick(),
onBlur: () => !instance.a && (onBlur == null ? void 0 : onBlur()),
onChange: onInputChange,
onClick: onInputClick,
onBlur: e => !instance.a && (onBlur == null ? void 0 : onBlur(e)),
onKeyDown: e => {

@@ -49,5 +50,3 @@ const {

if (items.length && (key === 'ArrowUp' || key === 'ArrowDown')) e.preventDefault();
onKeyDown == null || onKeyDown({
key
});
onKeyDown == null || onKeyDown(e);
}

@@ -59,5 +58,5 @@ });

onMouseDown: () => instance.a = 1,
onClick: () => {
onClick: e => {
var _inputRef$current;
onItemClick == null || onItemClick({
onItemClick == null || onItemClick(e, {
index

@@ -79,3 +78,4 @@ });

getProps,
...state
...state,
...actions
};

@@ -82,0 +82,0 @@ };

export { useAutocomplete } from './hooks/useAutocomplete.js';
export { autocomplete } from './features/autocomplete.js';
export { supercomplete } from './features/supercomplete.js';
{
"name": "@szhsin/react-autocomplete",
"version": "0.5.3",
"version": "0.6.0",
"description": "",

@@ -5,0 +5,0 @@ "author": "Zheng Song",

@@ -0,11 +1,14 @@

/// <reference types="react" />
export interface AutocompleteState {
inputValue: string;
setInputValue: (value: string) => void;
focusIndex: number;
setFocusIndex: (value: number) => void;
isOpen: boolean;
open: boolean;
setOpen: (value: boolean) => void;
}
interface ContextualProps {
onChange: (value: string) => void;
export type ChangeType = 'submit' | 'input' | 'blur' | 'esc';
export interface ContextualProps {
onChange: (value: string, meta: {
type: ChangeType;
}) => void;
items: string[];

@@ -26,2 +29,3 @@ }

export interface Contextual extends ContextualProps, AutocompleteState {
inputRef: React.RefObject<HTMLInputElement>;
/**

@@ -32,19 +36,13 @@ * ### INTERNAL API ###

}
type FeatureEventHandler<E> = (event: E) => void;
export type Feature = (cx: Contextual) => {
onInputChange?: FeatureEventHandler<{
value: string;
}>;
onInputClick?: () => void;
onBlur?: () => void;
onKeyDown?: FeatureEventHandler<{
key: string;
}>;
onItemClick?: FeatureEventHandler<{
export type Feature<Actions = object> = (cx: Contextual) => {
onInputChange?: React.ChangeEventHandler<HTMLInputElement>;
onInputClick?: React.MouseEventHandler<HTMLInputElement>;
onBlur?: React.FocusEventHandler<HTMLInputElement>;
onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;
onItemClick?: (event: React.MouseEvent<HTMLElement>, props: {
index: number;
}>;
};
export interface AutocompleteProps extends Partial<ContextualProps> {
feature?: Feature;
}) => void;
} & Actions;
export interface AutocompleteProps<FeatureActions = object> extends Partial<ContextualProps> {
feature?: Feature<FeatureActions>;
}
export {};

@@ -1,3 +0,5 @@

import { Feature } from '../common';
declare const autocomplete: () => Feature;
import type { Feature } from '../common';
declare const autocomplete: (props?: {
rovingInput?: boolean;
}) => Feature;
export { autocomplete };

@@ -9,11 +9,10 @@ import type { InputHTMLAttributes, HTMLAttributes } from 'react';

}
declare const useAutocomplete: ({ feature, items, onChange }: AutocompleteProps) => {
inputValue: string;
declare const useAutocomplete: <FeatureActions = object>({ feature: useFeature, items, onChange }: AutocompleteProps<FeatureActions>) => {
setInputValue: (value: string) => void;
focusIndex: number;
setFocusIndex: (value: number) => void;
isOpen: boolean;
open: boolean;
setOpen: (value: boolean) => void;
getProps: <T extends keyof GetProps>(elementType: T, option?: GetProps[T][0] | undefined) => GetProps[T][1];
};
} & FeatureActions;
export { useAutocomplete };
export { useAutocomplete } from './hooks/useAutocomplete';
export { autocomplete } from './features/autocomplete';
export { supercomplete } from './features/supercomplete';
export type { AutocompleteProps, AutocompleteState, Feature } from './common';
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc