@festo-ui/react 10.1.0-dev.875 → 10.1.1
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/dist/components/pagination/Pagination.d.ts +5 -1
- package/dist/components/pagination/Pagination.js +12 -6
- package/dist/components/popovers/popover/Popover.js +3 -6
- package/dist/components/search-input/ClearButton.d.ts +1 -0
- package/dist/components/search-input/ClearButton.js +11 -0
- package/dist/components/search-input/SearchInput.css +0 -12
- package/dist/components/search-input/SearchInput.d.ts +6 -18
- package/dist/components/search-input/SearchInput.js +58 -82
- package/dist/components/search-input/SearchSuggestion.d.ts +17 -0
- package/dist/components/search-input/SearchSuggestion.js +21 -0
- package/dist/components/search-input/useSearchInput.d.ts +13 -0
- package/dist/components/search-input/useSearchInput.js +85 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +2 -3
- package/package.json +1 -1
- package/dist/components/search-input/SearchInputOption.d.ts +0 -5
- package/dist/components/search-input/SearchInputOption.js +0 -18
- package/dist/components/search-input/SearchResult.d.ts +0 -8
- package/dist/components/search-input/SearchResult.js +0 -48
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import './Pagination.scss';
|
|
2
|
-
export
|
|
2
|
+
export declare enum PaginationType {
|
|
3
|
+
Simple = "SIMPLE",
|
|
4
|
+
Numeric = "NUMERIC",
|
|
5
|
+
Dots = "DOTS"
|
|
6
|
+
}
|
|
3
7
|
export interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange'> {
|
|
4
8
|
readonly type?: PaginationType;
|
|
5
9
|
readonly onChange?: (page: number, event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
@@ -2,7 +2,13 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import "./Pagination.css";
|
|
3
3
|
import classnames from "classnames";
|
|
4
4
|
import { forwardRef, useEffect, useState } from "react";
|
|
5
|
-
|
|
5
|
+
var Pagination_PaginationType = /*#__PURE__*/ function(PaginationType) {
|
|
6
|
+
PaginationType["Simple"] = "SIMPLE";
|
|
7
|
+
PaginationType["Numeric"] = "NUMERIC";
|
|
8
|
+
PaginationType["Dots"] = "DOTS";
|
|
9
|
+
return PaginationType;
|
|
10
|
+
}({});
|
|
11
|
+
const Pagination = /*#__PURE__*/ forwardRef(({ pageMax, onChange, pageCurrent, defaultPageCurrent = 1, type = "NUMERIC", className, ...props }, ref)=>{
|
|
6
12
|
const controlled = void 0 !== pageCurrent;
|
|
7
13
|
const dotArray = Array.from(new Array(pageMax).keys());
|
|
8
14
|
const [innerPageCurrent, setInnerPageCurrent] = useState(controlled ? pageCurrent : defaultPageCurrent);
|
|
@@ -34,7 +40,7 @@ const Pagination = /*#__PURE__*/ forwardRef(({ pageMax, onChange, pageCurrent, d
|
|
|
34
40
|
}
|
|
35
41
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
36
42
|
children: [
|
|
37
|
-
|
|
43
|
+
"DOTS" !== type && /*#__PURE__*/ jsxs("div", {
|
|
38
44
|
...props,
|
|
39
45
|
className: classnames('fwe-pagination', {
|
|
40
46
|
'fwe-d-none': pageMax < 2
|
|
@@ -49,7 +55,7 @@ const Pagination = /*#__PURE__*/ forwardRef(({ pageMax, onChange, pageCurrent, d
|
|
|
49
55
|
type: "button",
|
|
50
56
|
"aria-label": "navigate-btn-down"
|
|
51
57
|
}),
|
|
52
|
-
|
|
58
|
+
"NUMERIC" === type && /*#__PURE__*/ jsxs(Fragment, {
|
|
53
59
|
children: [
|
|
54
60
|
/*#__PURE__*/ jsx("span", {
|
|
55
61
|
className: "fwe-page-current",
|
|
@@ -64,7 +70,7 @@ const Pagination = /*#__PURE__*/ forwardRef(({ pageMax, onChange, pageCurrent, d
|
|
|
64
70
|
/*#__PURE__*/ jsx("button", {
|
|
65
71
|
className: classnames('fwe-navigate-btn-up', {
|
|
66
72
|
'fwe-disabled': innerPageCurrent >= pageMax,
|
|
67
|
-
'fwe-ml-4':
|
|
73
|
+
'fwe-ml-4': "SIMPLE" === type
|
|
68
74
|
}),
|
|
69
75
|
onClick: onBtnUp,
|
|
70
76
|
type: "button",
|
|
@@ -72,7 +78,7 @@ const Pagination = /*#__PURE__*/ forwardRef(({ pageMax, onChange, pageCurrent, d
|
|
|
72
78
|
})
|
|
73
79
|
]
|
|
74
80
|
}),
|
|
75
|
-
|
|
81
|
+
"DOTS" === type && /*#__PURE__*/ jsx("div", {
|
|
76
82
|
...props,
|
|
77
83
|
className: classnames({
|
|
78
84
|
'fwe-d-none': pageMax < 2
|
|
@@ -95,4 +101,4 @@ const Pagination = /*#__PURE__*/ forwardRef(({ pageMax, onChange, pageCurrent, d
|
|
|
95
101
|
});
|
|
96
102
|
});
|
|
97
103
|
Pagination.displayName = 'Pagination';
|
|
98
|
-
export { Pagination };
|
|
104
|
+
export { Pagination, Pagination_PaginationType as PaginationType };
|
|
@@ -61,12 +61,9 @@ const Popover = /*#__PURE__*/ forwardRef(({ children, className, style, containe
|
|
|
61
61
|
},
|
|
62
62
|
...getReferenceProps({
|
|
63
63
|
...props,
|
|
64
|
-
onClick: (
|
|
65
|
-
if (stopPropagation)
|
|
66
|
-
|
|
67
|
-
e.stopPropagation();
|
|
68
|
-
}
|
|
69
|
-
onTriggerClick?.(e);
|
|
64
|
+
onClick: (event)=>{
|
|
65
|
+
if (stopPropagation) event.stopPropagation();
|
|
66
|
+
onTriggerClick?.(event);
|
|
70
67
|
}
|
|
71
68
|
}),
|
|
72
69
|
children: children
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ClearButton: (props: Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & import("react").RefAttributes<HTMLButtonElement>) => React.ReactElement | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
const ClearButton = /*#__PURE__*/ forwardRef((props, ref)=>/*#__PURE__*/ jsx("button", {
|
|
4
|
+
type: "button",
|
|
5
|
+
className: "fwe-clear-icon fr-search-input-clear-button",
|
|
6
|
+
"aria-label": "Clear",
|
|
7
|
+
ref: ref,
|
|
8
|
+
...props
|
|
9
|
+
}));
|
|
10
|
+
ClearButton.displayName = 'ClearButton';
|
|
11
|
+
export { ClearButton };
|
|
@@ -2,13 +2,6 @@
|
|
|
2
2
|
height: 40px;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
.fwe-search-suggestions {
|
|
6
|
-
top: unset;
|
|
7
|
-
left: unset;
|
|
8
|
-
right: unset;
|
|
9
|
-
position: static;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
5
|
.fr-search-input-clear-button {
|
|
13
6
|
background: none;
|
|
14
7
|
border: none;
|
|
@@ -18,8 +11,3 @@
|
|
|
18
11
|
display: flex;
|
|
19
12
|
}
|
|
20
13
|
|
|
21
|
-
.fr-search-result-highlight {
|
|
22
|
-
font-weight: unset;
|
|
23
|
-
color: var(--fwe-hero, #0091dc);
|
|
24
|
-
}
|
|
25
|
-
|
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
import './SearchInput.scss';
|
|
2
|
-
import { type ComponentPropsWithoutRef
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { type ComponentPropsWithoutRef } from 'react';
|
|
3
|
+
import type { SearchSuggestion } from './SearchSuggestion';
|
|
4
|
+
export interface SearchInputProps extends Omit<ComponentPropsWithoutRef<'input'>, 'onChange' | 'value' | 'defaultValue'> {
|
|
5
5
|
readonly label?: string;
|
|
6
|
-
/** Controlled value. */
|
|
7
|
-
readonly value?: string;
|
|
8
|
-
/** Initial value for uncontrolled usage. */
|
|
9
6
|
readonly defaultValue?: string;
|
|
10
|
-
|
|
11
|
-
readonly
|
|
12
|
-
/**
|
|
13
|
-
* Called after the debounce interval when the user types.
|
|
14
|
-
* Use this to trigger a search and update the children (suggestions).
|
|
15
|
-
*/
|
|
7
|
+
readonly value?: string;
|
|
8
|
+
readonly suggestions?: SearchSuggestion[];
|
|
16
9
|
readonly onChange?: (value: string) => void;
|
|
17
|
-
|
|
10
|
+
readonly onKeyboardNavigate?: (value: string) => void;
|
|
18
11
|
readonly onSearch?: (value: string) => void;
|
|
19
|
-
/**
|
|
20
|
-
* Render search suggestions as children.
|
|
21
|
-
* Use `<SearchInputOption>` for each item.
|
|
22
|
-
*/
|
|
23
|
-
readonly children?: ReactNode;
|
|
24
12
|
}
|
|
25
13
|
export declare const SearchInput: (props: SearchInputProps & import("react").RefAttributes<HTMLDivElement>) => React.ReactElement | null;
|
|
@@ -1,88 +1,64 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "./SearchInput.css";
|
|
3
|
-
import { Combobox, ComboboxButton, ComboboxInput, ComboboxOptions } from "@headlessui/react";
|
|
4
3
|
import classnames from "classnames";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
/*#__PURE__*/ jsx("div", {
|
|
64
|
-
className: "fwe-search-icon"
|
|
65
|
-
}),
|
|
66
|
-
/*#__PURE__*/ jsx(ComboboxButton, {
|
|
67
|
-
className: "fwe-clear-icon fr-search-input-clear-button",
|
|
68
|
-
"aria-label": "Clear",
|
|
69
|
-
onClick: handleClear
|
|
70
|
-
}),
|
|
71
|
-
hasChildren && /*#__PURE__*/ jsx(ComboboxOptions, {
|
|
72
|
-
className: "fwe-search-suggestions",
|
|
73
|
-
as: "div",
|
|
74
|
-
portal: false,
|
|
75
|
-
anchor: {
|
|
76
|
-
to: 'bottom start',
|
|
77
|
-
gap: 4
|
|
78
|
-
},
|
|
79
|
-
style: {
|
|
80
|
-
minWidth: 'var(--input-width)'
|
|
81
|
-
},
|
|
82
|
-
children: children
|
|
83
|
-
})
|
|
84
|
-
]
|
|
85
|
-
})
|
|
4
|
+
import { forwardRef, useRef } from "react";
|
|
5
|
+
import { useForkRef } from "../../utils/useForkRef.js";
|
|
6
|
+
import { useOnClickOutside } from "../../utils/useOnClickOutside.js";
|
|
7
|
+
import { ClearButton } from "./ClearButton.js";
|
|
8
|
+
import { useSearchInput } from "./useSearchInput.js";
|
|
9
|
+
const SearchInput = /*#__PURE__*/ forwardRef(({ defaultValue, disabled, label, value, suggestions, onChange, onSearch, onKeyboardNavigate, className, ...props }, ref)=>{
|
|
10
|
+
const inputRef = useRef(null);
|
|
11
|
+
const containerRef = useRef(null);
|
|
12
|
+
const handleRef = useForkRef(ref, containerRef);
|
|
13
|
+
const cappedSuggestions = suggestions?.slice(0, 10) ?? [];
|
|
14
|
+
const { handleFocus, handleInput, handleClearQuery, handleSuggestionClick, handleOutsideClick, handleKeyDown, hideSuggestionList, selectedSuggestionIndex, innerValue } = useSearchInput(inputRef, cappedSuggestions, value, defaultValue, onChange, onSearch, onKeyboardNavigate);
|
|
15
|
+
useOnClickOutside(containerRef, handleOutsideClick);
|
|
16
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
17
|
+
className: classnames('fwe-search-input', className),
|
|
18
|
+
ref: handleRef,
|
|
19
|
+
children: [
|
|
20
|
+
/*#__PURE__*/ jsx("input", {
|
|
21
|
+
ref: inputRef,
|
|
22
|
+
disabled: disabled,
|
|
23
|
+
placeholder: label,
|
|
24
|
+
onFocus: handleFocus,
|
|
25
|
+
type: "search",
|
|
26
|
+
"aria-label": "Search",
|
|
27
|
+
onInput: handleInput,
|
|
28
|
+
onKeyDown: handleKeyDown,
|
|
29
|
+
value: innerValue,
|
|
30
|
+
...props
|
|
31
|
+
}),
|
|
32
|
+
/*#__PURE__*/ jsx("div", {
|
|
33
|
+
className: "fwe-search-icon"
|
|
34
|
+
}),
|
|
35
|
+
/*#__PURE__*/ jsx(ClearButton, {
|
|
36
|
+
onClick: handleClearQuery
|
|
37
|
+
}),
|
|
38
|
+
Boolean(suggestions?.length) && !hideSuggestionList && /*#__PURE__*/ jsxs("div", {
|
|
39
|
+
className: "fwe-search-suggestions",
|
|
40
|
+
role: "listbox",
|
|
41
|
+
children: [
|
|
42
|
+
cappedSuggestions.map((suggestion, i)=>/*#__PURE__*/ jsx("div", {
|
|
43
|
+
role: "option",
|
|
44
|
+
tabIndex: -1,
|
|
45
|
+
"aria-label": suggestion.value,
|
|
46
|
+
"aria-selected": selectedSuggestionIndex === i,
|
|
47
|
+
onClick: ()=>handleSuggestionClick(suggestion),
|
|
48
|
+
className: `fwe-search-suggestion ${selectedSuggestionIndex === i ? 'fwe-selected' : ''}`,
|
|
49
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
50
|
+
dangerouslySetInnerHTML: {
|
|
51
|
+
__html: suggestion.template
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
}, suggestion.value)),
|
|
55
|
+
suggestions && suggestions.length > 10 && /*#__PURE__*/ jsx("div", {
|
|
56
|
+
className: "fwe-ml-xxs",
|
|
57
|
+
children: "..."
|
|
58
|
+
})
|
|
59
|
+
]
|
|
60
|
+
})
|
|
61
|
+
]
|
|
86
62
|
});
|
|
87
63
|
});
|
|
88
64
|
SearchInput.displayName = 'SearchInput';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class SearchSuggestion {
|
|
2
|
+
/**
|
|
3
|
+
* a html-string. e.g.: '<b> hello </b>'
|
|
4
|
+
*/
|
|
5
|
+
template: string;
|
|
6
|
+
/**
|
|
7
|
+
* This Value will be used as new query when the user selects the suggestion.
|
|
8
|
+
*/
|
|
9
|
+
value: string;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a basic Suggestion from a string. The first query match is highlighted by bold tags.
|
|
12
|
+
* @param suggestionString The suggested string (should contain the whole query)
|
|
13
|
+
* @param query The current query. This string will be highlighted.
|
|
14
|
+
* @returns a html-string.
|
|
15
|
+
*/
|
|
16
|
+
static basicSuggestion(suggestionString: string, query: string): SearchSuggestion;
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class SearchSuggestion {
|
|
2
|
+
template;
|
|
3
|
+
value;
|
|
4
|
+
static basicSuggestion(suggestionString, query) {
|
|
5
|
+
const i = suggestionString.toLocaleLowerCase().indexOf(query.toLocaleLowerCase());
|
|
6
|
+
let template = suggestionString;
|
|
7
|
+
if (-1 !== i) {
|
|
8
|
+
const boldStart = i;
|
|
9
|
+
const boldEnd = i + query.length;
|
|
10
|
+
const part1 = suggestionString.substring(0, boldStart);
|
|
11
|
+
const part2 = suggestionString.substring(boldStart, boldEnd);
|
|
12
|
+
const part3 = suggestionString.substring(boldEnd, suggestionString.length);
|
|
13
|
+
template = `${part1}<strong>${part2}</strong>${part3}`;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
value: suggestionString,
|
|
17
|
+
template
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export { SearchSuggestion };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { SearchSuggestion } from './SearchSuggestion';
|
|
3
|
+
export declare function useSearchInput(inputRef: React.RefObject<HTMLInputElement | null>, cappedSuggestions: SearchSuggestion[], value?: string, defaultValue?: string, onChange?: (value: string) => void, onSearch?: (value: string) => void, onKeyboardNavigate?: (value: string) => void): {
|
|
4
|
+
innerValue: string | undefined;
|
|
5
|
+
hideSuggestionList: boolean;
|
|
6
|
+
selectedSuggestionIndex: number;
|
|
7
|
+
handleClearQuery: () => void;
|
|
8
|
+
handleFocus: () => void;
|
|
9
|
+
handleInput: (event: any) => void;
|
|
10
|
+
handleSuggestionClick: (suggestion: SearchSuggestion) => void;
|
|
11
|
+
handleOutsideClick: () => void;
|
|
12
|
+
handleKeyDown: (event: React.KeyboardEvent) => void;
|
|
13
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { useControlled } from "../../utils/useControlled.js";
|
|
3
|
+
function useSearchInput(inputRef, cappedSuggestions, value, defaultValue = '', onChange, onSearch, onKeyboardNavigate) {
|
|
4
|
+
const [innerValue, setValue] = useControlled({
|
|
5
|
+
controlled: value,
|
|
6
|
+
default: defaultValue
|
|
7
|
+
});
|
|
8
|
+
const [hideSuggestionList, setHideSuggestionList] = useState(false);
|
|
9
|
+
const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(-1);
|
|
10
|
+
function blurInput() {
|
|
11
|
+
if (inputRef.current) inputRef.current.blur();
|
|
12
|
+
}
|
|
13
|
+
function reset() {
|
|
14
|
+
setSelectedSuggestionIndex(-1);
|
|
15
|
+
setHideSuggestionList(true);
|
|
16
|
+
blurInput();
|
|
17
|
+
}
|
|
18
|
+
function handleSearch() {
|
|
19
|
+
reset();
|
|
20
|
+
if (void 0 !== innerValue) onSearch?.(innerValue);
|
|
21
|
+
}
|
|
22
|
+
function updateValue(newValue) {
|
|
23
|
+
setValue(newValue);
|
|
24
|
+
onChange?.(newValue);
|
|
25
|
+
onSearch?.(newValue);
|
|
26
|
+
}
|
|
27
|
+
function handleClearQuery() {
|
|
28
|
+
reset();
|
|
29
|
+
updateValue('');
|
|
30
|
+
}
|
|
31
|
+
function handleArrowKey(newSuggestionIndex) {
|
|
32
|
+
if (!cappedSuggestions || !cappedSuggestions.length) return;
|
|
33
|
+
const selectedSuggestion = cappedSuggestions[newSuggestionIndex];
|
|
34
|
+
setSelectedSuggestionIndex(newSuggestionIndex);
|
|
35
|
+
setValue(selectedSuggestion.value);
|
|
36
|
+
onKeyboardNavigate?.(selectedSuggestion.value);
|
|
37
|
+
}
|
|
38
|
+
function handleUpArrowKey() {
|
|
39
|
+
handleArrowKey(selectedSuggestionIndex > 0 ? selectedSuggestionIndex - 1 : cappedSuggestions.length - 1);
|
|
40
|
+
}
|
|
41
|
+
function handleDownArrowKey() {
|
|
42
|
+
handleArrowKey(selectedSuggestionIndex >= cappedSuggestions.length - 1 ? 0 : selectedSuggestionIndex + 1);
|
|
43
|
+
}
|
|
44
|
+
function handleKeyDown(event) {
|
|
45
|
+
switch(event.key){
|
|
46
|
+
case 'Enter':
|
|
47
|
+
handleSearch();
|
|
48
|
+
break;
|
|
49
|
+
case 'Escape':
|
|
50
|
+
handleClearQuery();
|
|
51
|
+
break;
|
|
52
|
+
case 'ArrowUp':
|
|
53
|
+
handleUpArrowKey();
|
|
54
|
+
break;
|
|
55
|
+
case 'ArrowDown':
|
|
56
|
+
handleDownArrowKey();
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const handleFocus = ()=>setHideSuggestionList(false);
|
|
63
|
+
const handleOutsideClick = ()=>setHideSuggestionList(true);
|
|
64
|
+
function handleSuggestionClick(suggestion) {
|
|
65
|
+
reset();
|
|
66
|
+
updateValue(suggestion.value);
|
|
67
|
+
}
|
|
68
|
+
function handleInput(event) {
|
|
69
|
+
setSelectedSuggestionIndex(-1);
|
|
70
|
+
setValue(event.target.value);
|
|
71
|
+
onChange?.(event.target.value);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
innerValue,
|
|
75
|
+
hideSuggestionList,
|
|
76
|
+
selectedSuggestionIndex,
|
|
77
|
+
handleClearQuery,
|
|
78
|
+
handleFocus,
|
|
79
|
+
handleInput,
|
|
80
|
+
handleSuggestionClick,
|
|
81
|
+
handleOutsideClick,
|
|
82
|
+
handleKeyDown
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export { useSearchInput };
|
package/dist/index.d.ts
CHANGED
|
@@ -34,8 +34,7 @@ export { PopoverMenuItem, type PopoverMenuItemProps, } from './components/popove
|
|
|
34
34
|
export { Tooltip, type TooltipProps, } from './components/popovers/tooltip/Tooltip';
|
|
35
35
|
export { Progress, type ProgressProps } from './components/progress/Progress';
|
|
36
36
|
export { SearchInput, type SearchInputProps, } from './components/search-input/SearchInput';
|
|
37
|
-
export {
|
|
38
|
-
export { SearchResult, type SearchResultProps, } from './components/search-input/SearchResult';
|
|
37
|
+
export { SearchSuggestion } from './components/search-input/SearchSuggestion';
|
|
39
38
|
export { Snackbar, type SnackbarConfig, type SnackbarData, type SnackbarProps, } from './components/snackbar/Snackbar';
|
|
40
39
|
export { addSnackbar, SnackbarProvider, type SnackbarProviderProps, } from './components/snackbar/SnackbarProvider';
|
|
41
40
|
export { useSnackbar } from './components/snackbar/useSnackbar';
|
package/dist/index.js
CHANGED
|
@@ -33,8 +33,7 @@ import { PopoverMenuItem } from "./components/popovers/popover-menu/popover-menu
|
|
|
33
33
|
import { Tooltip } from "./components/popovers/tooltip/Tooltip.js";
|
|
34
34
|
import { Progress } from "./components/progress/Progress.js";
|
|
35
35
|
import { SearchInput } from "./components/search-input/SearchInput.js";
|
|
36
|
-
import {
|
|
37
|
-
import { SearchResult } from "./components/search-input/SearchResult.js";
|
|
36
|
+
import { SearchSuggestion } from "./components/search-input/SearchSuggestion.js";
|
|
38
37
|
import { Snackbar } from "./components/snackbar/Snackbar.js";
|
|
39
38
|
import { SnackbarProvider, addSnackbar } from "./components/snackbar/SnackbarProvider.js";
|
|
40
39
|
import { useSnackbar } from "./components/snackbar/useSnackbar.js";
|
|
@@ -58,4 +57,4 @@ import { Switch } from "./forms/switch/Switch.js";
|
|
|
58
57
|
import { TextArea } from "./forms/text-area/TextArea.js";
|
|
59
58
|
import { TextInput } from "./forms/text-input/TextInput.js";
|
|
60
59
|
import { TimePicker } from "./forms/time-picker/TimePicker.js";
|
|
61
|
-
export { Accordion, AccordionHeader, AccordionItem, AccordionItemBody, AccordionItemHeader, AlertModal, BottomSheet, Breadcrumb, Button, Card, CardBody, CardHeader, CardNotification, Checkbox, Chip, ChipContainer, ChipType, ComboBox, ConfirmModal, CustomModal, ImageGallery, ImageGalleryContent, ImageGallerySwiper, ImageGalleryThumbsSwiper, Legend, LoadingIndicator, MobileFlyout, MobileFlyoutItem, MobileFlyoutPage, MultiSelect, Pagination, Popover, PopoverMenu, PopoverMenuContext, PopoverMenuItem, Progress, Prompt, RadioButton, RadioGroup, SearchInput,
|
|
60
|
+
export { Accordion, AccordionHeader, AccordionItem, AccordionItemBody, AccordionItemHeader, AlertModal, BottomSheet, Breadcrumb, Button, Card, CardBody, CardHeader, CardNotification, Checkbox, Chip, ChipContainer, ChipType, ComboBox, ConfirmModal, CustomModal, ImageGallery, ImageGalleryContent, ImageGallerySwiper, ImageGalleryThumbsSwiper, Legend, LoadingIndicator, MobileFlyout, MobileFlyoutItem, MobileFlyoutPage, MultiSelect, Pagination, Popover, PopoverMenu, PopoverMenuContext, PopoverMenuItem, Progress, Prompt, RadioButton, RadioGroup, SearchInput, SearchSuggestion, Segment, SegmentControl, Select, Slider, Snackbar, SnackbarProvider, StepHorizontal, StepVertical, StepperHorizontal, StepperVertical, Switch, TabPane, TableHeaderCell, Tabs, TextArea, TextInput, TimePicker, Tooltip, addSnackbar, useSnackbar };
|
package/package.json
CHANGED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type ComboboxOptionProps } from '@headlessui/react';
|
|
2
|
-
export interface SearchInputOptionProps extends Omit<ComboboxOptionProps, 'as'> {
|
|
3
|
-
readonly value: string;
|
|
4
|
-
}
|
|
5
|
-
export declare const SearchInputOption: (props: SearchInputOptionProps & import("react").RefAttributes<HTMLDivElement>) => React.ReactElement | null;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { ComboboxOption } from "@headlessui/react";
|
|
3
|
-
import classnames from "classnames";
|
|
4
|
-
import { forwardRef } from "react";
|
|
5
|
-
function SearchInputOptionComponent({ children, className, ...props }, ref) {
|
|
6
|
-
return /*#__PURE__*/ jsx(ComboboxOption, {
|
|
7
|
-
ref: ref,
|
|
8
|
-
as: "div",
|
|
9
|
-
className: ({ focus, selected })=>classnames('fwe-search-suggestion', className, {
|
|
10
|
-
'fwe-selected': focus || selected
|
|
11
|
-
}),
|
|
12
|
-
...props,
|
|
13
|
-
children: children
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
const SearchInputOption = /*#__PURE__*/ forwardRef(SearchInputOptionComponent);
|
|
17
|
-
SearchInputOption.displayName = 'SearchInputOption';
|
|
18
|
-
export { SearchInputOption };
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ComponentPropsWithoutRef } from 'react';
|
|
2
|
-
export interface SearchResultProps extends ComponentPropsWithoutRef<'span'> {
|
|
3
|
-
/** The full label text to display. */
|
|
4
|
-
readonly label: string;
|
|
5
|
-
/** The current search query — matching parts will be highlighted. */
|
|
6
|
-
readonly query?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare const SearchResult: (props: SearchResultProps & import("react").RefAttributes<HTMLSpanElement>) => React.ReactElement | null;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import classnames from "classnames";
|
|
3
|
-
import { forwardRef } from "react";
|
|
4
|
-
function getHighlightedParts(label, query) {
|
|
5
|
-
if (!query) return [
|
|
6
|
-
{
|
|
7
|
-
text: label,
|
|
8
|
-
highlighted: false
|
|
9
|
-
}
|
|
10
|
-
];
|
|
11
|
-
const parts = [];
|
|
12
|
-
const lowerLabel = label.toLowerCase();
|
|
13
|
-
const lowerQuery = query.toLowerCase();
|
|
14
|
-
let currentIndex = 0;
|
|
15
|
-
while(currentIndex < label.length){
|
|
16
|
-
const matchIndex = lowerLabel.indexOf(lowerQuery, currentIndex);
|
|
17
|
-
if (-1 === matchIndex) {
|
|
18
|
-
parts.push({
|
|
19
|
-
text: label.slice(currentIndex),
|
|
20
|
-
highlighted: false
|
|
21
|
-
});
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
if (matchIndex > currentIndex) parts.push({
|
|
25
|
-
text: label.slice(currentIndex, matchIndex),
|
|
26
|
-
highlighted: false
|
|
27
|
-
});
|
|
28
|
-
parts.push({
|
|
29
|
-
text: label.slice(matchIndex, matchIndex + query.length),
|
|
30
|
-
highlighted: true
|
|
31
|
-
});
|
|
32
|
-
currentIndex = matchIndex + query.length;
|
|
33
|
-
}
|
|
34
|
-
return parts;
|
|
35
|
-
}
|
|
36
|
-
const SearchResult = /*#__PURE__*/ forwardRef(({ label, query = '', className, ...props }, ref)=>/*#__PURE__*/ jsx("span", {
|
|
37
|
-
ref: ref,
|
|
38
|
-
className: classnames('fr-search-result', className),
|
|
39
|
-
...props,
|
|
40
|
-
children: getHighlightedParts(label, query).map((part, index)=>/*#__PURE__*/ jsx("span", {
|
|
41
|
-
className: classnames({
|
|
42
|
-
'fr-search-result-highlight': part.highlighted
|
|
43
|
-
}),
|
|
44
|
-
children: part.text
|
|
45
|
-
}, `${part.text}-${index}`))
|
|
46
|
-
}));
|
|
47
|
-
SearchResult.displayName = 'SearchResult';
|
|
48
|
-
export { SearchResult };
|