@linzjs/lui 23.11.2 → 23.13.0

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,3 +1,17 @@
1
+ # [23.13.0](https://github.com/linz/lui/compare/v23.12.0...v23.13.0) (2025-10-08)
2
+
3
+
4
+ ### Features
5
+
6
+ * **LuiSearchInput:** add 2 new optional variations to support design for CS-8444 ([#1256](https://github.com/linz/lui/issues/1256)) ([469f0b7](https://github.com/linz/lui/commit/469f0b7747e8e94a3436dca2f8086eae8f2ee198))
7
+
8
+ # [23.12.0](https://github.com/linz/lui/compare/v23.11.2...v23.12.0) (2025-10-06)
9
+
10
+
11
+ ### Features
12
+
13
+ * SURVEY-27089 add LuiPermissionDeniedPage ([#1250](https://github.com/linz/lui/issues/1250)) ([82caf9d](https://github.com/linz/lui/commit/82caf9ded76bfc7a4dd5b466a86cfd5a5a358e0b))
14
+
1
15
  ## [23.11.2](https://github.com/linz/lui/compare/v23.11.1...v23.11.2) (2025-10-02)
2
16
 
3
17
 
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
+ import { LuiErrorIllustrationType } from './LuiErrorIllustration';
2
3
  export declare const LuiErrorPage: React.FC<React.PropsWithChildren<{
3
4
  header?: React.ReactElement;
4
5
  footer?: React.ReactElement;
5
6
  content?: React.ReactElement;
6
7
  illustration?: React.ReactElement;
8
+ type?: LuiErrorIllustrationType;
7
9
  }>>;
@@ -23,5 +23,7 @@ export interface ISearchInputProps<SearchResult extends ISearchResult = ISearchR
23
23
  validateInput?: (input: string) => InputValidationResult | undefined;
24
24
  hideDisclaimerOnFail?: boolean;
25
25
  hideNoOptionsMessage?: boolean;
26
+ hideSearchIcon?: boolean;
27
+ filterElement?: ReactElement;
26
28
  }
27
29
  export declare const LuiSearchInput: <SearchResult extends ISearchResult = ISearchResult>(props: React.PropsWithChildren<ISearchInputProps<SearchResult>>) => JSX.Element;
package/dist/index.js CHANGED
@@ -17844,8 +17844,13 @@ var LuiSearchInput = function (props) {
17844
17844
  if (props.focusUpdate !== undefined)
17845
17845
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
17846
17846
  }, [props.focusUpdate]);
17847
- //clear result after search types changed
17848
17847
  React.useEffect(function () {
17848
+ //if there is a filter under way, recalculate the results
17849
+ if (props.filterElement) {
17850
+ retrieveResults(typedValue);
17851
+ return;
17852
+ }
17853
+ //if there is not a filter under way, then the results are no longer valid, clear them
17849
17854
  setResults([]);
17850
17855
  }, [props.getOptions]);
17851
17856
  React.useEffect(function () {
@@ -18004,16 +18009,36 @@ var LuiSearchInput = function (props) {
18004
18009
  }
18005
18010
  return null;
18006
18011
  }
18012
+ var filterRef = React.useRef(null);
18013
+ function determineFilterElement() {
18014
+ if (props.filterElement && haveFocus && results.length > 0) {
18015
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
18016
+ React__default["default"].createElement("hr", { className: "LuiSearchInput-resultSeparator" }),
18017
+ React__default["default"].createElement("div", { ref: filterRef, tabIndex: -1, "data-testid": "filter", className: "LuiSearchInput-filter" }, props.filterElement)));
18018
+ }
18019
+ return null;
18020
+ }
18007
18021
  return props.onSearch ? (React__default["default"].createElement(ControlledPassiveSearchInputComponent, __assign({ typedValue: typedValue, setTypedValue: setTypedValue }, props, { minCharactersForSearch: props.minCharactersForSearch, placeholderText: props.placeholderText, onSearch: props.onSearch, disclaimer: props.disclaimer, initialValue: props.initialValue, inputTransformer: props.inputTransformer, focusUpdate: props.focusUpdate, onClearCallback: props.onClearCallback, onClickInput: props.onClickInput, validateInput: props.validateInput }))) : (React__default["default"].createElement("div", { className: "LuiSearchInput", onClick: props.onClickInput },
18008
18022
  React__default["default"].createElement("span", { className: "LuiSearchInput-inputWrapper" },
18009
- searchIcon,
18010
- React__default["default"].createElement("input", { type: "text", className: clsx('LuiSearchInput-input'), ref: inputRef, value: typedValue, placeholder: props.placeholderText, "aria-label": "Search", onChange: function (e) { return setInputValue(e.target.value); }, onKeyDown: handleKeyDown, onFocus: function (e) {
18023
+ !props.hideSearchIcon && searchIcon,
18024
+ React__default["default"].createElement("input", { type: "text", className: clsx("LuiSearchInput-input ".concat(props.hideSearchIcon ? 'LuiSearchInput-input-hiddenIcon' : '')), ref: inputRef, value: typedValue, placeholder: props.placeholderText, "aria-label": "Search", onChange: function (e) {
18025
+ setInputValue(e.target.value);
18026
+ }, onKeyDown: handleKeyDown, onFocus: function (e) {
18011
18027
  e.target.select();
18012
18028
  retrieveResults(typedValue);
18013
18029
  setHaveFocus(true);
18014
18030
  }, style: { pointerEvents: props.externalSearch ? 'none' : 'auto' },
18015
18031
  // This timeout could be a little brittle but allows the menu to stay open long enough to click it
18016
- onBlur: function () { return setTimeout(function () { return setHaveFocus(false); }, 200); }, disabled: props.externalSearch }),
18032
+ onBlur: function (event) {
18033
+ // retain haveFocus while interacting with any supplied filter element
18034
+ // this is not a perfect solution, the filter ref will still get the focus, and maybe not have an onBlur
18035
+ if (filterRef.current &&
18036
+ event.relatedTarget === filterRef.current) {
18037
+ return;
18038
+ }
18039
+ // otherwise set the focus to false (close the results etc)
18040
+ setTimeout(function () { return setHaveFocus(false); }, 200);
18041
+ }, disabled: props.externalSearch }),
18017
18042
  cancelIcon),
18018
18043
  (isLoading || results.length > 0) && haveFocus && (React__default["default"].createElement("div", null,
18019
18044
  React__default["default"].createElement(ResultsDisplay, { results: results, selectedId: selectedId, setSelectedId: setSelectedId, selectedRef: selectedRef, onClick: selectItem, isLoading: isLoading, renderItem: props.renderItem }))),
@@ -18024,7 +18049,8 @@ var LuiSearchInput = function (props) {
18024
18049
  noOptionsMessage(typedValue) && (React__default["default"].createElement(React__default["default"].Fragment, null,
18025
18050
  React__default["default"].createElement("hr", { className: "LuiSearchInput-resultSeparator" }),
18026
18051
  React__default["default"].createElement("div", { "data-testid": "no-result-msg", className: "LuiSearchInput-disclaimer" }, noOptionsMessage(typedValue)))),
18027
- determineDisclaimer()));
18052
+ determineDisclaimer(),
18053
+ determineFilterElement()));
18028
18054
  };
18029
18055
 
18030
18056
  var resultStyle = { verticalAlign: 'middle' };
@@ -18239,7 +18265,7 @@ var LuiErrorPage = function (props) {
18239
18265
  props.header,
18240
18266
  React__default["default"].createElement("div", { className: "LuiErrorPage-wrapper" },
18241
18267
  React__default["default"].createElement("div", { className: 'LuiErrorPage-content' }, props.content),
18242
- React__default["default"].createElement("div", { className: 'LuiErrorPage-image' }, props.illustration ? props.illustration : React__default["default"].createElement(LuiErrorIllustration, null))),
18268
+ React__default["default"].createElement("div", { className: 'LuiErrorPage-image' }, props.illustration ? (props.illustration) : (React__default["default"].createElement(LuiErrorIllustration, { type: props.type })))),
18243
18269
  props.footer));
18244
18270
  };
18245
18271