@etoile-dev/react 0.2.1 → 0.2.2
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/SearchInput.d.ts +4 -2
- package/dist/components/SearchInput.js +13 -5
- package/dist/components/SearchResult.d.ts +3 -2
- package/dist/components/SearchResult.js +3 -2
- package/dist/components/SearchResultThumbnail.d.ts +4 -2
- package/dist/components/SearchResultThumbnail.js +3 -2
- package/dist/components/SearchResults.d.ts +3 -2
- package/dist/components/SearchResults.js +3 -2
- package/package.json +1 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import * as React from "react";
|
|
1
2
|
export type SearchInputProps = {
|
|
2
3
|
/** Placeholder text for the input field */
|
|
3
4
|
placeholder?: string;
|
|
4
5
|
/** CSS class name for styling the input */
|
|
5
6
|
className?: string;
|
|
6
|
-
}
|
|
7
|
+
} & React.InputHTMLAttributes<HTMLInputElement>;
|
|
7
8
|
/**
|
|
8
9
|
* Search input component with built-in keyboard navigation and accessibility.
|
|
9
10
|
*
|
|
10
11
|
* Integrates with SearchRoot context to provide debouncing and keyboard controls
|
|
11
12
|
* (ArrowUp, ArrowDown, Enter, Escape). Implements ARIA combobox pattern.
|
|
13
|
+
* Accepts standard input props like aria-label and autoComplete.
|
|
12
14
|
*
|
|
13
15
|
* @param props - Component props
|
|
14
16
|
*
|
|
@@ -25,4 +27,4 @@ export type SearchInputProps = {
|
|
|
25
27
|
* />
|
|
26
28
|
* ```
|
|
27
29
|
*/
|
|
28
|
-
export declare const SearchInput: ({ placeholder, className }: SearchInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare const SearchInput: ({ placeholder, className, ...props }: SearchInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,6 +5,7 @@ import { useSearchContext } from "../context/SearchContext.js";
|
|
|
5
5
|
*
|
|
6
6
|
* Integrates with SearchRoot context to provide debouncing and keyboard controls
|
|
7
7
|
* (ArrowUp, ArrowDown, Enter, Escape). Implements ARIA combobox pattern.
|
|
8
|
+
* Accepts standard input props like aria-label and autoComplete.
|
|
8
9
|
*
|
|
9
10
|
* @param props - Component props
|
|
10
11
|
*
|
|
@@ -21,21 +22,28 @@ import { useSearchContext } from "../context/SearchContext.js";
|
|
|
21
22
|
* />
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
24
|
-
export const SearchInput = ({ placeholder, className }) => {
|
|
25
|
+
export const SearchInput = ({ placeholder, className, ...props }) => {
|
|
25
26
|
const { query, setQuery, results, isOpen, setOpen, selectedIndex, setSelectedIndex, listboxId, getResultId, handleKeyDown, autoFocus, } = useSearchContext();
|
|
26
27
|
const showResults = isOpen && results.length > 0;
|
|
27
28
|
const activeId = selectedIndex >= 0 && showResults ? getResultId(selectedIndex) : undefined;
|
|
28
|
-
return (_jsxs(_Fragment, { children: [_jsx("input", { type: "text", placeholder: placeholder, className: className, value: query, autoFocus: autoFocus, role: "combobox", "aria-expanded": showResults, "aria-controls": listboxId, "aria-activedescendant": activeId, "aria-autocomplete": "list", onChange: (event) => {
|
|
29
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { ...props, type: "text", placeholder: placeholder, className: className, value: query, autoFocus: autoFocus, role: "combobox", "aria-expanded": showResults, "aria-controls": listboxId, "aria-activedescendant": activeId, "aria-autocomplete": "list", onChange: (event) => {
|
|
30
|
+
props.onChange?.(event);
|
|
29
31
|
const nextValue = event.target.value;
|
|
30
32
|
setQuery(nextValue);
|
|
31
33
|
if (nextValue.trim() !== "") {
|
|
32
34
|
setSelectedIndex(0);
|
|
33
35
|
}
|
|
34
|
-
}, onFocus: () => {
|
|
35
|
-
|
|
36
|
+
}, onFocus: (event) => {
|
|
37
|
+
props.onFocus?.(event);
|
|
38
|
+
if (!event.defaultPrevented && query.trim() !== "" && results.length > 0) {
|
|
36
39
|
setOpen(true);
|
|
37
40
|
}
|
|
38
|
-
}, onKeyDown:
|
|
41
|
+
}, onKeyDown: (event) => {
|
|
42
|
+
props.onKeyDown?.(event);
|
|
43
|
+
if (!event.defaultPrevented) {
|
|
44
|
+
handleKeyDown(event);
|
|
45
|
+
}
|
|
46
|
+
} }), _jsx("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", style: {
|
|
39
47
|
position: "absolute",
|
|
40
48
|
width: 1,
|
|
41
49
|
height: 1,
|
|
@@ -4,12 +4,13 @@ export type SearchResultProps = {
|
|
|
4
4
|
className?: string;
|
|
5
5
|
/** Content to render inside the result */
|
|
6
6
|
children: React.ReactNode;
|
|
7
|
-
}
|
|
7
|
+
} & React.HTMLAttributes<HTMLDivElement>;
|
|
8
8
|
/**
|
|
9
9
|
* Individual search result item with selection state and keyboard navigation.
|
|
10
10
|
*
|
|
11
11
|
* Manages selection state and accessibility attributes. Provides `data-selected`
|
|
12
12
|
* attribute for styling the active result. Must be used inside SearchResults.
|
|
13
|
+
* Accepts standard div props like onClick for custom behavior.
|
|
13
14
|
*
|
|
14
15
|
* @param props - Component props
|
|
15
16
|
*
|
|
@@ -27,4 +28,4 @@ export type SearchResultProps = {
|
|
|
27
28
|
* // CSS: .result-item[data-selected="true"] { background: #f0f9ff; }
|
|
28
29
|
* ```
|
|
29
30
|
*/
|
|
30
|
-
export declare const SearchResult: ({ className, children }: SearchResultProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
31
|
+
export declare const SearchResult: ({ className, children, ...props }: SearchResultProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -7,6 +7,7 @@ import { SearchResultIndexContext } from "./SearchResults.js";
|
|
|
7
7
|
*
|
|
8
8
|
* Manages selection state and accessibility attributes. Provides `data-selected`
|
|
9
9
|
* attribute for styling the active result. Must be used inside SearchResults.
|
|
10
|
+
* Accepts standard div props like onClick for custom behavior.
|
|
10
11
|
*
|
|
11
12
|
* @param props - Component props
|
|
12
13
|
*
|
|
@@ -24,7 +25,7 @@ import { SearchResultIndexContext } from "./SearchResults.js";
|
|
|
24
25
|
* // CSS: .result-item[data-selected="true"] { background: #f0f9ff; }
|
|
25
26
|
* ```
|
|
26
27
|
*/
|
|
27
|
-
export const SearchResult = ({ className, children }) => {
|
|
28
|
+
export const SearchResult = ({ className, children, ...props }) => {
|
|
28
29
|
const { selectedIndex, registerResult, getResultId } = useSearchContext();
|
|
29
30
|
const index = React.useContext(SearchResultIndexContext);
|
|
30
31
|
if (index === null) {
|
|
@@ -35,5 +36,5 @@ export const SearchResult = ({ className, children }) => {
|
|
|
35
36
|
const setRef = React.useCallback((node) => {
|
|
36
37
|
registerResult(index, node);
|
|
37
38
|
}, [index, registerResult]);
|
|
38
|
-
return (_jsx("div", { ref: setRef, id: id, role: "option", "aria-selected": isSelected, "data-selected": isSelected ? "true" : "false", "data-index": index, tabIndex: isSelected ? 0 : -1, className: className, children: children }));
|
|
39
|
+
return (_jsx("div", { ...props, ref: setRef, id: id, role: "option", "aria-selected": isSelected, "data-selected": isSelected ? "true" : "false", "data-index": index, tabIndex: isSelected ? 0 : -1, className: className, children: children }));
|
|
39
40
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as React from "react";
|
|
1
2
|
export type SearchResultThumbnailProps = {
|
|
2
3
|
/** Image source URL (defaults to result.metadata.thumbnailUrl) */
|
|
3
4
|
src?: string;
|
|
@@ -7,12 +8,13 @@ export type SearchResultThumbnailProps = {
|
|
|
7
8
|
size?: number;
|
|
8
9
|
/** CSS class name for styling */
|
|
9
10
|
className?: string;
|
|
10
|
-
}
|
|
11
|
+
} & React.ImgHTMLAttributes<HTMLImageElement>;
|
|
11
12
|
/**
|
|
12
13
|
* Thumbnail image for search results with automatic source detection.
|
|
13
14
|
*
|
|
14
15
|
* Automatically uses `metadata.thumbnailUrl` if available. Returns null
|
|
15
16
|
* if no image source is found. Must be used inside SearchResults.
|
|
17
|
+
* Accepts standard img props like loading and decoding.
|
|
16
18
|
*
|
|
17
19
|
* @param props - Component props
|
|
18
20
|
*
|
|
@@ -33,4 +35,4 @@ export type SearchResultThumbnailProps = {
|
|
|
33
35
|
* <SearchResultThumbnail size={48} className="rounded-full" />
|
|
34
36
|
* ```
|
|
35
37
|
*/
|
|
36
|
-
export declare const SearchResultThumbnail: ({ src, alt, size, className, }: SearchResultThumbnailProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
38
|
+
export declare const SearchResultThumbnail: ({ src, alt, size, className, ...props }: SearchResultThumbnailProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -6,6 +6,7 @@ import { SearchResultDataContext } from "./SearchResults.js";
|
|
|
6
6
|
*
|
|
7
7
|
* Automatically uses `metadata.thumbnailUrl` if available. Returns null
|
|
8
8
|
* if no image source is found. Must be used inside SearchResults.
|
|
9
|
+
* Accepts standard img props like loading and decoding.
|
|
9
10
|
*
|
|
10
11
|
* @param props - Component props
|
|
11
12
|
*
|
|
@@ -26,12 +27,12 @@ import { SearchResultDataContext } from "./SearchResults.js";
|
|
|
26
27
|
* <SearchResultThumbnail size={48} className="rounded-full" />
|
|
27
28
|
* ```
|
|
28
29
|
*/
|
|
29
|
-
export const SearchResultThumbnail = ({ src, alt, size = 40, className, }) => {
|
|
30
|
+
export const SearchResultThumbnail = ({ src, alt, size = 40, className, ...props }) => {
|
|
30
31
|
const result = React.useContext(SearchResultDataContext);
|
|
31
32
|
const imageSrc = src ?? result?.metadata?.thumbnailUrl;
|
|
32
33
|
const imageAlt = alt ?? result?.title ?? "";
|
|
33
34
|
if (!imageSrc) {
|
|
34
35
|
return null;
|
|
35
36
|
}
|
|
36
|
-
return (_jsx("img", { src: imageSrc, alt: imageAlt, width: size, height: size, className: className, draggable: false }));
|
|
37
|
+
return (_jsx("img", { ...props, src: imageSrc, alt: imageAlt, width: size, height: size, className: className, draggable: false }));
|
|
37
38
|
};
|
|
@@ -5,7 +5,7 @@ export type SearchResultsProps = {
|
|
|
5
5
|
className?: string;
|
|
6
6
|
/** Render function that receives each search result */
|
|
7
7
|
children: (result: SearchResultData) => React.ReactNode;
|
|
8
|
-
}
|
|
8
|
+
} & Omit<React.HTMLAttributes<HTMLDivElement>, "children">;
|
|
9
9
|
export declare const SearchResultIndexContext: React.Context<number | null>;
|
|
10
10
|
export declare const SearchResultDataContext: React.Context<SearchResultData | null>;
|
|
11
11
|
/**
|
|
@@ -13,6 +13,7 @@ export declare const SearchResultDataContext: React.Context<SearchResultData | n
|
|
|
13
13
|
*
|
|
14
14
|
* Accepts a render function that receives each result. Automatically hides
|
|
15
15
|
* when query is empty or no results found. Includes ARIA listbox role.
|
|
16
|
+
* Accepts standard div props like onScroll and style.
|
|
16
17
|
*
|
|
17
18
|
* @param props - Component props
|
|
18
19
|
*
|
|
@@ -35,4 +36,4 @@ export declare const SearchResultDataContext: React.Context<SearchResultData | n
|
|
|
35
36
|
* </SearchResults>
|
|
36
37
|
* ```
|
|
37
38
|
*/
|
|
38
|
-
export declare const SearchResults: ({ className, children }: SearchResultsProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
39
|
+
export declare const SearchResults: ({ className, children, ...props }: SearchResultsProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -8,6 +8,7 @@ export const SearchResultDataContext = React.createContext(null);
|
|
|
8
8
|
*
|
|
9
9
|
* Accepts a render function that receives each result. Automatically hides
|
|
10
10
|
* when query is empty or no results found. Includes ARIA listbox role.
|
|
11
|
+
* Accepts standard div props like onScroll and style.
|
|
11
12
|
*
|
|
12
13
|
* @param props - Component props
|
|
13
14
|
*
|
|
@@ -30,7 +31,7 @@ export const SearchResultDataContext = React.createContext(null);
|
|
|
30
31
|
* </SearchResults>
|
|
31
32
|
* ```
|
|
32
33
|
*/
|
|
33
|
-
export const SearchResults = ({ className, children }) => {
|
|
34
|
+
export const SearchResults = ({ className, children, ...props }) => {
|
|
34
35
|
const { query, results, isOpen, selectedIndex, listboxId, getResultNode } = useSearchContext();
|
|
35
36
|
const listboxRef = React.useRef(null);
|
|
36
37
|
React.useEffect(() => {
|
|
@@ -48,5 +49,5 @@ export const SearchResults = ({ className, children }) => {
|
|
|
48
49
|
if (!isOpen || query.trim() === "" || results.length === 0) {
|
|
49
50
|
return null;
|
|
50
51
|
}
|
|
51
|
-
return (_jsx("div", { role: "listbox", id: listboxId, className: className, ref: listboxRef, children: results.map((result, index) => (_jsx(SearchResultIndexContext.Provider, { value: index, children: _jsx(SearchResultDataContext.Provider, { value: result, children: children(result) }) }, result.external_id))) }));
|
|
52
|
+
return (_jsx("div", { ...props, role: "listbox", id: listboxId, className: className, ref: listboxRef, children: results.map((result, index) => (_jsx(SearchResultIndexContext.Provider, { value: index, children: _jsx(SearchResultDataContext.Provider, { value: result, children: children(result) }) }, result.external_id))) }));
|
|
52
53
|
};
|