react-tag-autocomplete
Advanced tools
Comparing version 7.0.1 to 7.1.0
# Changelog | ||
## v7.0.1 | ||
## v7.1.0 | ||
- Fixed an issue where the `onShouldExpand` and `onShouldCollapse` callbacks would receive the previous value on input. | ||
- Added support for rendering a custom list box component using `renderListBox` prop | ||
- Fixed an issue where auto scrolling to the active option in the list box could also scroll parent containers | ||
## v7.0.1 | ||
- Fixed an issue where the `onShouldExpand` and `onShouldCollapse` callbacks would receive the previous value on input | ||
## v7.0.0 | ||
@@ -8,0 +13,0 @@ |
@@ -428,3 +428,3 @@ "use strict"; | ||
function useOption(index) { | ||
const { id, inputRef, managerRef } = React.useContext(GlobalContext); | ||
const { id, inputRef, listBoxRef, managerRef } = React.useContext(GlobalContext); | ||
const optionRef = React.useRef(null); | ||
@@ -445,8 +445,3 @@ const option = managerRef.current.state.options[index]; | ||
}, [index, managerRef]); | ||
React.useEffect(() => { | ||
var _a; | ||
if (active) { | ||
(_a = optionRef.current) == null ? void 0 : _a.scrollIntoView({ block: "nearest", inline: "start" }); | ||
} | ||
}, [active, managerRef.current.state.options]); | ||
useScrollIntoView(optionRef, listBoxRef, active); | ||
return { | ||
@@ -549,2 +544,19 @@ option: { | ||
} | ||
function useScrollIntoView(targetRef, containerRef, shouldScroll) { | ||
React.useEffect(() => { | ||
var _a, _b, _c, _d; | ||
if (shouldScroll) { | ||
const targetHeight = (_a = targetRef.current) == null ? void 0 : _a.offsetHeight; | ||
const targetOffset = (_b = targetRef.current) == null ? void 0 : _b.offsetTop; | ||
const containerHeight = (_c = containerRef.current) == null ? void 0 : _c.offsetHeight; | ||
const containerScroll = (_d = containerRef.current) == null ? void 0 : _d.scrollTop; | ||
if (targetOffset < containerScroll) { | ||
containerRef.current.scrollTo(0, targetOffset); | ||
} | ||
if (targetOffset + targetHeight > containerScroll + containerHeight) { | ||
containerRef.current.scrollTo(0, targetOffset + targetHeight - containerHeight); | ||
} | ||
} | ||
}, [shouldScroll, containerRef, targetRef]); | ||
} | ||
function useSelectedTag(index, title) { | ||
@@ -657,3 +669,6 @@ const { isDisabled, managerRef } = React.useContext(GlobalContext); | ||
} | ||
function ListBox({ children }) { | ||
const DefaultListBox = ({ children, classNames, ...listBoxProps }) => { | ||
return /* @__PURE__ */ React.createElement("div", { className: classNames.listBox, ...listBoxProps }, children); | ||
}; | ||
function ListBox({ children, render = DefaultListBox }) { | ||
const { classNames, managerRef } = React.useContext(GlobalContext); | ||
@@ -663,3 +678,3 @@ const listBoxProps = useListBox(); | ||
return null; | ||
return /* @__PURE__ */ React.createElement("div", { className: classNames.listBox, ...listBoxProps }, children); | ||
return render({ children, classNames, ...listBoxProps }); | ||
} | ||
@@ -763,2 +778,3 @@ const DefaultOption = ({ children, classNames, option, ...optionProps }) => { | ||
renderLabel, | ||
renderListBox, | ||
renderOption, | ||
@@ -826,3 +842,3 @@ renderRoot, | ||
} | ||
), /* @__PURE__ */ React.createElement(ListBox, null, managerRef.current.state.options.map((option, index) => /* @__PURE__ */ React.createElement(Option, { key: tagToKey(option), index, render: renderOption }, /* @__PURE__ */ React.createElement( | ||
), /* @__PURE__ */ React.createElement(ListBox, { render: renderListBox }, managerRef.current.state.options.map((option, index) => /* @__PURE__ */ React.createElement(Option, { key: tagToKey(option), index, render: renderOption }, /* @__PURE__ */ React.createElement( | ||
MemoizedHighlight, | ||
@@ -829,0 +845,0 @@ { |
@@ -426,3 +426,3 @@ import React, { useContext, useMemo, useRef, useState, useLayoutEffect, useCallback, useEffect } from "react"; | ||
function useOption(index) { | ||
const { id, inputRef, managerRef } = useContext(GlobalContext); | ||
const { id, inputRef, listBoxRef, managerRef } = useContext(GlobalContext); | ||
const optionRef = useRef(null); | ||
@@ -443,8 +443,3 @@ const option = managerRef.current.state.options[index]; | ||
}, [index, managerRef]); | ||
useEffect(() => { | ||
var _a; | ||
if (active) { | ||
(_a = optionRef.current) == null ? void 0 : _a.scrollIntoView({ block: "nearest", inline: "start" }); | ||
} | ||
}, [active, managerRef.current.state.options]); | ||
useScrollIntoView(optionRef, listBoxRef, active); | ||
return { | ||
@@ -547,2 +542,19 @@ option: { | ||
} | ||
function useScrollIntoView(targetRef, containerRef, shouldScroll) { | ||
useEffect(() => { | ||
var _a, _b, _c, _d; | ||
if (shouldScroll) { | ||
const targetHeight = (_a = targetRef.current) == null ? void 0 : _a.offsetHeight; | ||
const targetOffset = (_b = targetRef.current) == null ? void 0 : _b.offsetTop; | ||
const containerHeight = (_c = containerRef.current) == null ? void 0 : _c.offsetHeight; | ||
const containerScroll = (_d = containerRef.current) == null ? void 0 : _d.scrollTop; | ||
if (targetOffset < containerScroll) { | ||
containerRef.current.scrollTo(0, targetOffset); | ||
} | ||
if (targetOffset + targetHeight > containerScroll + containerHeight) { | ||
containerRef.current.scrollTo(0, targetOffset + targetHeight - containerHeight); | ||
} | ||
} | ||
}, [shouldScroll, containerRef, targetRef]); | ||
} | ||
function useSelectedTag(index, title) { | ||
@@ -655,3 +667,6 @@ const { isDisabled, managerRef } = useContext(GlobalContext); | ||
} | ||
function ListBox({ children }) { | ||
const DefaultListBox = ({ children, classNames, ...listBoxProps }) => { | ||
return /* @__PURE__ */ React.createElement("div", { className: classNames.listBox, ...listBoxProps }, children); | ||
}; | ||
function ListBox({ children, render = DefaultListBox }) { | ||
const { classNames, managerRef } = useContext(GlobalContext); | ||
@@ -661,3 +676,3 @@ const listBoxProps = useListBox(); | ||
return null; | ||
return /* @__PURE__ */ React.createElement("div", { className: classNames.listBox, ...listBoxProps }, children); | ||
return render({ children, classNames, ...listBoxProps }); | ||
} | ||
@@ -761,2 +776,3 @@ const DefaultOption = ({ children, classNames, option, ...optionProps }) => { | ||
renderLabel, | ||
renderListBox, | ||
renderOption, | ||
@@ -824,3 +840,3 @@ renderRoot, | ||
} | ||
), /* @__PURE__ */ React.createElement(ListBox, null, managerRef.current.state.options.map((option, index) => /* @__PURE__ */ React.createElement(Option, { key: tagToKey(option), index, render: renderOption }, /* @__PURE__ */ React.createElement( | ||
), /* @__PURE__ */ React.createElement(ListBox, { render: renderListBox }, managerRef.current.state.options.map((option, index) => /* @__PURE__ */ React.createElement(Option, { key: tagToKey(option), index, render: renderOption }, /* @__PURE__ */ React.createElement( | ||
MemoizedHighlight, | ||
@@ -827,0 +843,0 @@ { |
@@ -429,3 +429,3 @@ (function(global, factory) { | ||
function useOption(index) { | ||
const { id, inputRef, managerRef } = React.useContext(GlobalContext); | ||
const { id, inputRef, listBoxRef, managerRef } = React.useContext(GlobalContext); | ||
const optionRef = React.useRef(null); | ||
@@ -446,8 +446,3 @@ const option = managerRef.current.state.options[index]; | ||
}, [index, managerRef]); | ||
React.useEffect(() => { | ||
var _a; | ||
if (active) { | ||
(_a = optionRef.current) == null ? void 0 : _a.scrollIntoView({ block: "nearest", inline: "start" }); | ||
} | ||
}, [active, managerRef.current.state.options]); | ||
useScrollIntoView(optionRef, listBoxRef, active); | ||
return { | ||
@@ -550,2 +545,19 @@ option: { | ||
} | ||
function useScrollIntoView(targetRef, containerRef, shouldScroll) { | ||
React.useEffect(() => { | ||
var _a, _b, _c, _d; | ||
if (shouldScroll) { | ||
const targetHeight = (_a = targetRef.current) == null ? void 0 : _a.offsetHeight; | ||
const targetOffset = (_b = targetRef.current) == null ? void 0 : _b.offsetTop; | ||
const containerHeight = (_c = containerRef.current) == null ? void 0 : _c.offsetHeight; | ||
const containerScroll = (_d = containerRef.current) == null ? void 0 : _d.scrollTop; | ||
if (targetOffset < containerScroll) { | ||
containerRef.current.scrollTo(0, targetOffset); | ||
} | ||
if (targetOffset + targetHeight > containerScroll + containerHeight) { | ||
containerRef.current.scrollTo(0, targetOffset + targetHeight - containerHeight); | ||
} | ||
} | ||
}, [shouldScroll, containerRef, targetRef]); | ||
} | ||
function useSelectedTag(index, title) { | ||
@@ -658,3 +670,6 @@ const { isDisabled, managerRef } = React.useContext(GlobalContext); | ||
} | ||
function ListBox({ children }) { | ||
const DefaultListBox = ({ children, classNames, ...listBoxProps }) => { | ||
return /* @__PURE__ */ React.createElement("div", { className: classNames.listBox, ...listBoxProps }, children); | ||
}; | ||
function ListBox({ children, render = DefaultListBox }) { | ||
const { classNames, managerRef } = React.useContext(GlobalContext); | ||
@@ -664,3 +679,3 @@ const listBoxProps = useListBox(); | ||
return null; | ||
return /* @__PURE__ */ React.createElement("div", { className: classNames.listBox, ...listBoxProps }, children); | ||
return render({ children, classNames, ...listBoxProps }); | ||
} | ||
@@ -764,2 +779,3 @@ const DefaultOption = ({ children, classNames, option, ...optionProps }) => { | ||
renderLabel, | ||
renderListBox, | ||
renderOption, | ||
@@ -827,3 +843,3 @@ renderRoot, | ||
} | ||
), /* @__PURE__ */ React.createElement(ListBox, null, managerRef.current.state.options.map((option, index) => /* @__PURE__ */ React.createElement(Option, { key: tagToKey(option), index, render: renderOption }, /* @__PURE__ */ React.createElement( | ||
), /* @__PURE__ */ React.createElement(ListBox, { render: renderListBox }, managerRef.current.state.options.map((option, index) => /* @__PURE__ */ React.createElement(Option, { key: tagToKey(option), index, render: renderOption }, /* @__PURE__ */ React.createElement( | ||
MemoizedHighlight, | ||
@@ -830,0 +846,0 @@ { |
@@ -85,2 +85,7 @@ // Generated by dts-bundle-generator v8.0.1 | ||
export type OptionRenderer = (props: OptionRendererProps) => JSX.Element; | ||
export type ListBoxRendererProps = React.ComponentPropsWithRef<"div"> & { | ||
children: React.ReactNode; | ||
classNames: ClassNames; | ||
}; | ||
export type ListBoxRenderer = (props: ListBoxRendererProps) => JSX.Element; | ||
export type RootRendererProps = React.ComponentPropsWithRef<"div"> & { | ||
@@ -132,2 +137,3 @@ children: React.ReactNode; | ||
renderLabel?: LabelRenderer; | ||
renderListBox?: ListBoxRenderer; | ||
renderOption?: OptionRenderer; | ||
@@ -134,0 +140,0 @@ renderRoot?: RootRenderer; |
{ | ||
"name": "react-tag-autocomplete", | ||
"version": "7.0.1", | ||
"version": "7.1.0", | ||
"description": "A simple, accessible, tagging component ready to drop into your React projects.", | ||
@@ -5,0 +5,0 @@ "main": "dist/ReactTags.cjs.js", |
@@ -105,2 +105,3 @@ # React Tag Autocomplete | ||
- [`renderLabel`](#renderLabel-optional) | ||
- [`renderListBox`](#renderListBox-optional) | ||
- [`renderOption`](#renderOption-optional) | ||
@@ -326,2 +327,16 @@ - [`renderRoot`](#renderRoot-optional) | ||
#### renderListBox (optional) | ||
A custom list box component to render. Receives the options as children, required list box element attributes, and [`classNames`](#classNames-optional) as props. Defaults to `null`. | ||
```jsx | ||
function CustomListBox({ children, classNames, ...listBoxProps }) { | ||
return ( | ||
<div className={classNames.listBox} {...listBoxProps}> | ||
{children} | ||
</div> | ||
) | ||
} | ||
``` | ||
#### renderOption (optional) | ||
@@ -328,0 +343,0 @@ |
398276
13031
515