@open-pioneer/search 0.10.0 → 0.11.0-dev.20250515143825

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @open-pioneer/search
2
2
 
3
+ ## 0.11.0-dev.20250515143825
4
+
5
+ ### Minor Changes
6
+
7
+ - 738390e: Update to Chakra v3
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [738390e]
12
+ - Updated dependencies [738390e]
13
+ - @open-pioneer/map@0.11.0-dev.20250515143825
14
+
3
15
  ## 0.10.0
4
16
 
5
17
  ### Minor Changes
@@ -1,9 +1,11 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { SearchIcon } from '@chakra-ui/icons';
3
- import { chakra, CloseButton } from '@open-pioneer/chakra-integration';
2
+ import { FiSearch } from 'react-icons/fi';
3
+ import { chakra } from '@chakra-ui/react';
4
+ import { CloseButton } from '@open-pioneer/chakra-snippets/close-button';
4
5
  import { chakraComponents } from 'chakra-react-select';
5
6
  import classNames from 'classnames';
6
7
  import { useIntl } from './_virtual/_virtual-pioneer-module_react-hooks.js';
8
+ import { useMemo } from 'react';
7
9
 
8
10
  function MenuComp(props) {
9
11
  const hasInput = props.selectProps.inputValue.length > 0;
@@ -43,7 +45,7 @@ function ValueContainer({
43
45
  className: classNames(props.className, "search-value-container")
44
46
  };
45
47
  return /* @__PURE__ */ jsxs(chakraComponents.ValueContainer, { ...containerProps, children: [
46
- !!children && /* @__PURE__ */ jsx(SearchIcon, { style: { position: "absolute", left: 8 } }),
48
+ !!children && /* @__PURE__ */ jsx(FiSearch, { style: { position: "absolute", left: 8 }, size: "1.25em" }),
47
49
  children
48
50
  ] });
49
51
  }
@@ -83,8 +85,8 @@ function CustomClearIndicator(props) {
83
85
  CloseButton,
84
86
  {
85
87
  role: "button",
86
- size: "md",
87
- mr: 1,
88
+ size: "sm",
89
+ mr: "1px",
88
90
  "aria-label": clearButtonLabel,
89
91
  onClick: clickHandler,
90
92
  onTouchEnd: clickHandler,
@@ -102,7 +104,10 @@ function HighlightOption(props) {
102
104
  ...props,
103
105
  className: classNames(props.className, "search-option")
104
106
  };
105
- return /* @__PURE__ */ jsx(chakraComponents.Option, { ...optionProps, children: /* @__PURE__ */ jsx(chakra.div, { className: "search-option-label", children: userInput.trim().length > 0 ? getHighlightedLabel(label, userInput) : label }) });
107
+ const highlightedLabel = useMemo(() => {
108
+ return /* @__PURE__ */ jsx(chakra.div, { className: "search-option-label", children: userInput.trim().length > 0 ? getHighlightedLabel(label, userInput) : label });
109
+ }, [label, userInput]);
110
+ return /* @__PURE__ */ jsx(chakraComponents.Option, { ...optionProps, children: highlightedLabel });
106
111
  }
107
112
  function getHighlightedLabel(label, userInput) {
108
113
  const matchIndex = label.toLowerCase().indexOf(userInput.toLowerCase());
@@ -1 +1 @@
1
- {"version":3,"file":"CustomComponents.js","sources":["CustomComponents.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { SearchIcon } from \"@chakra-ui/icons\";\nimport { CloseButton, chakra } from \"@open-pioneer/chakra-integration\";\nimport {\n ClearIndicatorProps,\n GroupProps,\n IndicatorsContainerProps,\n InputProps,\n MenuProps,\n NoticeProps,\n OptionProps,\n Props as SelectProps,\n SingleValueProps,\n ValueContainerProps,\n chakraComponents\n} from \"chakra-react-select\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { UIEvent } from \"react\";\nimport { SearchGroupOption, SearchOption } from \"./Search\";\n\nexport function MenuComp(props: MenuProps<SearchOption, false, SearchGroupOption>) {\n const hasInput = props.selectProps.inputValue.length > 0;\n const menuProps: typeof props = {\n ...props,\n className: classNames(props.className, {\n \"search-invisible\": !hasInput\n })\n };\n\n return <chakraComponents.Menu {...menuProps}>{props.children}</chakraComponents.Menu>;\n}\n\nexport function GroupComp(props: GroupProps<SearchOption, false, SearchGroupOption>) {\n const ariaLabel = props.data.label;\n const innerProps = {\n ...props.innerProps,\n \"aria-label\": ariaLabel,\n role: \"group\"\n };\n return <chakraComponents.Group {...props} innerProps={innerProps}></chakraComponents.Group>;\n}\n\nexport function NoOptionsMessage(props: NoticeProps<SearchOption, false, SearchGroupOption>) {\n const intl = useIntl();\n const noMessageText = intl.formatMessage({ id: \"noOptionsText\" });\n\n return (\n <chakraComponents.NoOptionsMessage {...props}>\n <chakra.span className=\"search-no-match\">{noMessageText}</chakra.span>\n </chakraComponents.NoOptionsMessage>\n );\n}\n\nexport function LoadingMessage(props: NoticeProps<SearchOption, false, SearchGroupOption>) {\n const intl = useIntl();\n const loadingText = intl.formatMessage({ id: \"loadingText\" });\n\n return (\n <chakraComponents.LoadingMessage {...props}>\n <chakra.span className=\"search-loading-text\">{loadingText}</chakra.span>\n </chakraComponents.LoadingMessage>\n );\n}\n\nexport function ValueContainer({\n children,\n ...props\n}: ValueContainerProps<SearchOption, false, SearchGroupOption>) {\n const containerProps: typeof props = {\n ...props,\n className: classNames(props.className, \"search-value-container\")\n };\n return (\n <chakraComponents.ValueContainer {...containerProps}>\n {!!children && <SearchIcon style={{ position: \"absolute\", left: 8 }}></SearchIcon>}\n {children}\n </chakraComponents.ValueContainer>\n );\n}\n\nexport function Input(props: InputProps<SearchOption, false, SearchGroupOption>) {\n const inputProps: typeof props = {\n ...props,\n isHidden: false\n };\n return <chakraComponents.Input {...inputProps} />;\n}\n\nexport function SingleValue(_props: SingleValueProps<SearchOption, false, SearchGroupOption>) {\n // Never render anything (we use the text input to show the selected result)\n return null;\n}\n\nexport function IndicatorsContainer(\n props: IndicatorsContainerProps<SearchOption, false, SearchGroupOption>\n) {\n return (\n <chakraComponents.IndicatorsContainer {...props}>\n {props.children}\n {!props.selectProps.isLoading && props.selectProps.inputValue && (\n <CustomClearIndicator\n selectProps={props.selectProps}\n clearValue={props.clearValue}\n />\n )}\n </chakraComponents.IndicatorsContainer>\n );\n}\n\nfunction CustomClearIndicator(props: {\n clearValue(): void;\n selectProps: SelectProps<SearchOption, false, SearchGroupOption>;\n}) {\n const intl = useIntl();\n const clearButtonLabel = intl.formatMessage({\n id: \"ariaLabel.clearButton\"\n });\n const clickHandler = (e: UIEvent) => {\n e.preventDefault();\n e.stopPropagation();\n props.clearValue();\n };\n\n return (\n <CloseButton\n role=\"button\"\n size=\"md\"\n mr={1}\n aria-label={clearButtonLabel}\n onClick={clickHandler}\n // needed for correct touch handling; select control would otherwise preventDefault()\n onTouchEnd={clickHandler}\n // Stop select component from opening the menu.\n // It will otherwise flash briefly because of a mouse down listener in the select.\n onMouseDown={(e) => e.preventDefault()}\n />\n );\n}\n\nexport function ClearIndicator(\n _props: ClearIndicatorProps<SearchOption, false, SearchGroupOption>\n) {\n // Never render anything; we use our own clear indicator\n return null;\n}\n\nexport function HighlightOption(props: OptionProps<SearchOption, false, SearchGroupOption>) {\n const userInput = props.selectProps.inputValue;\n const label = props.data.label;\n const optionProps: typeof props = {\n ...props,\n className: classNames(props.className, \"search-option\")\n };\n return (\n <chakraComponents.Option {...optionProps}>\n <chakra.div className=\"search-option-label\">\n {userInput.trim().length > 0 ? getHighlightedLabel(label, userInput) : label}\n </chakra.div>\n </chakraComponents.Option>\n );\n}\n\nfunction getHighlightedLabel(label: string, userInput: string) {\n const matchIndex = label.toLowerCase().indexOf(userInput.toLowerCase());\n if (matchIndex >= 0) {\n return (\n <>\n {label.substring(0, matchIndex)}\n <chakra.span key=\"highlighted\" className=\"search-highlighted-match\">\n {label.substring(matchIndex, matchIndex + userInput.length)}\n </chakra.span>\n {label.substring(matchIndex + userInput.length)}\n </>\n );\n }\n return label;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CustomComponents.js","sources":["CustomComponents.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { FiSearch } from \"react-icons/fi\";\nimport { chakra } from \"@chakra-ui/react\";\nimport { CloseButton } from \"@open-pioneer/chakra-snippets/close-button\";\nimport {\n ClearIndicatorProps,\n GroupProps,\n IndicatorsContainerProps,\n InputProps,\n MenuProps,\n NoticeProps,\n OptionProps,\n Props as SelectProps,\n SingleValueProps,\n ValueContainerProps,\n chakraComponents\n} from \"chakra-react-select\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { UIEvent, useMemo } from \"react\";\nimport { SearchGroupOption, SearchOption } from \"./Search\";\n\nexport function MenuComp(props: MenuProps<SearchOption, false, SearchGroupOption>) {\n const hasInput = props.selectProps.inputValue.length > 0;\n const menuProps: typeof props = {\n ...props,\n className: classNames(props.className, {\n \"search-invisible\": !hasInput\n })\n };\n\n return <chakraComponents.Menu {...menuProps}>{props.children}</chakraComponents.Menu>;\n}\n\nexport function GroupComp(props: GroupProps<SearchOption, false, SearchGroupOption>) {\n const ariaLabel = props.data.label;\n const innerProps = {\n ...props.innerProps,\n \"aria-label\": ariaLabel,\n role: \"group\"\n };\n return <chakraComponents.Group {...props} innerProps={innerProps}></chakraComponents.Group>;\n}\n\nexport function NoOptionsMessage(props: NoticeProps<SearchOption, false, SearchGroupOption>) {\n const intl = useIntl();\n const noMessageText = intl.formatMessage({ id: \"noOptionsText\" });\n\n return (\n <chakraComponents.NoOptionsMessage {...props}>\n <chakra.span className=\"search-no-match\">{noMessageText}</chakra.span>\n </chakraComponents.NoOptionsMessage>\n );\n}\n\nexport function LoadingMessage(props: NoticeProps<SearchOption, false, SearchGroupOption>) {\n const intl = useIntl();\n const loadingText = intl.formatMessage({ id: \"loadingText\" });\n\n return (\n <chakraComponents.LoadingMessage {...props}>\n <chakra.span className=\"search-loading-text\">{loadingText}</chakra.span>\n </chakraComponents.LoadingMessage>\n );\n}\n\nexport function ValueContainer({\n children,\n ...props\n}: ValueContainerProps<SearchOption, false, SearchGroupOption>) {\n const containerProps: typeof props = {\n ...props,\n className: classNames(props.className, \"search-value-container\")\n };\n return (\n <chakraComponents.ValueContainer {...containerProps}>\n {!!children && <FiSearch style={{ position: \"absolute\", left: 8 }} size=\"1.25em\" />}\n {children}\n </chakraComponents.ValueContainer>\n );\n}\n\nexport function Input(props: InputProps<SearchOption, false, SearchGroupOption>) {\n const inputProps: typeof props = {\n ...props,\n isHidden: false\n };\n return <chakraComponents.Input {...inputProps} />;\n}\n\nexport function SingleValue(_props: SingleValueProps<SearchOption, false, SearchGroupOption>) {\n // Never render anything (we use the text input to show the selected result)\n return null;\n}\n\nexport function IndicatorsContainer(\n props: IndicatorsContainerProps<SearchOption, false, SearchGroupOption>\n) {\n return (\n <chakraComponents.IndicatorsContainer {...props}>\n {props.children}\n {!props.selectProps.isLoading && props.selectProps.inputValue && (\n <CustomClearIndicator\n selectProps={props.selectProps}\n clearValue={props.clearValue}\n />\n )}\n </chakraComponents.IndicatorsContainer>\n );\n}\n\nfunction CustomClearIndicator(props: {\n clearValue(): void;\n selectProps: SelectProps<SearchOption, false, SearchGroupOption>;\n}) {\n const intl = useIntl();\n const clearButtonLabel = intl.formatMessage({\n id: \"ariaLabel.clearButton\"\n });\n const clickHandler = (e: UIEvent) => {\n e.preventDefault();\n e.stopPropagation();\n props.clearValue();\n };\n\n return (\n <CloseButton\n role=\"button\"\n size=\"sm\"\n mr=\"1px\"\n aria-label={clearButtonLabel}\n onClick={clickHandler}\n // needed for correct touch handling; select control would otherwise preventDefault()\n onTouchEnd={clickHandler}\n // Stop select component from opening the menu.\n // It will otherwise flash briefly because of a mouse down listener in the select.\n onMouseDown={(e) => e.preventDefault()}\n />\n );\n}\n\nexport function ClearIndicator(\n _props: ClearIndicatorProps<SearchOption, false, SearchGroupOption>\n) {\n // Never render anything; we use our own clear indicator\n return null;\n}\n\nexport function HighlightOption(props: OptionProps<SearchOption, false, SearchGroupOption>) {\n const userInput = props.selectProps.inputValue;\n const label = props.data.label;\n const optionProps: typeof props = {\n ...props,\n className: classNames(props.className, \"search-option\")\n };\n\n const highlightedLabel = useMemo(() => {\n return (\n <chakra.div className=\"search-option-label\">\n {userInput.trim().length > 0 ? getHighlightedLabel(label, userInput) : label}\n </chakra.div>\n );\n }, [label, userInput]);\n\n return <chakraComponents.Option {...optionProps}>{highlightedLabel}</chakraComponents.Option>;\n}\n\nfunction getHighlightedLabel(label: string, userInput: string) {\n const matchIndex = label.toLowerCase().indexOf(userInput.toLowerCase());\n if (matchIndex >= 0) {\n return (\n <>\n {label.substring(0, matchIndex)}\n <chakra.span key=\"highlighted\" className=\"search-highlighted-match\">\n {label.substring(matchIndex, matchIndex + userInput.length)}\n </chakra.span>\n {label.substring(matchIndex + userInput.length)}\n </>\n );\n }\n return label;\n}\n"],"names":[],"mappings":"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"}
package/Search.js CHANGED
@@ -1,5 +1,5 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { Box, useToken } from '@open-pioneer/chakra-integration';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Box, Portal, chakra, useToken } from '@chakra-ui/react';
3
3
  import { createLogger, isAbortError } from '@open-pioneer/core';
4
4
  import { useMapModel } from '@open-pioneer/map';
5
5
  import { useCommonComponentProps, useEvent } from '@open-pioneer/react-utils';
@@ -20,6 +20,7 @@ const Search = (props) => {
20
20
  const chakraStyles = useChakraStyles();
21
21
  const ariaMessages = useAriaMessages(intl);
22
22
  const components = useCustomComponents();
23
+ const portalDiv = useRef(null);
23
24
  const handleInputChange = useEvent((newValue, actionMeta) => {
24
25
  if (actionMeta.action === "input-change") {
25
26
  onInputChanged(newValue);
@@ -50,33 +51,35 @@ const Search = (props) => {
50
51
  }
51
52
  );
52
53
  const selectRef = useRef(null);
53
- return /* @__PURE__ */ jsx(Box, { ...containerProps, children: /* @__PURE__ */ jsx(
54
- Select,
55
- {
56
- className: "search-component",
57
- classNamePrefix: "react-select",
58
- ref: selectRef,
59
- inputValue: input,
60
- onInputChange: handleInputChange,
61
- "aria-label": intl.formatMessage({ id: "ariaLabel.search" }),
62
- ariaLiveMessages: ariaMessages,
63
- tagColorScheme: "trails",
64
- selectedOptionStyle: "color",
65
- selectedOptionColorScheme: "trails",
66
- chakraStyles,
67
- isClearable: true,
68
- placeholder: props.placeholder ?? intl.formatMessage({ id: "searchPlaceholder" }),
69
- closeMenuOnSelect: true,
70
- isLoading: search2.kind === "loading",
71
- options: search2.kind === "ready" ? search2.results : void 0,
72
- filterOption: () => true,
73
- tabSelectsValue: false,
74
- components,
75
- onChange: handleSelectChange,
76
- value: selectedOption,
77
- menuPosition: "fixed"
78
- }
79
- ) });
54
+ return /* @__PURE__ */ jsxs(Box, { ...containerProps, children: [
55
+ /* @__PURE__ */ jsx(
56
+ Select,
57
+ {
58
+ className: "search-component",
59
+ classNamePrefix: "react-select",
60
+ ref: selectRef,
61
+ inputValue: input,
62
+ onInputChange: handleInputChange,
63
+ "aria-label": intl.formatMessage({ id: "ariaLabel.search" }),
64
+ ariaLiveMessages: ariaMessages,
65
+ selectedOptionStyle: "color",
66
+ selectedOptionColorPalette: "colorPalette",
67
+ chakraStyles,
68
+ isClearable: true,
69
+ placeholder: props.placeholder ?? intl.formatMessage({ id: "searchPlaceholder" }),
70
+ closeMenuOnSelect: true,
71
+ isLoading: search2.kind === "loading",
72
+ options: search2.kind === "ready" ? search2.results : void 0,
73
+ filterOption: () => true,
74
+ tabSelectsValue: false,
75
+ components,
76
+ onChange: handleSelectChange,
77
+ value: selectedOption,
78
+ menuPortalTarget: portalDiv.current
79
+ }
80
+ ),
81
+ /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(chakra.div, { ref: portalDiv, className: "search-component-menu" }) })
82
+ ] });
80
83
  };
81
84
  function useAriaMessages(intl) {
82
85
  return useMemo(() => {
@@ -117,20 +120,29 @@ function useCustomComponents() {
117
120
  }, []);
118
121
  }
119
122
  function useChakraStyles() {
120
- const [groupHeadingBg, focussedItemBg, selectedItemBg] = useToken(
121
- "colors",
122
- ["trails.100", "trails.50", "trails.500"],
123
- ["#d5e5ec", "#eaf2f5", "#1A202C"]
124
- );
123
+ const [groupHeadingBg, focussedItemBg, selectedItemBg] = useToken("colors", [
124
+ "colorPalette.100",
125
+ "colorPalette.50",
126
+ "colorPalette.500"
127
+ ]);
125
128
  return useMemo(() => {
126
129
  const chakraStyles = {
127
- inputContainer: (container) => ({
128
- ...container,
130
+ control: (provided) => ({
131
+ ...provided,
132
+ paddingInline: 0
133
+ }),
134
+ inputContainer: (provided) => ({
135
+ ...provided,
129
136
  gridTemplateAreas: "'area area area'",
130
137
  display: "grid"
131
138
  }),
132
- input: (base) => ({
133
- ...base,
139
+ indicatorsContainer: (provided) => ({
140
+ ...provided,
141
+ // pointerEvents none can sneak in via chakra theme from <Select />
142
+ pointerEvents: "auto"
143
+ }),
144
+ input: (provided) => ({
145
+ ...provided,
134
146
  gridArea: "area"
135
147
  }),
136
148
  groupHeading: (provided) => ({
@@ -144,7 +156,7 @@ function useChakraStyles() {
144
156
  option: (provided) => ({
145
157
  ...provided,
146
158
  backgroundColor: "inherit",
147
- _focus: {
159
+ _highlighted: {
148
160
  backgroundColor: focussedItemBg
149
161
  },
150
162
  _selected: {
package/Search.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Search.js","sources":["Search.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box, useToken } from \"@open-pioneer/chakra-integration\";\nimport { createLogger, isAbortError } from \"@open-pioneer/core\";\nimport { MapModel, MapModelProps, useMapModel } from \"@open-pioneer/map\";\nimport { CommonComponentProps, useCommonComponentProps, useEvent } from \"@open-pioneer/react-utils\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport {\n ActionMeta,\n AriaLiveMessages,\n AriaOnChange,\n AriaOnFocus,\n ChakraStylesConfig,\n InputActionMeta,\n Select,\n SelectInstance,\n Props as SelectProps,\n SingleValue\n} from \"chakra-react-select\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, useCallback, useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport {\n ClearIndicator,\n GroupComp,\n HighlightOption,\n IndicatorsContainer,\n Input,\n LoadingMessage,\n MenuComp,\n NoOptionsMessage,\n SingleValue as SingleValueComp,\n ValueContainer\n} from \"./CustomComponents\";\nimport { SearchController, SuggestionGroup } from \"./SearchController\";\nimport { SearchResult, SearchSource } from \"./api\";\n\nconst LOG = createLogger(\"search:Search\");\n\nexport interface SearchOption {\n /** Unique value for this option. */\n value: string;\n\n /** Display text shown in menu. */\n label: string;\n\n /** Search source that returned the suggestion. */\n source: SearchSource;\n\n /** The raw result from the search source. */\n result: SearchResult;\n}\n\nexport interface SearchGroupOption {\n /** Display text shown in menu. */\n label: string;\n\n /** Set of options that belong to this group. */\n options: SearchOption[];\n}\n\n/**\n * Event type emitted when the user selects an item.\n */\nexport interface SearchSelectEvent {\n /** The source that returned the {@link result}. */\n source: SearchSource;\n\n /** The search result selected by the user. */\n result: SearchResult;\n}\n\n/**\n * Properties supported by the {@link Search} component.\n */\nexport interface SearchProps extends CommonComponentProps, MapModelProps {\n /**\n * Data sources to be searched on.\n */\n sources: SearchSource[];\n\n /**\n * Typing delay (in milliseconds) before the async search query starts after the user types in the search term.\n * Defaults to `200`.\n */\n searchTypingDelay?: number;\n\n /**\n * The maximum number of results shown per group.\n * Defaults to `5`.\n */\n maxResultsPerGroup?: number;\n\n /**\n * The placeholder text shown in the search input field when it is empty.\n * Defaults to a generic (and localized) hint.\n */\n placeholder?: string;\n\n /**\n * This event handler will be called when the user selects a search result.\n */\n onSelect?: (event: SearchSelectEvent) => void;\n\n /**\n * This event handler will be called when the user clears the search input.\n */\n onClear?: () => void;\n}\n\n/**\n * A component that allows the user to search a given set of {@link SearchSource | SearchSources}.\n */\nexport const Search: FC<SearchProps> = (props) => {\n const { sources, searchTypingDelay, maxResultsPerGroup, onSelect, onClear } = props;\n const { containerProps } = useCommonComponentProps(\"search\", props);\n const { map } = useMapModel(props);\n const intl = useIntl();\n const controller = useController(sources, searchTypingDelay, maxResultsPerGroup, map);\n const { input, search, selectedOption, onInputChanged, onResultConfirmed } =\n useSearchState(controller);\n\n const chakraStyles = useChakraStyles();\n const ariaMessages = useAriaMessages(intl);\n const components = useCustomComponents();\n\n const handleInputChange = useEvent((newValue: string, actionMeta: InputActionMeta) => {\n // Only update the input if the user actually typed something.\n // This keeps the input content if the user focuses another element or if the menu is closed.\n if (actionMeta.action === \"input-change\") {\n onInputChanged(newValue);\n }\n });\n\n const handleSelectChange = useEvent(\n (value: SingleValue<SearchOption>, actionMeta: ActionMeta<SearchOption>) => {\n switch (actionMeta.action) {\n case \"select-option\":\n if (value) {\n // Updates the input field with the option label\n onResultConfirmed(value);\n onSelect?.({\n source: value.source,\n result: value.result\n });\n }\n break;\n case \"clear\":\n // Updates the input field\n onInputChanged(\"\");\n\n // the next two lines are a workaround for the open bug in react-select regarding the\n // cursor not being shown after clearing, although the component is focussed:\n // https://github.com/JedWatson/react-select/issues/3871\n selectRef.current?.blur();\n selectRef.current?.focus();\n onClear?.();\n break;\n default:\n LOG.debug(`Unhandled action type '${actionMeta.action}'.`);\n break;\n }\n }\n );\n\n const selectRef = useRef<SelectInstance<SearchOption, false, SearchGroupOption>>(null);\n return (\n <Box {...containerProps}>\n <Select<SearchOption, false, SearchGroupOption>\n className=\"search-component\"\n classNamePrefix=\"react-select\"\n ref={selectRef}\n inputValue={input}\n onInputChange={handleInputChange}\n aria-label={intl.formatMessage({ id: \"ariaLabel.search\" })}\n ariaLiveMessages={ariaMessages}\n tagColorScheme=\"trails\"\n selectedOptionStyle=\"color\"\n selectedOptionColorScheme=\"trails\"\n chakraStyles={chakraStyles}\n isClearable={true}\n placeholder={props.placeholder ?? intl.formatMessage({ id: \"searchPlaceholder\" })}\n closeMenuOnSelect={true}\n isLoading={search.kind === \"loading\"}\n options={search.kind === \"ready\" ? search.results : undefined}\n filterOption={() => true} // always show all options (don't filter based on input text)\n tabSelectsValue={false}\n components={components}\n onChange={handleSelectChange}\n value={selectedOption}\n menuPosition=\"fixed\"\n />\n </Box>\n );\n};\n\n/**\n * Provides custom aria messages for the select component.\n */\nfunction useAriaMessages(\n intl: PackageIntl\n): AriaLiveMessages<SearchOption, false, SearchGroupOption> {\n return useMemo(() => {\n /**\n * Method to create Aria-String for focus-Event\n */\n const onFocus: AriaOnFocus<SearchOption> = () => {\n //no aria string for focus-events because in some screen readers (NVDA) and browsers (Chrome) updating the aria string causes the instructions to be read out again each time a select option is focused\n return \"\";\n };\n\n /**\n * Method to create Aria-String for value-change-Event\n */\n const onChange: AriaOnChange<SearchOption, boolean> = () => {\n //no aria string for change-events because in some screen readers (NVDA) and browsers (Chrome) updating the aria string causes the instructions to be read out again each time a select option is focused\n return \"\";\n };\n\n /**\n * Method to create Aria-String for instruction\n */\n const guidance = () => {\n return `${intl.formatMessage({ id: \"ariaLabel.instructions\" })}`;\n };\n\n /**\n * Method to create Aria-String for result length\n */\n const onFilter = () => {\n return \"\";\n };\n\n return {\n onFocus,\n onChange,\n guidance,\n onFilter\n };\n }, [intl]);\n}\n\n/**\n * Customizes the inner components used by the select component.\n */\nfunction useCustomComponents(): SelectProps<SearchOption, false, SearchGroupOption>[\"components\"] {\n return useMemo(() => {\n return {\n Menu: MenuComp,\n Input: Input,\n SingleValue: SingleValueComp,\n Option: HighlightOption,\n NoOptionsMessage: NoOptionsMessage,\n LoadingMessage: LoadingMessage,\n ValueContainer: ValueContainer,\n IndicatorsContainer: IndicatorsContainer,\n ClearIndicator: ClearIndicator,\n Group: GroupComp\n };\n }, []);\n}\n\n/**\n * Customizes components styles within the select component.\n */\nfunction useChakraStyles() {\n const [groupHeadingBg, focussedItemBg, selectedItemBg] = useToken(\n \"colors\",\n [\"trails.100\", \"trails.50\", \"trails.500\"],\n [\"#d5e5ec\", \"#eaf2f5\", \"#1A202C\"]\n );\n return useMemo(() => {\n const chakraStyles: ChakraStylesConfig<SearchOption, false, SearchGroupOption> = {\n inputContainer: (container) => ({\n ...container,\n gridTemplateAreas: \"'area area area'\",\n display: \"grid\"\n }),\n input: (base) => ({\n ...base,\n gridArea: \"area\"\n }),\n groupHeading: (provided) => ({\n ...provided,\n backgroundColor: groupHeadingBg,\n padding: \"8px 12px\",\n // make Header look like normal options:\n fontSize: \"inherit\",\n fontWeight: \"inherit\"\n }),\n option: (provided) => ({\n ...provided,\n backgroundColor: \"inherit\",\n _focus: {\n backgroundColor: focussedItemBg\n },\n _selected: {\n // Prevent white on white\n backgroundColor: selectedItemBg\n }\n }),\n dropdownIndicator: (provided) => ({\n ...provided,\n display: \"none\" // always hide\n })\n };\n return chakraStyles;\n }, [groupHeadingBg, focussedItemBg, selectedItemBg]);\n}\n\n/**\n * Creates a controller to search on the given sources.\n */\nfunction useController(\n sources: SearchSource[],\n searchTypingDelay: number | undefined,\n maxResultsPerGroup: number | undefined,\n map: MapModel | undefined\n) {\n const [controller, setController] = useState<SearchController | undefined>(undefined);\n useEffect(() => {\n if (!map) {\n return;\n }\n const controller = new SearchController(map, sources);\n setController(controller);\n return () => {\n controller.destroy();\n setController(undefined);\n };\n }, [map, sources]);\n\n useEffect(() => {\n if (controller) {\n controller.searchTypingDelay = searchTypingDelay;\n }\n }, [controller, searchTypingDelay]);\n useEffect(() => {\n if (controller) {\n controller.maxResultsPerSource = maxResultsPerGroup;\n }\n }, [controller, maxResultsPerGroup]);\n return controller;\n}\n\ntype SearchResultsReady = {\n kind: \"ready\";\n results: SearchGroupOption[];\n};\n\ntype SearchResultsLoading = {\n kind: \"loading\";\n};\n\ntype SearchResultsState = SearchResultsReady | SearchResultsLoading;\n\n/**\n * Keeps track of the current input text, active searches and their results.\n *\n * NOTE: it would be great to merge this state handling with the search controller\n * in a future revision.\n */\nfunction useSearchState(controller: SearchController | undefined) {\n interface FullSearchState {\n query: string;\n selectedOption: SearchOption | null;\n search: SearchResultsState;\n }\n\n type Action =\n | { kind: \"input\"; query: string }\n | { kind: \"select-option\"; option: SearchOption }\n | { kind: \"load-results\" }\n | { kind: \"accept-results\"; results: SearchGroupOption[] };\n\n const [state, dispatch] = useReducer(\n (current: FullSearchState, action: Action): FullSearchState => {\n switch (action.kind) {\n case \"input\":\n return {\n ...current,\n query: action.query,\n selectedOption: null\n };\n case \"select-option\":\n return {\n ...current,\n selectedOption: action.option,\n query: action.option.label\n };\n case \"load-results\":\n return {\n ...current,\n search: {\n kind: \"loading\"\n }\n };\n case \"accept-results\":\n return {\n ...current,\n search: {\n kind: \"ready\",\n results: action.results\n }\n };\n }\n },\n undefined,\n (): FullSearchState => ({\n query: \"\",\n selectedOption: null,\n search: {\n kind: \"ready\",\n results: []\n }\n })\n );\n\n // Stores the promise for the current search.\n // Any results from outdated searches are ignored.\n const currentSearch = useRef<Promise<unknown>>(undefined);\n const startSearch = useEvent((query: string) => {\n if (!controller) {\n currentSearch.current = undefined;\n dispatch({ kind: \"accept-results\", results: [] });\n return;\n }\n\n LOG.isDebug() && LOG.debug(`Starting new search for query ${JSON.stringify(query)}.`);\n dispatch({ kind: \"load-results\" });\n const promise = (currentSearch.current = search(controller, query).then((results) => {\n // Check if this job is still current\n if (currentSearch.current === promise) {\n dispatch({ kind: \"accept-results\", results });\n }\n }));\n });\n\n // Called when the user confirms a search result\n const onResultConfirmed = useCallback((option: SearchOption) => {\n // Do not start a new search when the user confirms a result\n dispatch({ kind: \"select-option\", option });\n }, []);\n\n // Called when a user types into the input field\n const onInputChanged = useCallback(\n (newValue: string) => {\n // Trigger a new search if the user changes the query by typing\n dispatch({ kind: \"input\", query: newValue });\n startSearch(newValue);\n },\n [startSearch]\n );\n\n return {\n input: state.query,\n search: state.search,\n selectedOption: state.selectedOption,\n onResultConfirmed,\n onInputChanged\n };\n}\n\nasync function search(controller: SearchController, query: string): Promise<SearchGroupOption[]> {\n let suggestions: SuggestionGroup[];\n try {\n suggestions = await controller.search(query);\n } catch (error) {\n if (!isAbortError(error)) {\n LOG.error(`Search failed`, error);\n }\n suggestions = [];\n }\n return mapSuggestions(suggestions);\n}\n\nfunction mapSuggestions(suggestions: SuggestionGroup[]): SearchGroupOption[] {\n const options = suggestions.map(\n (group, groupIndex): SearchGroupOption => ({\n label: group.label,\n options: group.results.map((suggestion): SearchOption => {\n return {\n value: `${groupIndex}-${suggestion.id}`,\n label: suggestion.label,\n source: group.source,\n result: suggestion\n };\n })\n })\n );\n return options;\n}\n"],"names":["search","SingleValueComp","controller"],"mappings":"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"}
1
+ {"version":3,"file":"Search.js","sources":["Search.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box, chakra, Portal, useToken } from \"@chakra-ui/react\";\nimport { createLogger, isAbortError } from \"@open-pioneer/core\";\nimport { MapModel, MapModelProps, useMapModel } from \"@open-pioneer/map\";\nimport { CommonComponentProps, useCommonComponentProps, useEvent } from \"@open-pioneer/react-utils\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport {\n ActionMeta,\n AriaLiveMessages,\n AriaOnChange,\n AriaOnFocus,\n ChakraStylesConfig,\n InputActionMeta,\n Select,\n SelectInstance,\n Props as SelectProps,\n SingleValue\n} from \"chakra-react-select\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, useCallback, useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport {\n ClearIndicator,\n GroupComp,\n HighlightOption,\n IndicatorsContainer,\n Input,\n LoadingMessage,\n MenuComp,\n NoOptionsMessage,\n SingleValue as SingleValueComp,\n ValueContainer\n} from \"./CustomComponents\";\nimport { SearchController, SuggestionGroup } from \"./SearchController\";\nimport { SearchResult, SearchSource } from \"./api\";\n\nconst LOG = createLogger(\"search:Search\");\n\nexport interface SearchOption {\n /** Unique value for this option. */\n value: string;\n\n /** Display text shown in menu. */\n label: string;\n\n /** Search source that returned the suggestion. */\n source: SearchSource;\n\n /** The raw result from the search source. */\n result: SearchResult;\n}\n\nexport interface SearchGroupOption {\n /** Display text shown in menu. */\n label: string;\n\n /** Set of options that belong to this group. */\n options: SearchOption[];\n}\n\n/**\n * Event type emitted when the user selects an item.\n */\nexport interface SearchSelectEvent {\n /** The source that returned the {@link result}. */\n source: SearchSource;\n\n /** The search result selected by the user. */\n result: SearchResult;\n}\n\n/**\n * Properties supported by the {@link Search} component.\n */\nexport interface SearchProps extends CommonComponentProps, MapModelProps {\n /**\n * Data sources to be searched on.\n */\n sources: SearchSource[];\n\n /**\n * Typing delay (in milliseconds) before the async search query starts after the user types in the search term.\n * Defaults to `200`.\n */\n searchTypingDelay?: number;\n\n /**\n * The maximum number of results shown per group.\n * Defaults to `5`.\n */\n maxResultsPerGroup?: number;\n\n /**\n * The placeholder text shown in the search input field when it is empty.\n * Defaults to a generic (and localized) hint.\n */\n placeholder?: string;\n\n /**\n * This event handler will be called when the user selects a search result.\n */\n onSelect?: (event: SearchSelectEvent) => void;\n\n /**\n * This event handler will be called when the user clears the search input.\n */\n onClear?: () => void;\n}\n\n/**\n * A component that allows the user to search a given set of {@link SearchSource | SearchSources}.\n */\nexport const Search: FC<SearchProps> = (props) => {\n const { sources, searchTypingDelay, maxResultsPerGroup, onSelect, onClear } = props;\n const { containerProps } = useCommonComponentProps(\"search\", props);\n const { map } = useMapModel(props);\n const intl = useIntl();\n const controller = useController(sources, searchTypingDelay, maxResultsPerGroup, map);\n const { input, search, selectedOption, onInputChanged, onResultConfirmed } =\n useSearchState(controller);\n\n const chakraStyles = useChakraStyles();\n const ariaMessages = useAriaMessages(intl);\n const components = useCustomComponents();\n\n const portalDiv = useRef<HTMLDivElement>(null);\n\n const handleInputChange = useEvent((newValue: string, actionMeta: InputActionMeta) => {\n // Only update the input if the user actually typed something.\n // This keeps the input content if the user focuses another element or if the menu is closed.\n if (actionMeta.action === \"input-change\") {\n onInputChanged(newValue);\n }\n });\n\n const handleSelectChange = useEvent(\n (value: SingleValue<SearchOption>, actionMeta: ActionMeta<SearchOption>) => {\n switch (actionMeta.action) {\n case \"select-option\":\n if (value) {\n // Updates the input field with the option label\n onResultConfirmed(value);\n onSelect?.({\n source: value.source,\n result: value.result\n });\n }\n break;\n case \"clear\":\n // Updates the input field\n onInputChanged(\"\");\n\n // the next two lines are a workaround for the open bug in react-select regarding the\n // cursor not being shown after clearing, although the component is focussed:\n // https://github.com/JedWatson/react-select/issues/3871\n selectRef.current?.blur();\n selectRef.current?.focus();\n onClear?.();\n break;\n default:\n LOG.debug(`Unhandled action type '${actionMeta.action}'.`);\n break;\n }\n }\n );\n\n const selectRef = useRef<SelectInstance<SearchOption, false, SearchGroupOption>>(null);\n return (\n <Box {...containerProps}>\n <Select<SearchOption, false, SearchGroupOption>\n className=\"search-component\"\n classNamePrefix=\"react-select\"\n ref={selectRef}\n inputValue={input}\n onInputChange={handleInputChange}\n aria-label={intl.formatMessage({ id: \"ariaLabel.search\" })}\n ariaLiveMessages={ariaMessages}\n selectedOptionStyle=\"color\"\n selectedOptionColorPalette=\"colorPalette\"\n chakraStyles={chakraStyles}\n isClearable={true}\n placeholder={props.placeholder ?? intl.formatMessage({ id: \"searchPlaceholder\" })}\n closeMenuOnSelect={true}\n isLoading={search.kind === \"loading\"}\n options={search.kind === \"ready\" ? search.results : undefined}\n filterOption={() => true} // always show all options (don't filter based on input text)\n tabSelectsValue={false}\n components={components}\n onChange={handleSelectChange}\n value={selectedOption}\n menuPortalTarget={portalDiv.current}\n />\n <Portal>\n <chakra.div ref={portalDiv} className=\"search-component-menu\" />\n </Portal>\n </Box>\n );\n};\n\n/**\n * Provides custom aria messages for the select component.\n */\nfunction useAriaMessages(\n intl: PackageIntl\n): AriaLiveMessages<SearchOption, false, SearchGroupOption> {\n return useMemo(() => {\n /**\n * Method to create Aria-String for focus-Event\n */\n const onFocus: AriaOnFocus<SearchOption> = () => {\n //no aria string for focus-events because in some screen readers (NVDA) and browsers (Chrome) updating the aria string causes the instructions to be read out again each time a select option is focused\n return \"\";\n };\n\n /**\n * Method to create Aria-String for value-change-Event\n */\n const onChange: AriaOnChange<SearchOption, boolean> = () => {\n //no aria string for change-events because in some screen readers (NVDA) and browsers (Chrome) updating the aria string causes the instructions to be read out again each time a select option is focused\n return \"\";\n };\n\n /**\n * Method to create Aria-String for instruction\n */\n const guidance = () => {\n return `${intl.formatMessage({ id: \"ariaLabel.instructions\" })}`;\n };\n\n /**\n * Method to create Aria-String for result length\n */\n const onFilter = () => {\n return \"\";\n };\n\n return {\n onFocus,\n onChange,\n guidance,\n onFilter\n };\n }, [intl]);\n}\n\n/**\n * Customizes the inner components used by the select component.\n */\nfunction useCustomComponents(): SelectProps<SearchOption, false, SearchGroupOption>[\"components\"] {\n return useMemo(() => {\n return {\n Menu: MenuComp,\n Input: Input,\n SingleValue: SingleValueComp,\n Option: HighlightOption,\n NoOptionsMessage: NoOptionsMessage,\n LoadingMessage: LoadingMessage,\n ValueContainer: ValueContainer,\n IndicatorsContainer: IndicatorsContainer,\n ClearIndicator: ClearIndicator,\n Group: GroupComp\n };\n }, []);\n}\n\n/**\n * Customizes components styles within the select component.\n */\nfunction useChakraStyles() {\n const [groupHeadingBg, focussedItemBg, selectedItemBg] = useToken(\"colors\", [\n \"colorPalette.100\",\n \"colorPalette.50\",\n \"colorPalette.500\"\n ]);\n return useMemo(() => {\n const chakraStyles: ChakraStylesConfig<SearchOption, false, SearchGroupOption> = {\n control: (provided) => ({\n ...provided,\n paddingInline: 0\n }),\n inputContainer: (provided) => ({\n ...provided,\n gridTemplateAreas: \"'area area area'\",\n display: \"grid\"\n }),\n indicatorsContainer: (provided) => ({\n ...provided,\n // pointerEvents none can sneak in via chakra theme from <Select />\n pointerEvents: \"auto\"\n }),\n input: (provided) => ({\n ...provided,\n gridArea: \"area\"\n }),\n groupHeading: (provided) => ({\n ...provided,\n backgroundColor: groupHeadingBg,\n padding: \"8px 12px\",\n // make Header look like normal options:\n fontSize: \"inherit\",\n fontWeight: \"inherit\"\n }),\n option: (provided) => ({\n ...provided,\n backgroundColor: \"inherit\",\n _highlighted: {\n backgroundColor: focussedItemBg\n },\n _selected: {\n // Prevent white on white\n backgroundColor: selectedItemBg\n }\n }),\n dropdownIndicator: (provided) => ({\n ...provided,\n display: \"none\" // always hide\n })\n };\n return chakraStyles;\n }, [groupHeadingBg, focussedItemBg, selectedItemBg]);\n}\n\n/**\n * Creates a controller to search on the given sources.\n */\nfunction useController(\n sources: SearchSource[],\n searchTypingDelay: number | undefined,\n maxResultsPerGroup: number | undefined,\n map: MapModel | undefined\n) {\n const [controller, setController] = useState<SearchController | undefined>(undefined);\n useEffect(() => {\n if (!map) {\n return;\n }\n const controller = new SearchController(map, sources);\n setController(controller);\n return () => {\n controller.destroy();\n setController(undefined);\n };\n }, [map, sources]);\n\n useEffect(() => {\n if (controller) {\n controller.searchTypingDelay = searchTypingDelay;\n }\n }, [controller, searchTypingDelay]);\n useEffect(() => {\n if (controller) {\n controller.maxResultsPerSource = maxResultsPerGroup;\n }\n }, [controller, maxResultsPerGroup]);\n return controller;\n}\n\ntype SearchResultsReady = {\n kind: \"ready\";\n results: SearchGroupOption[];\n};\n\ntype SearchResultsLoading = {\n kind: \"loading\";\n};\n\ntype SearchResultsState = SearchResultsReady | SearchResultsLoading;\n\n/**\n * Keeps track of the current input text, active searches and their results.\n *\n * NOTE: it would be great to merge this state handling with the search controller\n * in a future revision.\n */\nfunction useSearchState(controller: SearchController | undefined) {\n interface FullSearchState {\n query: string;\n selectedOption: SearchOption | null;\n search: SearchResultsState;\n }\n\n type Action =\n | { kind: \"input\"; query: string }\n | { kind: \"select-option\"; option: SearchOption }\n | { kind: \"load-results\" }\n | { kind: \"accept-results\"; results: SearchGroupOption[] };\n\n const [state, dispatch] = useReducer(\n (current: FullSearchState, action: Action): FullSearchState => {\n switch (action.kind) {\n case \"input\":\n return {\n ...current,\n query: action.query,\n selectedOption: null\n };\n case \"select-option\":\n return {\n ...current,\n selectedOption: action.option,\n query: action.option.label\n };\n case \"load-results\":\n return {\n ...current,\n search: {\n kind: \"loading\"\n }\n };\n case \"accept-results\":\n return {\n ...current,\n search: {\n kind: \"ready\",\n results: action.results\n }\n };\n }\n },\n undefined,\n (): FullSearchState => ({\n query: \"\",\n selectedOption: null,\n search: {\n kind: \"ready\",\n results: []\n }\n })\n );\n\n // Stores the promise for the current search.\n // Any results from outdated searches are ignored.\n const currentSearch = useRef<Promise<unknown>>(undefined);\n const startSearch = useEvent((query: string) => {\n if (!controller) {\n currentSearch.current = undefined;\n dispatch({ kind: \"accept-results\", results: [] });\n return;\n }\n\n LOG.isDebug() && LOG.debug(`Starting new search for query ${JSON.stringify(query)}.`);\n dispatch({ kind: \"load-results\" });\n const promise = (currentSearch.current = search(controller, query).then((results) => {\n // Check if this job is still current\n if (currentSearch.current === promise) {\n dispatch({ kind: \"accept-results\", results });\n }\n }));\n });\n\n // Called when the user confirms a search result\n const onResultConfirmed = useCallback((option: SearchOption) => {\n // Do not start a new search when the user confirms a result\n dispatch({ kind: \"select-option\", option });\n }, []);\n\n // Called when a user types into the input field\n const onInputChanged = useCallback(\n (newValue: string) => {\n // Trigger a new search if the user changes the query by typing\n dispatch({ kind: \"input\", query: newValue });\n startSearch(newValue);\n },\n [startSearch]\n );\n\n return {\n input: state.query,\n search: state.search,\n selectedOption: state.selectedOption,\n onResultConfirmed,\n onInputChanged\n };\n}\n\nasync function search(controller: SearchController, query: string): Promise<SearchGroupOption[]> {\n let suggestions: SuggestionGroup[];\n try {\n suggestions = await controller.search(query);\n } catch (error) {\n if (!isAbortError(error)) {\n LOG.error(`Search failed`, error);\n }\n suggestions = [];\n }\n return mapSuggestions(suggestions);\n}\n\nfunction mapSuggestions(suggestions: SuggestionGroup[]): SearchGroupOption[] {\n const options = suggestions.map(\n (group, groupIndex): SearchGroupOption => ({\n label: group.label,\n options: group.results.map((suggestion): SearchOption => {\n return {\n value: `${groupIndex}-${suggestion.id}`,\n label: suggestion.label,\n source: group.source,\n result: suggestion\n };\n })\n })\n );\n return options;\n}\n"],"names":["search","SingleValueComp","controller"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/search",
4
- "version": "0.10.0",
4
+ "version": "0.11.0-dev.20250515143825",
5
5
  "description": "This package provides a UI component to perform a search on given search sources.",
6
6
  "keywords": [
7
7
  "open-pioneer-trails"
@@ -14,16 +14,17 @@
14
14
  "directory": "src/packages/search"
15
15
  },
16
16
  "dependencies": {
17
- "@chakra-ui/icons": "^2.2.4",
18
- "@open-pioneer/chakra-integration": "^3.1.0",
19
- "@open-pioneer/core": "^3.1.0",
20
- "@open-pioneer/react-utils": "^3.1.0",
21
- "@open-pioneer/runtime": "^3.1.0",
22
- "chakra-react-select": "^5.0.4",
17
+ "@chakra-ui/react": "^3.17.0",
18
+ "@open-pioneer/chakra-snippets": "4.0.0-dev.20250512105016",
19
+ "@open-pioneer/core": "4.0.0-dev.20250512105016",
20
+ "@open-pioneer/react-utils": "4.0.0-dev.20250512105016",
21
+ "@open-pioneer/runtime": "4.0.0-dev.20250512105016",
22
+ "chakra-react-select": "^6.1.0",
23
23
  "classnames": "^2.3.2",
24
24
  "ol": "^10.5.0",
25
25
  "react": "^19.1.0",
26
- "@open-pioneer/map": "^0.10.0"
26
+ "react-icons": "^5.3.0",
27
+ "@open-pioneer/map": "0.11.0-dev.20250515143825"
27
28
  },
28
29
  "exports": {
29
30
  "./package.json": "./package.json",
package/search.css CHANGED
@@ -2,19 +2,24 @@
2
2
  display: none;
3
3
  }
4
4
 
5
- .search-component .search-highlighted-match {
6
- font-weight: bold;
7
- }
8
-
9
5
  .search-component .search-value-container {
10
6
  cursor: text;
11
7
  padding-left: 30px !important;
12
8
  }
13
9
 
14
- .search-component .search-invisible {
10
+ .search-component-menu > * {
11
+ /* Render react-select's menu on top */
12
+ z-index: var(--chakra-z-index-modal) !important;
13
+ }
14
+
15
+ .search-component-menu .search-invisible {
15
16
  display: none;
16
17
  }
17
18
 
19
+ .search-component-menu .search-highlighted-match {
20
+ font-weight: bold;
21
+ }
22
+
18
23
  /* Exposition only
19
24
 
20
25
  .search-option {
package/search.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["search.css"],"names":[],"mappings":"AAAA;IACI,aAAa;AACjB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,YAAY;IACZ,6BAA6B;AACjC;;AAEA;IACI,aAAa;AACjB;;AAEA;;;;;;;;;GASG","file":"search.css","sourcesContent":[".search-component .chakra-divider {\n display: none;\n}\n\n.search-component .search-highlighted-match {\n font-weight: bold;\n}\n\n.search-component .search-value-container {\n cursor: text;\n padding-left: 30px !important;\n}\n\n.search-component .search-invisible {\n display: none;\n}\n\n/* Exposition only\n\n.search-option {\n}\n\n.search-no-match {\n}\n\n.search-loading-text {\n} */\n"]}
1
+ {"version":3,"sources":["search.css"],"names":[],"mappings":"AAAA;IACI,aAAa;AACjB;;AAEA;IACI,YAAY;IACZ,6BAA6B;AACjC;;AAEA;IACI,sCAAsC;IACtC,+CAA+C;AACnD;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;;;;;;;;;GASG","file":"search.css","sourcesContent":[".search-component .chakra-divider {\n display: none;\n}\n\n.search-component .search-value-container {\n cursor: text;\n padding-left: 30px !important;\n}\n\n.search-component-menu > * {\n /* Render react-select's menu on top */\n z-index: var(--chakra-z-index-modal) !important;\n}\n\n.search-component-menu .search-invisible {\n display: none;\n}\n\n.search-component-menu .search-highlighted-match {\n font-weight: bold;\n}\n\n/* Exposition only\n\n.search-option {\n}\n\n.search-no-match {\n}\n\n.search-loading-text {\n} */\n"]}