@gooddata/sdk-ui-semantic-search 10.38.0 → 10.39.0-alpha.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/esm/FooterButtonAiAssistant.d.ts +1 -1
- package/esm/FooterButtonAiAssistant.d.ts.map +1 -1
- package/esm/FooterButtonAiAssistant.js +6 -6
- package/esm/FooterButtonAiAssistant.js.map +1 -1
- package/esm/SearchItem.d.ts +5 -2
- package/esm/SearchItem.d.ts.map +1 -1
- package/esm/SearchItem.js +3 -2
- package/esm/SearchItem.js.map +1 -1
- package/esm/SemanticSearch.d.ts +7 -3
- package/esm/SemanticSearch.d.ts.map +1 -1
- package/esm/SemanticSearch.js +73 -58
- package/esm/SemanticSearch.js.map +1 -1
- package/esm/SemanticSearchItem.d.ts.map +1 -1
- package/esm/SemanticSearchItem.js +5 -2
- package/esm/SemanticSearchItem.js.map +1 -1
- package/esm/SemanticSearchTreeView.d.ts +22 -0
- package/esm/SemanticSearchTreeView.d.ts.map +1 -0
- package/esm/SemanticSearchTreeView.js +65 -0
- package/esm/SemanticSearchTreeView.js.map +1 -0
- package/esm/hooks/index.d.ts +2 -2
- package/esm/hooks/index.d.ts.map +1 -1
- package/esm/hooks/index.js +2 -2
- package/esm/hooks/index.js.map +1 -1
- package/esm/hooks/usSearchKeyboard.d.ts +7 -0
- package/esm/hooks/usSearchKeyboard.d.ts.map +1 -0
- package/esm/hooks/usSearchKeyboard.js +19 -0
- package/esm/hooks/usSearchKeyboard.js.map +1 -0
- package/esm/hooks/useSearchIds.d.ts +9 -0
- package/esm/hooks/useSearchIds.d.ts.map +1 -0
- package/esm/hooks/useSearchIds.js +13 -0
- package/esm/hooks/useSearchIds.js.map +1 -0
- package/esm/hooks/useSemanticSearch.d.ts +4 -0
- package/esm/hooks/useSemanticSearch.d.ts.map +1 -1
- package/esm/hooks/useSemanticSearch.js +4 -1
- package/esm/hooks/useSemanticSearch.js.map +1 -1
- package/esm/internal/GroupResultCounter.js +1 -1
- package/esm/internal/GroupResultCounter.js.map +1 -1
- package/esm/internal/HistorySearchTreeView.d.ts +3 -1
- package/esm/internal/HistorySearchTreeView.d.ts.map +1 -1
- package/esm/internal/HistorySearchTreeView.js +6 -5
- package/esm/internal/HistorySearchTreeView.js.map +1 -1
- package/esm/internal/HistorySearchTreeViewItem.d.ts.map +1 -1
- package/esm/internal/HistorySearchTreeViewItem.js +6 -3
- package/esm/internal/HistorySearchTreeViewItem.js.map +1 -1
- package/esm/internal/LeveledSearchTreeView.d.ts +4 -1
- package/esm/internal/LeveledSearchTreeView.d.ts.map +1 -1
- package/esm/internal/LeveledSearchTreeView.js +14 -5
- package/esm/internal/LeveledSearchTreeView.js.map +1 -1
- package/esm/internal/LeveledSearchTreeViewItem.d.ts.map +1 -1
- package/esm/internal/LeveledSearchTreeViewItem.js +7 -4
- package/esm/internal/LeveledSearchTreeViewItem.js.map +1 -1
- package/esm/internal/SearchItemDetails.d.ts.map +1 -1
- package/esm/internal/SearchItemDetails.js +1 -1
- package/esm/internal/SearchItemDetails.js.map +1 -1
- package/esm/internal/SearchOverlay.d.ts +12 -0
- package/esm/internal/SearchOverlay.d.ts.map +1 -1
- package/esm/internal/SearchOverlay.js +46 -31
- package/esm/internal/SearchOverlay.js.map +1 -1
- package/esm/localization/bundles/en-US.json +2 -2
- package/esm/localization/bundles/en-US.localization-bundle.js +1 -1
- package/esm/localization/bundles/en-US.localization-bundle.js.map +1 -1
- package/esm/permissions/PermissionsContext.d.ts +13 -0
- package/esm/permissions/PermissionsContext.d.ts.map +1 -0
- package/esm/permissions/PermissionsContext.js +14 -0
- package/esm/permissions/PermissionsContext.js.map +1 -0
- package/esm/permissions/index.d.ts +4 -0
- package/esm/permissions/index.d.ts.map +1 -0
- package/esm/permissions/index.js +5 -0
- package/esm/permissions/index.js.map +1 -0
- package/esm/permissions/usePermissions.d.ts +6 -0
- package/esm/permissions/usePermissions.d.ts.map +1 -0
- package/esm/permissions/usePermissions.js +6 -0
- package/esm/permissions/usePermissions.js.map +1 -0
- package/esm/permissions/useWorkspacePermissions.d.ts +8 -0
- package/esm/permissions/useWorkspacePermissions.d.ts.map +1 -0
- package/esm/permissions/useWorkspacePermissions.js +16 -0
- package/esm/permissions/useWorkspacePermissions.js.map +1 -0
- package/esm/permissions/utils.d.ts +3 -0
- package/esm/permissions/utils.d.ts.map +1 -0
- package/esm/permissions/utils.js +4 -0
- package/esm/permissions/utils.js.map +1 -0
- package/esm/sdk-ui-semantic-search.d.ts +10 -2
- package/esm/utils/getAriaLabel.js +1 -1
- package/package.json +9 -9
- package/styles/css/internal.css +11 -31
- package/styles/css/internal.css.map +1 -1
- package/styles/css/main.css +11 -28
- package/styles/css/main.css.map +1 -1
- package/styles/scss/internal.scss +0 -6
- package/styles/scss/main.scss +15 -33
- package/esm/hooks/useListScroll.d.ts +0 -2
- package/esm/hooks/useListScroll.d.ts.map +0 -1
- package/esm/hooks/useListScroll.js +0 -29
- package/esm/hooks/useListScroll.js.map +0 -1
- package/esm/hooks/useListSelector.d.ts +0 -7
- package/esm/hooks/useListSelector.d.ts.map +0 -1
- package/esm/hooks/useListSelector.js +0 -47
- package/esm/hooks/useListSelector.js.map +0 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FooterButtonAiAssistant.d.ts","sourceRoot":"","sources":["../src/FooterButtonAiAssistant.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
1
|
+
{"version":3,"file":"FooterButtonAiAssistant.d.ts","sourceRoot":"","sources":["../src/FooterButtonAiAssistant.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IACzC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC3C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,OAAO,EAAE,EAAE,4BAA4B,qBAgBhF"}
|
@@ -1,15 +1,15 @@
|
|
1
1
|
// (C) 2025 GoodData Corporation
|
2
|
-
import
|
3
|
-
import {
|
2
|
+
import React from "react";
|
3
|
+
import { UiButton } from "@gooddata/sdk-ui-kit";
|
4
4
|
import { useIntl } from "react-intl";
|
5
5
|
/**
|
6
6
|
* @public
|
7
7
|
*/
|
8
8
|
export function FooterButtonAiAssistant({ onClick }) {
|
9
9
|
const intl = useIntl();
|
10
|
-
return (React.createElement("
|
11
|
-
React.createElement(
|
12
|
-
|
13
|
-
|
10
|
+
return (React.createElement("div", { className: "gd-semantic-search__ai_assistant_button" },
|
11
|
+
React.createElement(UiButton, { label: intl.formatMessage({ id: "semantic-search.ask.ai.assistant" }), variant: "tertiary", iconBefore: "genai2", onClick: onClick, accessibilityConfig: {
|
12
|
+
iconAriaHidden: true,
|
13
|
+
} })));
|
14
14
|
}
|
15
15
|
//# sourceMappingURL=FooterButtonAiAssistant.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FooterButtonAiAssistant.js","sourceRoot":"","sources":["../src/FooterButtonAiAssistant.tsx"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,KAAK,
|
1
|
+
{"version":3,"file":"FooterButtonAiAssistant.js","sourceRoot":"","sources":["../src/FooterButtonAiAssistant.tsx"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AASrC;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAE,OAAO,EAAgC;IAC7E,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,OAAO,CACH,6BAAK,SAAS,EAAC,yCAAyC;QACpD,oBAAC,QAAQ,IACL,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,kCAAkC,EAAE,CAAC,EACrE,OAAO,EAAC,UAAU,EAClB,UAAU,EAAC,QAAQ,EACnB,OAAO,EAAE,OAAO,EAChB,mBAAmB,EAAE;gBACjB,cAAc,EAAE,IAAI;aACvB,GACH,CACA,CACT,CAAC;AACN,CAAC"}
|
package/esm/SearchItem.d.ts
CHANGED
@@ -2,13 +2,16 @@ import React from "react";
|
|
2
2
|
export type SearchItemProps = {
|
3
3
|
className?: string;
|
4
4
|
children: React.ReactNode;
|
5
|
-
ariaLabel: string;
|
6
5
|
level: number;
|
7
6
|
icon: React.ReactNode;
|
8
7
|
details?: React.ReactNode;
|
9
8
|
resultCounter?: React.ReactNode;
|
10
9
|
href?: string;
|
11
10
|
isFocused?: boolean;
|
11
|
+
ariaAttributes: React.AriaAttributes & {
|
12
|
+
id: string;
|
13
|
+
role: React.AriaRole;
|
14
|
+
};
|
12
15
|
onClick: (event: React.MouseEvent) => void;
|
13
16
|
onHover: (event: React.MouseEvent) => void;
|
14
17
|
};
|
@@ -16,5 +19,5 @@ export type SearchItemProps = {
|
|
16
19
|
* A single result item in the search results.
|
17
20
|
* @internal
|
18
21
|
*/
|
19
|
-
export declare const SearchItem: ({ className, children,
|
22
|
+
export declare const SearchItem: ({ className, children, level, isFocused, icon, details, resultCounter, href, ariaAttributes, onClick, onHover, }: SearchItemProps) => React.JSX.Element;
|
20
23
|
//# sourceMappingURL=SearchItem.d.ts.map
|
package/esm/SearchItem.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SearchItem.d.ts","sourceRoot":"","sources":["../src/SearchItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,
|
1
|
+
{"version":3,"file":"SearchItem.d.ts","sourceRoot":"","sources":["../src/SearchItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,KAAK,CAAC,cAAc,GAAG;QACnC,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC;KACxB,CAAC;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC9C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,kHAYxB,eAAe,sBAmCjB,CAAC"}
|
package/esm/SearchItem.js
CHANGED
@@ -5,7 +5,7 @@ import classnames from "classnames";
|
|
5
5
|
* A single result item in the search results.
|
6
6
|
* @internal
|
7
7
|
*/
|
8
|
-
export const SearchItem = ({ className, children,
|
8
|
+
export const SearchItem = ({ className, children, level, isFocused, icon, details, resultCounter, href, ariaAttributes, onClick, onHover, }) => {
|
9
9
|
const handleClick = (event) => {
|
10
10
|
// Only report left and middle clicks
|
11
11
|
if (event.button < 2) {
|
@@ -13,12 +13,13 @@ export const SearchItem = ({ className, children, ariaLabel, level, isFocused, i
|
|
13
13
|
}
|
14
14
|
};
|
15
15
|
const Tag = href ? "a" : "div";
|
16
|
+
const tabIndex = href ? -1 : undefined;
|
16
17
|
const wrapperClassName = classnames(className, {
|
17
18
|
"gd-semantic-search__results-item": true,
|
18
19
|
"gd-semantic-search__results-item--active": isFocused,
|
19
20
|
});
|
20
21
|
return (React.createElement("div", { className: wrapperClassName, "data-level": level },
|
21
|
-
React.createElement(Tag, {
|
22
|
+
React.createElement(Tag, { ...ariaAttributes, href: href, tabIndex: tabIndex, className: "gd-semantic-search__results-item__content", onClick: handleClick, onAuxClick: handleClick, onMouseEnter: onHover },
|
22
23
|
React.createElement("span", { className: "gd-semantic-search__results-item__icon" }, icon),
|
23
24
|
React.createElement("span", { className: "gd-semantic-search__results-item__text" }, children),
|
24
25
|
React.createElement("div", { className: "gd-semantic-search__results-item__details-container" },
|
package/esm/SearchItem.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SearchItem.js","sourceRoot":"","sources":["../src/SearchItem.tsx"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,YAAY,CAAC;
|
1
|
+
{"version":3,"file":"SearchItem.js","sourceRoot":"","sources":["../src/SearchItem.tsx"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,YAAY,CAAC;AAmBpC;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EACvB,SAAS,EACT,QAAQ,EACR,KAAK,EACL,SAAS,EACT,IAAI,EACJ,OAAO,EACP,aAAa,EACb,IAAI,EACJ,cAAc,EACd,OAAO,EACP,OAAO,GACO,EAAE,EAAE;IAClB,MAAM,WAAW,GAAG,CAAC,KAAuB,EAAE,EAAE;QAC5C,qCAAqC;QACrC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvC,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,EAAE;QAC3C,kCAAkC,EAAE,IAAI;QACxC,0CAA0C,EAAE,SAAS;KACxD,CAAC,CAAC;IAEH,OAAO,CACH,6BAAK,SAAS,EAAE,gBAAgB,gBAAc,KAAK;QAC/C,oBAAC,GAAG,OACI,cAAc,EAClB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,2CAA2C,EACrD,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,WAAW,EACvB,YAAY,EAAE,OAAO;YAErB,8BAAM,SAAS,EAAC,wCAAwC,IAAE,IAAI,CAAQ;YACtE,8BAAM,SAAS,EAAC,wCAAwC,IAAE,QAAQ,CAAQ;YAC1E,6BAAK,SAAS,EAAC,qDAAqD;gBAC/D,CAAC,CAAC,SAAS,IAAI,KAAK,KAAK,CAAC,IAAI,OAAO;gBACrC,aAAa,CACZ,CACJ,CACJ,CACT,CAAC;AACN,CAAC,CAAC"}
|
package/esm/SemanticSearch.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import
|
2
|
-
import { GenAIObjectType, ISemanticSearchResultItem } from "@gooddata/sdk-model";
|
1
|
+
import React from "react";
|
2
|
+
import { GenAIObjectType, ISemanticSearchResultItem, type ISemanticSearchRelationship } from "@gooddata/sdk-model";
|
3
3
|
import { IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
|
4
4
|
/**
|
5
5
|
* Semantic search component props.
|
@@ -21,7 +21,7 @@ export type SemanticSearchProps = {
|
|
21
21
|
/**
|
22
22
|
* A function called when the user selects an item from the search results.
|
23
23
|
*/
|
24
|
-
onSelect: (item: ISemanticSearchResultItem) => void;
|
24
|
+
onSelect: (item: ISemanticSearchResultItem | ISemanticSearchRelationship) => void;
|
25
25
|
/**
|
26
26
|
* A function called when an error occurs during the search.
|
27
27
|
*/
|
@@ -42,6 +42,10 @@ export type SemanticSearchProps = {
|
|
42
42
|
* A limit of search results to return.
|
43
43
|
*/
|
44
44
|
limit?: number;
|
45
|
+
/**
|
46
|
+
* A minimum similarity score for search result to be shown to user.
|
47
|
+
*/
|
48
|
+
threshold?: number;
|
45
49
|
/**
|
46
50
|
* Placeholder text for the search input.
|
47
51
|
*/
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SemanticSearch.d.ts","sourceRoot":"","sources":["../src/SemanticSearch.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
1
|
+
{"version":3,"file":"SemanticSearch.d.ts","sourceRoot":"","sources":["../src/SemanticSearch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAUjF,OAAO,EACH,eAAe,EACf,yBAAyB,EACzB,KAAK,2BAA2B,EACnC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAO/D;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,yBAAyB,GAAG,2BAA2B,KAAK,IAAI,CAAC;IAClF;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,YAAY,CAAC,EAAE,CACX,KAAK,EAAE,mBAAmB,GAAG;QAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAChG,QAAQ,EAAE;QACN,WAAW,EAAE,MAAM,IAAI,CAAC;KAC3B,KACA,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC;AA+KF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAUxD,CAAC"}
|
package/esm/SemanticSearch.js
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
// (C) 2024-2025 GoodData Corporation
|
2
|
-
import
|
2
|
+
import React, { useRef, useEffect, useCallback, useState, useMemo } from "react";
|
3
3
|
import { useIntl } from "react-intl";
|
4
|
-
import { Input, Dropdown, LoadingMask,
|
5
|
-
import { useDebouncedState } from "@gooddata/sdk-ui";
|
6
|
-
import { useSemanticSearch, useElementWidth } from "./hooks/index.js";
|
4
|
+
import { Input, Dropdown, LoadingMask, UiTreeViewEventsProvider, } from "@gooddata/sdk-ui-kit";
|
5
|
+
import { useDebouncedState, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
6
|
+
import { useSemanticSearch, useElementWidth, useSearchIds } from "./hooks/index.js";
|
7
7
|
import classnames from "classnames";
|
8
8
|
import { IntlWrapper } from "./localization/IntlWrapper.js";
|
9
|
-
import {
|
9
|
+
import { SemanticSearchTreeView } from "./SemanticSearchTreeView.js";
|
10
|
+
import { useSearchKeyboard } from "./hooks/usSearchKeyboard.js";
|
11
|
+
import { PermissionsProvider, usePermissions } from "./permissions/index.js";
|
10
12
|
/**
|
11
13
|
* Search input debounce time.
|
12
14
|
* I.e. how long to wait after the user stops typing before sending the search request.
|
@@ -16,85 +18,97 @@ const DEBOUNCE = 300;
|
|
16
18
|
* Loading mask height.
|
17
19
|
*/
|
18
20
|
const LOADING_HEIGHT = 100;
|
21
|
+
/**
|
22
|
+
* A threshold for search results to be shown to user.
|
23
|
+
*/
|
24
|
+
const THRESHOLD = 0.5;
|
19
25
|
/**
|
20
26
|
* Semantic search component core.
|
21
27
|
* @beta
|
22
28
|
*/
|
23
29
|
const SemanticSearchCore = (props) => {
|
30
|
+
const { backend, workspace, onSelect, onError, objectTypes, deepSearch = false, limit = 10, threshold = THRESHOLD, className, placeholder, renderFooter, } = props;
|
24
31
|
const intl = useIntl();
|
25
|
-
const
|
32
|
+
const effectiveWorkspace = useWorkspaceStrict(workspace);
|
33
|
+
const { loading, permissions } = usePermissions();
|
26
34
|
// Input value handling
|
35
|
+
const inputRef = useRef(null);
|
27
36
|
const [value, setValue, searchTerm, setImmediate] = useDebouncedState("", DEBOUNCE);
|
28
|
-
const
|
37
|
+
const { inputId, treeViewId } = useSearchIds();
|
38
|
+
const handleKeyDown = useSearchKeyboard();
|
39
|
+
const [activeNodeId, setActiveNodeId] = useState();
|
29
40
|
// Search results
|
30
|
-
const { searchStatus, searchResults, searchError } = useSemanticSearch({
|
41
|
+
const { searchStatus, searchResults, relationships, searchMessage, searchError } = useSemanticSearch({
|
31
42
|
backend,
|
32
|
-
workspace,
|
43
|
+
workspace: effectiveWorkspace,
|
33
44
|
searchTerm,
|
34
45
|
objectTypes,
|
35
46
|
deepSearch,
|
36
47
|
limit,
|
37
48
|
});
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
// The List component requires explicit width
|
49
|
+
const inputAccessibilityConfig = useMemo(() => ({
|
50
|
+
role: "combobox",
|
51
|
+
ariaLabel: intl.formatMessage({ id: "semantic-search.label" }),
|
52
|
+
ariaControls: treeViewId,
|
53
|
+
ariaExpanded: Boolean(activeNodeId),
|
54
|
+
ariaActiveDescendant: activeNodeId,
|
55
|
+
}), [intl, activeNodeId, treeViewId]);
|
56
|
+
// The component requires explicit width
|
47
57
|
const [ref, width] = useElementWidth();
|
58
|
+
const handleValueChange = useCallback((value) => setValue(String(value)), [setValue]);
|
48
59
|
// Report errors
|
49
|
-
|
60
|
+
useEffect(() => {
|
50
61
|
if (onError && searchStatus === "error") {
|
51
62
|
onError(searchError);
|
52
63
|
}
|
53
64
|
}, [onError, searchError, searchStatus]);
|
54
|
-
const Wrapper = ({ children, status, closeSearch, }) => {
|
55
|
-
const comp = renderFooter?.({ ...props, status, value }, {
|
56
|
-
closeSearch,
|
57
|
-
});
|
58
|
-
if (comp) {
|
59
|
-
return (React.createElement("div", null,
|
60
|
-
children,
|
61
|
-
comp));
|
62
|
-
}
|
63
|
-
return React.createElement(React.Fragment, null, children);
|
64
|
-
};
|
65
|
-
const onKeyDown = useUiTreeViewEventPublisher("keydown");
|
66
65
|
return (React.createElement(Dropdown, { className: classnames("gd-semantic-search", className), ignoreClicksOnByClass: [
|
67
66
|
".gd-bubble",
|
68
67
|
".gd-input-icon-clear",
|
69
68
|
".gd-semantic-search__results-item",
|
70
69
|
".gd-semantic-search__input",
|
71
|
-
],
|
72
|
-
if (
|
73
|
-
|
74
|
-
React.createElement(LoadingMask, { width: isMobile ? "100%" : width, height: LOADING_HEIGHT })));
|
75
|
-
}
|
76
|
-
if (items.length === 0 || searchStatus !== "success") {
|
77
|
-
return null;
|
70
|
+
], onOpenStateChanged: (isOpen) => {
|
71
|
+
if (!isOpen) {
|
72
|
+
setActiveNodeId(undefined);
|
78
73
|
}
|
79
|
-
|
80
|
-
React.createElement(UiStaticTreeview, { items: items, width: width, ItemComponent: SemanticSearchItem, ariaAttributes: {
|
81
|
-
id: "semantic-search-tree",
|
82
|
-
"aria-label": intl.formatMessage({ id: "semantic-search.tree" }),
|
83
|
-
}, onSelect: (item) => {
|
84
|
-
// Blur and clear the state
|
85
|
-
const input = inputRef.current?.inputNodeRef?.inputNodeRef;
|
86
|
-
if (input) {
|
87
|
-
input.blur();
|
88
|
-
}
|
89
|
-
setImmediate("");
|
90
|
-
closeDropdown();
|
91
|
-
// Report the selected item
|
92
|
-
onSelect(item.data);
|
93
|
-
}, shouldKeyboardActionPreventDefault: false })));
|
94
|
-
}, renderButton: ({ openDropdown }) => {
|
74
|
+
}, closeOnEscape: false, renderButton: ({ openDropdown }) => {
|
95
75
|
return (React.createElement("div", { ref: ref },
|
96
|
-
React.createElement(Input, { className: "gd-semantic-search__input",
|
97
|
-
} })
|
76
|
+
React.createElement(Input, { ref: inputRef, className: "gd-semantic-search__input", id: inputId, type: "search", placeholder: placeholder, accessibilityConfig: inputAccessibilityConfig, isSearch: true, clearOnEsc: true, value: value, onChange: handleValueChange, onFocus: openDropdown, onKeyDown: handleKeyDown })));
|
77
|
+
}, renderBody: ({ closeDropdown, isMobile }) => (React.createElement("div", null,
|
78
|
+
(() => {
|
79
|
+
const responsiveWidth = isMobile ? undefined : width;
|
80
|
+
if (loading) {
|
81
|
+
return React.createElement(LoadingMask, { width: responsiveWidth, height: LOADING_HEIGHT });
|
82
|
+
}
|
83
|
+
switch (searchStatus) {
|
84
|
+
case "loading":
|
85
|
+
return React.createElement(LoadingMask, { width: responsiveWidth, height: LOADING_HEIGHT });
|
86
|
+
case "error":
|
87
|
+
return null;
|
88
|
+
case "success":
|
89
|
+
// API search message
|
90
|
+
if (!searchResults.length && searchMessage) {
|
91
|
+
return React.createElement("div", { className: "gd-semantic-search__message" }, searchMessage);
|
92
|
+
}
|
93
|
+
// No search results
|
94
|
+
if (!searchResults.length) {
|
95
|
+
return null;
|
96
|
+
}
|
97
|
+
return (React.createElement(SemanticSearchTreeView, { id: treeViewId, searchResults: searchResults, searchRelationships: relationships, threshold: threshold, width: responsiveWidth, onSelect: (item) => {
|
98
|
+
// Blur and clear the state
|
99
|
+
inputRef.current?.inputNodeRef?.inputNodeRef?.blur();
|
100
|
+
setImmediate("");
|
101
|
+
closeDropdown();
|
102
|
+
// Report the selected item
|
103
|
+
onSelect(item.data);
|
104
|
+
}, onFocus: setActiveNodeId, canEdit: permissions.canManageProject ??
|
105
|
+
permissions.canCreateVisualization ??
|
106
|
+
false }));
|
107
|
+
case "idle":
|
108
|
+
return null;
|
109
|
+
}
|
110
|
+
})(),
|
111
|
+
renderFooter?.({ ...props, status: searchStatus, value }, { closeSearch: closeDropdown }))) }));
|
98
112
|
};
|
99
113
|
/**
|
100
114
|
* Semantic search filed with dropdown for selecting items.
|
@@ -102,7 +116,8 @@ const SemanticSearchCore = (props) => {
|
|
102
116
|
*/
|
103
117
|
export const SemanticSearch = ({ locale, ...coreProps }) => {
|
104
118
|
return (React.createElement(IntlWrapper, { locale: locale },
|
105
|
-
React.createElement(
|
106
|
-
React.createElement(
|
119
|
+
React.createElement(PermissionsProvider, { backend: coreProps.backend, workspace: coreProps.workspace },
|
120
|
+
React.createElement(UiTreeViewEventsProvider, null,
|
121
|
+
React.createElement(SemanticSearchCore, { ...coreProps })))));
|
107
122
|
};
|
108
123
|
//# sourceMappingURL=SemanticSearch.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SemanticSearch.js","sourceRoot":"","sources":["../src/SemanticSearch.tsx"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,KAAK,
|
1
|
+
{"version":3,"file":"SemanticSearch.js","sourceRoot":"","sources":["../src/SemanticSearch.tsx"],"names":[],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SemanticSearchItem.d.ts","sourceRoot":"","sources":["../src/SemanticSearchItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAMjE,KAAK,KAAK,GAAG,oBAAoB,CAAC,yBAAyB,CAAC,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,
|
1
|
+
{"version":3,"file":"SemanticSearchItem.d.ts","sourceRoot":"","sources":["../src/SemanticSearchItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAMjE,KAAK,KAAK,GAAG,oBAAoB,CAAC,yBAAyB,CAAC,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,qBAoB9C"}
|
@@ -9,8 +9,11 @@ import { getAriaLabel } from "./utils/getAriaLabel.js";
|
|
9
9
|
* @internal
|
10
10
|
*/
|
11
11
|
export function SemanticSearchItem(props) {
|
12
|
-
const { item, level, isFocused, onSelect, onHover } = props;
|
13
|
-
return (React.createElement(SearchItem, {
|
12
|
+
const { item, level, isFocused, onSelect, onHover, ariaAttributes } = props;
|
13
|
+
return (React.createElement(SearchItem, { ariaAttributes: {
|
14
|
+
...ariaAttributes,
|
15
|
+
"aria-label": getAriaLabel(item.data),
|
16
|
+
}, level: level, onClick: onSelect, onHover: onHover, isFocused: isFocused, icon: React.createElement(SearchItemIcon, { item: item.data }), details: React.createElement(SearchItemDetails, { item: item.data }) },
|
14
17
|
React.createElement("span", { className: "gd-semantic-search__results-item__text__row" },
|
15
18
|
React.createElement("span", { className: "gd-semantic-search__results-item__text__ellipsis" }, item.stringTitle))));
|
16
19
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SemanticSearchItem.js","sourceRoot":"","sources":["../src/SemanticSearchItem.tsx"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIvD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAY;IAC3C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;
|
1
|
+
{"version":3,"file":"SemanticSearchItem.js","sourceRoot":"","sources":["../src/SemanticSearchItem.tsx"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIvD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAY;IAC3C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAC5E,OAAO,CACH,oBAAC,UAAU,IACP,cAAc,EAAE;YACZ,GAAG,cAAc;YACjB,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;SACxC,EACD,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,oBAAC,cAAc,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAI,EACzC,OAAO,EAAE,oBAAC,iBAAiB,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAI;QAE/C,8BAAM,SAAS,EAAC,6CAA6C;YACzD,8BAAM,SAAS,EAAC,kDAAkD,IAAE,IAAI,CAAC,WAAW,CAAQ,CACzF,CACE,CAChB,CAAC;AACN,CAAC"}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import type { ISemanticSearchResultItem, ISemanticSearchRelationship } from "@gooddata/sdk-model";
|
3
|
+
import { type UiLeveledTreeView, type OnLeveledSelectFn } from "@gooddata/sdk-ui-kit";
|
4
|
+
export type SearchTreeViewLevels = [ISemanticSearchResultItem, ISemanticSearchRelationship];
|
5
|
+
export type SearchTreeViewItem = UiLeveledTreeView<SearchTreeViewLevels>;
|
6
|
+
type Props = {
|
7
|
+
id: string;
|
8
|
+
searchResults: ISemanticSearchResultItem[];
|
9
|
+
searchRelationships: ISemanticSearchRelationship[];
|
10
|
+
width?: number;
|
11
|
+
threshold?: number;
|
12
|
+
canEdit?: boolean;
|
13
|
+
onSelect: OnLeveledSelectFn<SearchTreeViewLevels>;
|
14
|
+
onFocus: (nodeId: string) => void;
|
15
|
+
};
|
16
|
+
/**
|
17
|
+
* A tree view component for semantic search results.
|
18
|
+
* @internal
|
19
|
+
*/
|
20
|
+
export declare function SemanticSearchTreeView({ id, width, onSelect, onFocus, ...props }: Props): React.JSX.Element;
|
21
|
+
export {};
|
22
|
+
//# sourceMappingURL=SemanticSearchTreeView.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"SemanticSearchTreeView.d.ts","sourceRoot":"","sources":["../src/SemanticSearchTreeView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAqB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIzG,MAAM,MAAM,oBAAoB,GAAG,CAAC,yBAAyB,EAAE,2BAA2B,CAAC,CAAC;AAC5F,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;AAEzE,KAAK,KAAK,GAAG;IACT,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,yBAAyB,EAAE,CAAC;IAC3C,mBAAmB,EAAE,2BAA2B,EAAE,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;IAClD,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,qBAuBvF"}
|
@@ -0,0 +1,65 @@
|
|
1
|
+
// (C) 2025 GoodData Corporation
|
2
|
+
import React from "react";
|
3
|
+
import { useIntl } from "react-intl";
|
4
|
+
import { UiLeveledTreeview } from "@gooddata/sdk-ui-kit";
|
5
|
+
import { LeveledSearchTreeViewItemMemo } from "./internal/LeveledSearchTreeViewItem.js";
|
6
|
+
import { getItemRelationships } from "./utils/searchItem.js";
|
7
|
+
/**
|
8
|
+
* A tree view component for semantic search results.
|
9
|
+
* @internal
|
10
|
+
*/
|
11
|
+
export function SemanticSearchTreeView({ id, width, onSelect, onFocus, ...props }) {
|
12
|
+
const intl = useIntl();
|
13
|
+
const items = buildItems(props);
|
14
|
+
return (React.createElement(UiLeveledTreeview, { items: items, width: width, maxHeight: 500, ariaAttributes: {
|
15
|
+
id,
|
16
|
+
tabIndex: -1,
|
17
|
+
"aria-label": intl.formatMessage({ id: "semantic-search.tree" }),
|
18
|
+
}, expandedMode: "default-collapsed", selectionMode: "leafs-only", expansionMode: "single", onSelect: onSelect, onFocus: onFocus, ItemComponent: LeveledSearchTreeViewItemMemo, shouldKeyboardActionPreventDefault: false, isDisabledFocusable // For displaying locked items
|
19
|
+
: true }));
|
20
|
+
}
|
21
|
+
function buildItems({ searchResults, searchRelationships, threshold = 0.8, canEdit = false, }) {
|
22
|
+
return searchResults
|
23
|
+
.filter((item) => {
|
24
|
+
// Filter out items with similarity score below the threshold
|
25
|
+
return (item.score ?? 0) >= threshold;
|
26
|
+
})
|
27
|
+
.map((item) => {
|
28
|
+
// Do not show relationships for dashboard items
|
29
|
+
if (item.type === "dashboard") {
|
30
|
+
return {
|
31
|
+
item: {
|
32
|
+
id: item.id,
|
33
|
+
stringTitle: item.title,
|
34
|
+
data: item,
|
35
|
+
},
|
36
|
+
};
|
37
|
+
}
|
38
|
+
const relationships = getItemRelationships(item, searchRelationships);
|
39
|
+
return {
|
40
|
+
item: {
|
41
|
+
id: item.id,
|
42
|
+
stringTitle: item.title,
|
43
|
+
data: item,
|
44
|
+
},
|
45
|
+
children: relationships.map((relationship) => {
|
46
|
+
return {
|
47
|
+
item: {
|
48
|
+
id: relationship.sourceObjectId,
|
49
|
+
stringTitle: relationship.sourceObjectTitle,
|
50
|
+
data: relationship,
|
51
|
+
},
|
52
|
+
};
|
53
|
+
}),
|
54
|
+
};
|
55
|
+
})
|
56
|
+
.filter((item) => {
|
57
|
+
//NOTE: This is a workaround for a permissions, if user has only view permission on the dashboard
|
58
|
+
// and we found object that is not dashboard has no relationships, we don't want to show it
|
59
|
+
if (!canEdit && item.item.data.type !== "dashboard") {
|
60
|
+
return (item.children?.length ?? 0) > 0;
|
61
|
+
}
|
62
|
+
return true;
|
63
|
+
});
|
64
|
+
}
|
65
|
+
//# sourceMappingURL=SemanticSearchTreeView.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"SemanticSearchTreeView.js","sourceRoot":"","sources":["../src/SemanticSearchTreeView.tsx"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EAAE,iBAAiB,EAAkD,MAAM,sBAAsB,CAAC;AACzG,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAgB7D;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,EAAS;IACpF,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAChC,OAAO,CACH,oBAAC,iBAAiB,IACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,GAAG,EACd,cAAc,EAAE;YACZ,EAAE;YACF,QAAQ,EAAE,CAAC,CAAC;YACZ,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,sBAAsB,EAAE,CAAC;SACnE,EACD,YAAY,EAAC,mBAAmB,EAChC,aAAa,EAAC,YAAY,EAC1B,aAAa,EAAC,QAAQ,EACtB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,6BAA6B,EAC5C,kCAAkC,EAAE,KAAK,EACzC,mBAAmB,CAAC,8BAA8B;iBACpD,CACL,CAAC;AACN,CAAC;AASD,SAAS,UAAU,CAAC,EAChB,aAAa,EACb,mBAAmB,EACnB,SAAS,GAAG,GAAG,EACf,OAAO,GAAG,KAAK,GACD;IACd,OAAO,aAAa;SACf,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACb,6DAA6D;QAC7D,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,SAAS,CAAC;IAC1C,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,IAAI,EAAsB,EAAE;QAC9B,gDAAgD;QAChD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC5B,OAAO;gBACH,IAAI,EAAE;oBACF,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,WAAW,EAAE,IAAI,CAAC,KAAK;oBACvB,IAAI,EAAE,IAAI;iBACb;aACJ,CAAC;QACN,CAAC;QACD,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QACtE,OAAO;YACH,IAAI,EAAE;gBACF,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,WAAW,EAAE,IAAI,CAAC,KAAK;gBACvB,IAAI,EAAE,IAAI;aACb;YACD,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE;gBACzC,OAAO;oBACH,IAAI,EAAE;wBACF,EAAE,EAAE,YAAY,CAAC,cAAc;wBAC/B,WAAW,EAAE,YAAY,CAAC,iBAAiB;wBAC3C,IAAI,EAAE,YAAY;qBACrB;iBACJ,CAAC;YACN,CAAC,CAAC;SACL,CAAC;IACN,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACb,iGAAiG;QACjG,2FAA2F;QAC3F,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC,CAAC;AACX,CAAC"}
|
package/esm/hooks/index.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
export * from "./useSemanticSearch.js";
|
2
|
-
export * from "./useListSelector.js";
|
3
|
-
export * from "./useListScroll.js";
|
4
2
|
export * from "./useSearchMetrics.js";
|
5
3
|
export * from "./useElementWidth.js";
|
4
|
+
export { useSearchIds } from "./useSearchIds.js";
|
5
|
+
export { useSearchKeyboard } from "./usSearchKeyboard.js";
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/esm/hooks/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAEA,cAAc,wBAAwB,CAAC;AACvC,cAAc,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAEA,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/esm/hooks/index.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
// (C) 2024-2025 GoodData Corporation
|
2
2
|
export * from "./useSemanticSearch.js";
|
3
|
-
export * from "./useListSelector.js";
|
4
|
-
export * from "./useListScroll.js";
|
5
3
|
export * from "./useSearchMetrics.js";
|
6
4
|
export * from "./useElementWidth.js";
|
5
|
+
export { useSearchIds } from "./useSearchIds.js";
|
6
|
+
export { useSearchKeyboard } from "./usSearchKeyboard.js";
|
7
7
|
//# sourceMappingURL=index.js.map
|
package/esm/hooks/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,cAAc,wBAAwB,CAAC;AACvC,cAAc,
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"usSearchKeyboard.d.ts","sourceRoot":"","sources":["../../src/hooks/usSearchKeyboard.ts"],"names":[],"mappings":"AACA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAG3C;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAcxE"}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
// (C) 2025 GoodData Corporation
|
2
|
+
import { useCallback } from "react";
|
3
|
+
import { useUiTreeViewEventPublisher } from "@gooddata/sdk-ui-kit";
|
4
|
+
/**
|
5
|
+
* Common keyboard handler for the search combobox input element.
|
6
|
+
* @internal
|
7
|
+
*/
|
8
|
+
export function useSearchKeyboard() {
|
9
|
+
const publishKeyDown = useUiTreeViewEventPublisher("keydown");
|
10
|
+
return useCallback((event) => {
|
11
|
+
// Ignore the Space key when the input is focused
|
12
|
+
if (event.code === "Space") {
|
13
|
+
return;
|
14
|
+
}
|
15
|
+
// Forward the event to the TreeView keyboard handler
|
16
|
+
publishKeyDown(event);
|
17
|
+
}, [publishKeyDown]);
|
18
|
+
}
|
19
|
+
//# sourceMappingURL=usSearchKeyboard.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"usSearchKeyboard.js","sourceRoot":"","sources":["../../src/hooks/usSearchKeyboard.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAc,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAEnE;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC7B,MAAM,cAAc,GAAG,2BAA2B,CAAC,SAAS,CAAC,CAAC;IAE9D,OAAO,WAAW,CACd,CAAC,KAA0B,EAAE,EAAE;QAC3B,iDAAiD;QACjD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO;QACX,CAAC;QACD,qDAAqD;QACrD,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,EACD,CAAC,cAAc,CAAC,CACnB,CAAC;AACN,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useSearchIds.d.ts","sourceRoot":"","sources":["../../src/hooks/useSearchIds.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,YAAY;;;EAK3B"}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// (C) 2025 GoodData Corporation
|
2
|
+
import { useId } from "react";
|
3
|
+
/**
|
4
|
+
* Generates unique IDs for the semantic search.
|
5
|
+
* @internal
|
6
|
+
*/
|
7
|
+
export function useSearchIds() {
|
8
|
+
const id = useId();
|
9
|
+
const inputId = `semantic-search/${id}/input`;
|
10
|
+
const treeViewId = `semantic-search/${id}/treeview`;
|
11
|
+
return { inputId, treeViewId };
|
12
|
+
}
|
13
|
+
//# sourceMappingURL=useSearchIds.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useSearchIds.js","sourceRoot":"","sources":["../../src/hooks/useSearchIds.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B;;;GAGG;AACH,MAAM,UAAU,YAAY;IACxB,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,OAAO,GAAG,mBAAmB,EAAE,QAAQ,CAAC;IAC9C,MAAM,UAAU,GAAG,mBAAmB,EAAE,WAAW,CAAC;IACpD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AACnC,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useSemanticSearch.d.ts","sourceRoot":"","sources":["../../src/hooks/useSemanticSearch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAE9G,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACpC;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACvD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,EAAE,yBAAyB,EAAE,CAAC;IAC3C,aAAa,EAAE,2BAA2B,EAAE,CAAC;CAChD,CAAC;
|
1
|
+
{"version":3,"file":"useSemanticSearch.d.ts","sourceRoot":"","sources":["../../src/hooks/useSemanticSearch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAE9G,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACpC;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACvD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,aAAa,EAAE,yBAAyB,EAAE,CAAC;IAC3C,aAAa,EAAE,2BAA2B,EAAE,CAAC;CAChD,CAAC;AAaF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAClC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,qEAO/B,uBAAuB,KAAG,yBAmE5B,CAAC"}
|