@telia-ace/knowledge-widget-components-search 1.0.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/LICENSE.txt ADDED
@@ -0,0 +1,6 @@
1
+ Copyright © 2021, Telia Company AB. All rights reserved.
2
+
3
+ THIS PACKAGE AND CONTAINING SOFTWARE IS PART OF
4
+ THE HUMANY SERVICE. BY USING THIS SOFTWARE YOU
5
+ AGREE TO THE FOLLOWING TERMS AND CONDITIONS:
6
+ http://www.humany.com/legal
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # `@telia-ace/widget-services`
2
+
3
+ Services for ACE Widgets.
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ declare type Props = {
3
+ inputHasFocus: boolean;
4
+ searchContainerRef: HTMLElement | null;
5
+ showGuideCategory: boolean;
6
+ showTag: boolean;
7
+ position: 'inside' | 'below';
8
+ };
9
+ declare const FilterBadges: React.FC<Props>;
10
+ export default FilterBadges;
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
+ return cooked;
5
+ };
6
+ var __assign = (this && this.__assign) || function () {
7
+ __assign = Object.assign || function(t) {
8
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
9
+ s = arguments[i];
10
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
11
+ t[p] = s[p];
12
+ }
13
+ return t;
14
+ };
15
+ return __assign.apply(this, arguments);
16
+ };
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ var __rest = (this && this.__rest) || function (s, e) {
41
+ var t = {};
42
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
43
+ t[p] = s[p];
44
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
45
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
46
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
47
+ t[p[i]] = s[p[i]];
48
+ }
49
+ return t;
50
+ };
51
+ var __read = (this && this.__read) || function (o, n) {
52
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
53
+ if (!m) return o;
54
+ var i = m.call(o), r, ar = [], e;
55
+ try {
56
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
57
+ }
58
+ catch (error) { e = { error: error }; }
59
+ finally {
60
+ try {
61
+ if (r && !r.done && (m = i["return"])) m.call(i);
62
+ }
63
+ finally { if (e) throw e.error; }
64
+ }
65
+ return ar;
66
+ };
67
+ Object.defineProperty(exports, "__esModule", { value: true });
68
+ var knowledge_widget_ui_1 = require("@telia-ace/knowledge-widget-ui");
69
+ var widget_utilities_1 = require("@telia-ace/widget-utilities");
70
+ var react_1 = __importStar(require("react"));
71
+ var styled_components_1 = __importStar(require("styled-components"));
72
+ var FilterBadge = function (_a) {
73
+ var text = _a.text, className = _a.className, forceFocusStyle = _a.forceFocusStyle, filterType = _a.filterType, handleClick = _a.handleClick, _b = _a.deleteAriaLabel, deleteAriaLabel = _b === void 0 ? '' : _b, p = __rest(_a, ["text", "className", "forceFocusStyle", "filterType", "handleClick", "deleteAriaLabel"]);
74
+ var ref = (0, react_1.useRef)();
75
+ return (react_1.default.createElement(knowledge_widget_ui_1.Text, { className: (0, widget_utilities_1.appendClassNames)(className, 'humany-filter-badge'), onKeyDown: function (e) {
76
+ if (e.key === 'Enter') {
77
+ handleClick(e, filterType);
78
+ }
79
+ } },
80
+ text,
81
+ react_1.default.createElement(knowledge_widget_ui_1.Link, __assign({}, p, { ref: ref, tabIndex: 0, role: "button", "aria-label": deleteAriaLabel.replace('{{item}}', text), onClick: function (e) { return handleClick(e, filterType); } }),
82
+ react_1.default.createElement(knowledge_widget_ui_1.SymbolBadge, { size: 13, symbol: { type: 'Svg', content: 'close' } }))));
83
+ };
84
+ var FilterBadges = function (_a) {
85
+ var inputHasFocus = _a.inputHasFocus, searchContainerRef = _a.searchContainerRef, showTag = _a.showTag, showGuideCategory = _a.showGuideCategory, position = _a.position;
86
+ var _b = (0, knowledge_widget_ui_1.useProperties)(), _c = _b.activeFilterBadges, activeFilterBadges = _c === void 0 ? {} : _c, _d = _b.deleteFilterBadgeAriaLabel, deleteFilterBadgeAriaLabel = _d === void 0 ? '' : _d;
87
+ var dispatch = (0, knowledge_widget_ui_1.useDispatch)();
88
+ var _e = (0, knowledge_widget_ui_1.useRouteData)(), name = _e.name, params = _e.params;
89
+ var _f = __read((0, react_1.useState)(false), 2), isNavigatingWithKeyBoard = _f[0], setIsNavigatingWithKeyboard = _f[1];
90
+ var onKeyDown = (0, react_1.useCallback)(function (event) {
91
+ var key = event.key;
92
+ if (['ArrowLeft', 'ArrowRight'].indexOf(key) === -1) {
93
+ setIsNavigatingWithKeyboard(false);
94
+ }
95
+ }, []);
96
+ (0, knowledge_widget_ui_1.useEventListener)('keydown', onKeyDown, window);
97
+ (0, knowledge_widget_ui_1.useEventListener)('click', onKeyDown, window);
98
+ var guideCategory = activeFilterBadges.guideCategory, tag = activeFilterBadges.tag, tooltip = activeFilterBadges.tooltip;
99
+ var getFocusedFilterBadge = function (container) {
100
+ var badges = container.querySelectorAll('.humany-filter-badge');
101
+ return {
102
+ badges: badges,
103
+ index: Array.from(badges).findIndex(function (e) { return document.activeElement === e; }),
104
+ };
105
+ };
106
+ var handleFilterBadgeClick = function (event, filterType) {
107
+ event.preventDefault();
108
+ dispatch('quick-filter:remove', { types: [filterType] });
109
+ };
110
+ var keyboardNavigation = function (direction, inputElem) {
111
+ if (!searchContainerRef) {
112
+ return;
113
+ }
114
+ var _a = getFocusedFilterBadge(searchContainerRef), badges = _a.badges, currentFocusedIndex = _a.index;
115
+ if (badges.length) {
116
+ var toFocus = null;
117
+ if (direction === 'left') {
118
+ if (currentFocusedIndex === -1) {
119
+ // if no badge is focused and direction is left
120
+ // focus last badge
121
+ toFocus = badges.item(badges.length - 1);
122
+ }
123
+ else if (currentFocusedIndex > 0) {
124
+ // if there are more badges to the left, go one step back
125
+ // do nothing if already focusing the most left badge
126
+ toFocus = badges.item(currentFocusedIndex - 1);
127
+ }
128
+ }
129
+ else if (direction === 'right') {
130
+ if (currentFocusedIndex === badges.length - 1) {
131
+ // if currently focusing the last badge, move focus to search input
132
+ inputElem && inputElem.focus();
133
+ }
134
+ else if (badges.item(currentFocusedIndex + 1)) {
135
+ toFocus = badges.item(currentFocusedIndex + 1);
136
+ }
137
+ }
138
+ if (toFocus) {
139
+ toFocus.focus();
140
+ setIsNavigatingWithKeyboard(true);
141
+ }
142
+ }
143
+ };
144
+ (0, knowledge_widget_ui_1.useKeyPress)('ArrowLeft', (0, react_1.useCallback)(function () {
145
+ if (!searchContainerRef) {
146
+ return;
147
+ }
148
+ var focusedBadgeIndex = getFocusedFilterBadge(searchContainerRef).index;
149
+ if (inputHasFocus || focusedBadgeIndex > -1) {
150
+ var inputElem = searchContainerRef.querySelector('[data-type="search"]');
151
+ var isAtBeginningOfInput = inputElem && inputElem.selectionStart !== null && inputElem.selectionStart <= 0;
152
+ var isFocusingAFilterBadge = focusedBadgeIndex > -1;
153
+ if (isAtBeginningOfInput || isFocusingAFilterBadge) {
154
+ keyboardNavigation('left', inputElem);
155
+ }
156
+ }
157
+ }, [inputHasFocus, searchContainerRef]));
158
+ (0, knowledge_widget_ui_1.useKeyPress)('ArrowRight', (0, react_1.useCallback)(function () {
159
+ if (!searchContainerRef) {
160
+ return;
161
+ }
162
+ var focusedBadgeIndex = getFocusedFilterBadge(searchContainerRef).index;
163
+ if (focusedBadgeIndex > -1) {
164
+ var inputElem = searchContainerRef.querySelector('[data-type="search"]');
165
+ var isFocusingAFilterBadge = focusedBadgeIndex > -1;
166
+ if (isFocusingAFilterBadge) {
167
+ keyboardNavigation('right', inputElem);
168
+ }
169
+ }
170
+ }, [searchContainerRef]));
171
+ (0, knowledge_widget_ui_1.useKeyPress)('Backspace', (0, react_1.useCallback)(function (event) {
172
+ if (!searchContainerRef) {
173
+ return;
174
+ }
175
+ var filtersToRemove = [];
176
+ var focusedBadgeIndex = getFocusedFilterBadge(searchContainerRef).index;
177
+ var inputElem = searchContainerRef.querySelector('[data-type="search"]');
178
+ var isFocusingAFilterBadge = focusedBadgeIndex > -1;
179
+ if (isFocusingAFilterBadge) {
180
+ if (focusedBadgeIndex === 0) {
181
+ if (showGuideCategory) {
182
+ filtersToRemove = ['guideCategory'];
183
+ }
184
+ else if (showTag) {
185
+ filtersToRemove = ['tag'];
186
+ }
187
+ }
188
+ else if (focusedBadgeIndex === 1) {
189
+ filtersToRemove = ['tag'];
190
+ }
191
+ }
192
+ else {
193
+ var isAtBeginningOfInput = inputElem &&
194
+ inputElem.selectionStart !== null &&
195
+ inputElem.selectionStart <= 0;
196
+ if (isAtBeginningOfInput) {
197
+ if (activeFilterBadges === null || activeFilterBadges === void 0 ? void 0 : activeFilterBadges.tag) {
198
+ filtersToRemove = ['tag'];
199
+ }
200
+ else if (activeFilterBadges === null || activeFilterBadges === void 0 ? void 0 : activeFilterBadges.guideCategory) {
201
+ filtersToRemove = ['guideCategory'];
202
+ }
203
+ }
204
+ }
205
+ if (filtersToRemove.length > 0) {
206
+ event.preventDefault();
207
+ dispatch('quick-filter:remove', { types: filtersToRemove });
208
+ }
209
+ }, [searchContainerRef, activeFilterBadges, showTag, showGuideCategory]));
210
+ var renderBadge = (0, react_1.useCallback)(function (type) {
211
+ if (type === 'guideCategory' && guideCategory && showGuideCategory) {
212
+ return (react_1.default.createElement(StyledFilterBadge, { text: "@".concat(guideCategory.title), routeName: name, filterType: "guideCategory", handleClick: handleFilterBadgeClick, forceFocusStyle: isNavigatingWithKeyBoard, deleteAriaLabel: deleteFilterBadgeAriaLabel, params: __assign(__assign({}, params), { guideCategory: undefined }) }));
213
+ }
214
+ if (type === 'tag' && tag && showTag) {
215
+ return (react_1.default.createElement(StyledFilterBadge, { className: "humany-filter-badge", text: "#".concat(tag.title), routeName: name, filterType: "tag", handleClick: handleFilterBadgeClick, forceFocusStyle: isNavigatingWithKeyBoard, deleteAriaLabel: deleteFilterBadgeAriaLabel, params: __assign(__assign({}, params), { tag: undefined }) }));
216
+ }
217
+ return null;
218
+ }, [guideCategory, tag, name, params, showGuideCategory, showTag, isNavigatingWithKeyBoard]);
219
+ if (!guideCategory && !tag) {
220
+ return null;
221
+ }
222
+ return (react_1.default.createElement(Wrapper, { className: "humany-filter-badges", position: position },
223
+ guideCategory && tooltip ? (react_1.default.createElement(knowledge_widget_ui_1.Tooltip, { content: react_1.default.createElement(react_1.default.Fragment, null, tooltip), sticky: false }, renderBadge('guideCategory'))) : (renderBadge('guideCategory')),
224
+ tag && renderBadge('tag')));
225
+ };
226
+ exports.default = FilterBadges;
227
+ var Wrapper = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n\n ", "\n"], ["\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n\n ", "\n"])), function (p) {
228
+ return p.position === 'inside'
229
+ ? (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n &:not(:first-child) {\n margin: 0 0 0 ", ";\n }\n "], ["\n &:not(:first-child) {\n margin: 0 0 0 ", ";\n }\n "])), function (p) { var _a; return (_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.normal; }) : (0, styled_components_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n margin: ", " 0 0 0;\n span:first-child {\n margin-left: 0;\n }\n "], ["\n margin: ", " 0 0 0;\n span:first-child {\n margin-left: 0;\n }\n "])), function (p) { var _a; return (_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.small; });
230
+ });
231
+ var StyledFilterBadge = (0, styled_components_1.default)(FilterBadge)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n padding: ", ";\n background-color: ", ";\n border-radius: ", ";\n font-weight: 300;\n font-size: ", ";\n font-style: italic;\n color: #ffffff;\n text-decoration: none;\n white-space: nowrap;\n\n margin: calc(", " / 2);\n\n &:focus-within {\n ", ";\n a {\n outline: none;\n }\n }\n\n svg {\n width: 17px;\n height: 11px;\n margin: 1px 0 0 ", ";\n path {\n stroke: #ffffff;\n stroke-width: 2px;\n }\n order: 1;\n }\n"], ["\n display: flex;\n align-items: center;\n padding: ", ";\n background-color: ", ";\n border-radius: ", ";\n font-weight: 300;\n font-size: ", ";\n font-style: italic;\n color: #ffffff;\n text-decoration: none;\n white-space: nowrap;\n\n margin: calc(", " / 2);\n\n &:focus-within {\n ", ";\n a {\n outline: none;\n }\n }\n\n svg {\n width: 17px;\n height: 11px;\n margin: 1px 0 0 ", ";\n path {\n stroke: #ffffff;\n stroke-width: 2px;\n }\n order: 1;\n }\n"])), function (p) { var _a, _b; return "".concat((_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.small, " calc(").concat((_b = p.theme.sizes) === null || _b === void 0 ? void 0 : _b.normal, "/2) "); }, function (p) { var _a; return (_a = p.theme.colors) === null || _a === void 0 ? void 0 : _a.primary; }, function (p) { return p.theme.borderRadius; }, function (p) { var _a; return (_a = p.theme.fonts) === null || _a === void 0 ? void 0 : _a.normal; }, function (p) { var _a; return (_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.small; }, function (p) {
232
+ var _a;
233
+ return (((_a = p.theme.accessibility) === null || _a === void 0 ? void 0 : _a.isTabbing) || p.forceFocusStyle) && (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n ", "\n background-color: transparent;\n\n svg {\n path {\n stroke: ", ";\n }\n }\n "], ["\n ", "\n background-color: transparent;\n\n svg {\n path {\n stroke: ", ";\n }\n }\n "])), knowledge_widget_ui_1.borderTabStyle, function (p) { var _a; return (_a = p.theme.colors) === null || _a === void 0 ? void 0 : _a.primary; });
234
+ }, function (p) { var _a; return (_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.small; });
235
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5;
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import SearchComponent from './search-component';
2
+ export default SearchComponent;
package/lib/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var search_component_1 = __importDefault(require("./search-component"));
7
+ exports.default = search_component_1.default;
@@ -0,0 +1,17 @@
1
+ import { Category, Tag } from '@telia-ace/knowledge-widget-core';
2
+ import React from 'react';
3
+ declare type Props = {
4
+ filterPhrase: string;
5
+ items: Category[] | Tag[];
6
+ filterType: 'guideCategory' | 'tag';
7
+ searchContainer: HTMLElement | null;
8
+ filterContainer: HTMLElement | null;
9
+ inputHasFocus: boolean;
10
+ };
11
+ export declare const getFocusedIndex: (elem: HTMLElement) => {
12
+ anchors: HTMLAnchorElement[];
13
+ focusedIndex: number;
14
+ };
15
+ export declare const focusInput: (searchContainerRef: HTMLElement | null) => void;
16
+ declare const QuickFilterItemList: React.FC<Props>;
17
+ export default QuickFilterItemList;
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
+ return cooked;
5
+ };
6
+ var __assign = (this && this.__assign) || function () {
7
+ __assign = Object.assign || function(t) {
8
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
9
+ s = arguments[i];
10
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
11
+ t[p] = s[p];
12
+ }
13
+ return t;
14
+ };
15
+ return __assign.apply(this, arguments);
16
+ };
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ var __read = (this && this.__read) || function (o, n) {
41
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
42
+ if (!m) return o;
43
+ var i = m.call(o), r, ar = [], e;
44
+ try {
45
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
46
+ }
47
+ catch (error) { e = { error: error }; }
48
+ finally {
49
+ try {
50
+ if (r && !r.done && (m = i["return"])) m.call(i);
51
+ }
52
+ finally { if (e) throw e.error; }
53
+ }
54
+ return ar;
55
+ };
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.focusInput = exports.getFocusedIndex = void 0;
58
+ var knowledge_widget_ui_1 = require("@telia-ace/knowledge-widget-ui");
59
+ var react_1 = __importStar(require("react"));
60
+ var styled_components_1 = __importStar(require("styled-components"));
61
+ var utils_1 = require("./utils");
62
+ var getFocusedIndex = function (elem) {
63
+ var anchors = Array.from((elem === null || elem === void 0 ? void 0 : elem.getElementsByTagName('A')) || []).filter(function (a) { return a.getAttribute('disabled') === null; });
64
+ return {
65
+ anchors: anchors,
66
+ focusedIndex: anchors.findIndex(function (e) { return document.activeElement === e; }),
67
+ };
68
+ };
69
+ exports.getFocusedIndex = getFocusedIndex;
70
+ var getInputElem = function (searchContainerRef) {
71
+ return searchContainerRef
72
+ ? searchContainerRef.querySelector('[data-type="search"], input[type="search"]')
73
+ : null;
74
+ };
75
+ var focusInput = function (searchContainerRef) {
76
+ if (!searchContainerRef) {
77
+ return;
78
+ }
79
+ var inputElem = getInputElem(searchContainerRef);
80
+ if (inputElem) {
81
+ inputElem.focus();
82
+ }
83
+ };
84
+ exports.focusInput = focusInput;
85
+ var QuickFilterItemList = function (_a) {
86
+ var filterPhrase = _a.filterPhrase, rawItems = _a.items, filterType = _a.filterType, filterContainer = _a.filterContainer, searchContainer = _a.searchContainer, inputHasFocus = _a.inputHasFocus;
87
+ var _b = __read((0, react_1.useState)(rawItems || []), 2), items = _b[0], setItems = _b[1];
88
+ var _c = __read((0, react_1.useState)(null), 2), first = _c[0], setFirst = _c[1];
89
+ var dispatch = (0, knowledge_widget_ui_1.useDispatch)();
90
+ var _d = (0, knowledge_widget_ui_1.useProperties)(), activeFilterBadges = _d.activeFilterBadges, quickFilters = _d.quickFilters;
91
+ var autoSelect = (typeof quickFilters === 'object' && !!quickFilters.autoSelect) ||
92
+ (typeof quickFilters === 'boolean' && !!quickFilters);
93
+ (0, react_1.useEffect)(function () {
94
+ setItems((0, utils_1.filterItems)(rawItems, filterType, filterPhrase));
95
+ }, [filterPhrase, filterType, rawItems]);
96
+ (0, react_1.useEffect)(function () {
97
+ var _a;
98
+ if (filterContainer) {
99
+ var anchors = (0, exports.getFocusedIndex)(filterContainer).anchors;
100
+ var id = (_a = anchors[0]) === null || _a === void 0 ? void 0 : _a.getAttribute('data-id');
101
+ if (id) {
102
+ setFirst(id);
103
+ }
104
+ }
105
+ }, [items, filterContainer]);
106
+ var handleItemClicked = (0, react_1.useCallback)(function (item, type) {
107
+ var data = {
108
+ category: (activeFilterBadges === null || activeFilterBadges === void 0 ? void 0 : activeFilterBadges.guideCategory)
109
+ ? activeFilterBadges.guideCategory.id
110
+ : undefined,
111
+ tag: (activeFilterBadges === null || activeFilterBadges === void 0 ? void 0 : activeFilterBadges.tag) ? activeFilterBadges.tag.id : undefined,
112
+ };
113
+ if (type === 'guideCategory') {
114
+ data.category = item.id;
115
+ }
116
+ else if (type === 'tag') {
117
+ data.tag = item.id;
118
+ }
119
+ dispatch('quick-filter:add', data);
120
+ }, [activeFilterBadges, dispatch]);
121
+ var buildListProps = function (type) {
122
+ if (type === 'guideCategory') {
123
+ return {
124
+ renderItem: function (item, level) { return (react_1.default.createElement(StyledLink, { autoSelect: autoSelect && inputHasFocus && item.id === first, disabled: !(0, utils_1.match)(item.title, filterPhrase), tabIndex: !(0, utils_1.match)(item.title, filterPhrase) ? -1 : 0, onKeyDown: function (e) {
125
+ if (e.key === 'Enter') {
126
+ handleItemClicked(item, type);
127
+ }
128
+ }, "data-level": level, onClick: function () {
129
+ handleItemClicked(item, type);
130
+ }, "data-id": item.id },
131
+ react_1.default.createElement(Title, { title: item.title, phrase: filterPhrase, matches: (0, utils_1.match)(item.title, filterPhrase) }))); },
132
+ };
133
+ }
134
+ return {
135
+ renderLi: true,
136
+ renderItem: function (item) { return (react_1.default.createElement(StyledLink, { autoSelect: autoSelect && inputHasFocus && item.id === first, onKeyDown: function (e) {
137
+ if (e.key === 'Enter') {
138
+ handleItemClicked(item, type);
139
+ }
140
+ }, onClick: function () {
141
+ handleItemClicked(item, type);
142
+ }, "data-id": item.id },
143
+ react_1.default.createElement(Title, { symbol: "#", title: item.title, phrase: filterPhrase, matches: (0, utils_1.match)(item.title, filterPhrase) }))); },
144
+ };
145
+ };
146
+ (0, knowledge_widget_ui_1.useEventListener)('keydown', function (e) {
147
+ var _a;
148
+ var key = e.key;
149
+ if (!filterContainer ||
150
+ !(key === 'ArrowDown' || key === 'ArrowUp' || key === 'Enter')) {
151
+ return;
152
+ }
153
+ var _b = (0, exports.getFocusedIndex)(filterContainer), anchors = _b.anchors, focusedIndex = _b.focusedIndex;
154
+ if (key === 'Enter') {
155
+ if (inputHasFocus && autoSelect) {
156
+ var id = (_a = anchors[0]) === null || _a === void 0 ? void 0 : _a.getAttribute('data-id');
157
+ if (id) {
158
+ handleItemClicked({ id: id }, filterType);
159
+ }
160
+ }
161
+ return;
162
+ }
163
+ var focusFirst = function () { var _a; return (_a = anchors[0]) === null || _a === void 0 ? void 0 : _a.focus(); };
164
+ var focusLast = function () { var _a; return (_a = anchors[anchors.length - 1]) === null || _a === void 0 ? void 0 : _a.focus(); };
165
+ var focusNext = function () { var _a; return (_a = anchors[focusedIndex + 1]) === null || _a === void 0 ? void 0 : _a.focus(); };
166
+ var focusPrev = function () { var _a; return (_a = anchors[focusedIndex - 1]) === null || _a === void 0 ? void 0 : _a.focus(); };
167
+ if (inputHasFocus) {
168
+ // Input is focused
169
+ e.preventDefault();
170
+ if (key === 'ArrowDown') {
171
+ focusFirst();
172
+ }
173
+ else {
174
+ focusLast();
175
+ }
176
+ }
177
+ else if (focusedIndex > -1) {
178
+ // A quick-filter-item is focused
179
+ e.preventDefault();
180
+ if (key === 'ArrowDown') {
181
+ if (anchors.length > focusedIndex + 1) {
182
+ focusNext();
183
+ }
184
+ else {
185
+ (0, exports.focusInput)(searchContainer);
186
+ }
187
+ }
188
+ else {
189
+ if (focusedIndex - 1 < 0) {
190
+ (0, exports.focusInput)(searchContainer);
191
+ }
192
+ else {
193
+ focusPrev();
194
+ }
195
+ }
196
+ }
197
+ }, window);
198
+ return (react_1.default.createElement(knowledge_widget_ui_1.ItemTree, __assign({ tree: items, renderEmpty: false, ulProps: { role: 'listbox' }, liProps: { role: 'option' } }, buildListProps(filterType))));
199
+ };
200
+ exports.default = QuickFilterItemList;
201
+ var Title = function (_a) {
202
+ var title = _a.title, phrase = _a.phrase, matches = _a.matches, _b = _a.symbol, symbol = _b === void 0 ? '' : _b;
203
+ var createTitle = function () {
204
+ if (!matches || !phrase) {
205
+ return [title];
206
+ }
207
+ var index = title.toLowerCase().indexOf(phrase.toLowerCase());
208
+ var start = title.substr(0, index);
209
+ var bold = title.slice(index, index + phrase.length);
210
+ var end = title.substr(index + phrase.length);
211
+ return [start, bold, end];
212
+ };
213
+ var _c = __read(createTitle(), 3), start = _c[0], bold = _c[1], end = _c[2];
214
+ return (react_1.default.createElement(knowledge_widget_ui_1.Text, null,
215
+ symbol,
216
+ start,
217
+ bold ? react_1.default.createElement("strong", null, bold) : null,
218
+ end ? end : null));
219
+ };
220
+ var disabledCss = (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n opacity: 0.5;\n pointer-events: none;\n"], ["\n opacity: 0.5;\n pointer-events: none;\n"])));
221
+ var focused = (0, styled_components_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n background-color: ", ";\n color: #ffffff;\n outline: none;\n\n span:first-child {\n border-color: ", ";\n }\n"], ["\n background-color: ", ";\n color: #ffffff;\n outline: none;\n\n span:first-child {\n border-color: ", ";\n }\n"])), function (p) { var _a; return (_a = p.theme.colors) === null || _a === void 0 ? void 0 : _a.text; }, function (p) { var _a; return (_a = p.theme.colors) === null || _a === void 0 ? void 0 : _a.text; });
222
+ var StyledLink = (0, styled_components_1.default)(knowledge_widget_ui_1.Link)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n display: block;\n text-decoration: none;\n font-size: ", ";\n\n ", "\n color: ", ";\n background-color: transparent;\n\n span {\n display: block;\n ", "\n ", "\n }\n\n span:first-child {\n border-color: #e7e7e7;\n }\n\n ", "\n\n ", "\n\n &:hover,\n &:focus {\n ", "\n }\n"], ["\n display: block;\n text-decoration: none;\n font-size: ", ";\n\n ", "\n color: ", ";\n background-color: transparent;\n\n span {\n display: block;\n ", "\n ", "\n }\n\n span:first-child {\n border-color: #e7e7e7;\n }\n\n ", "\n\n ", "\n\n &:hover,\n &:focus {\n ", "\n }\n"])), function (p) { var _a; return (_a = p.theme.fonts) === null || _a === void 0 ? void 0 : _a.normal; }, function (p) { return p.disabled && disabledCss; }, function (p) { var _a; return (_a = p.theme.colors) === null || _a === void 0 ? void 0 : _a.text; }, function (p) {
223
+ var _a, _b, _c, _d;
224
+ return p['data-level']
225
+ ? "padding: calc(".concat((_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.normal, " / 2) ").concat((_b = p.theme.sizes) === null || _b === void 0 ? void 0 : _b.normal, ";")
226
+ : "padding: calc(".concat((_c = p.theme.sizes) === null || _c === void 0 ? void 0 : _c.normal, " / 2) ").concat((_d = p.theme.sizes) === null || _d === void 0 ? void 0 : _d.medium, "; ");
227
+ }, function (p) { return p['data-level'] && 'border-left: 2px solid'; }, function (p) { var _a; return p['data-level'] && "padding: 0 calc(".concat((_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.medium, " * ").concat(p['data-level'], ");"); }, function (p) { return p.autoSelect && focused; }, focused);
228
+ var templateObject_1, templateObject_2, templateObject_3;
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ declare type Props = {
3
+ phrase: string;
4
+ inputHasFocus: boolean;
5
+ searchContainerRef: HTMLElement | null;
6
+ };
7
+ declare const _default: ({ phrase, inputHasFocus, searchContainerRef }: Props) => JSX.Element | null;
8
+ export default _default;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
+ return cooked;
5
+ };
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || function (mod) {
23
+ if (mod && mod.__esModule) return mod;
24
+ var result = {};
25
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
26
+ __setModuleDefault(result, mod);
27
+ return result;
28
+ };
29
+ var __read = (this && this.__read) || function (o, n) {
30
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
31
+ if (!m) return o;
32
+ var i = m.call(o), r, ar = [], e;
33
+ try {
34
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
35
+ }
36
+ catch (error) { e = { error: error }; }
37
+ finally {
38
+ try {
39
+ if (r && !r.done && (m = i["return"])) m.call(i);
40
+ }
41
+ finally { if (e) throw e.error; }
42
+ }
43
+ return ar;
44
+ };
45
+ var __importDefault = (this && this.__importDefault) || function (mod) {
46
+ return (mod && mod.__esModule) ? mod : { "default": mod };
47
+ };
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ var knowledge_widget_ui_1 = require("@telia-ace/knowledge-widget-ui");
50
+ var widget_utilities_1 = require("@telia-ace/widget-utilities");
51
+ var react_1 = __importStar(require("react"));
52
+ var styled_components_1 = __importDefault(require("styled-components"));
53
+ var quick_filter_item_list_1 = __importStar(require("./quick-filter-item-list"));
54
+ exports.default = (function (_a) {
55
+ var _b = _a.phrase, phrase = _b === void 0 ? '' : _b, inputHasFocus = _a.inputHasFocus, searchContainerRef = _a.searchContainerRef;
56
+ var _c = (0, knowledge_widget_ui_1.useProperties)().quickFilter, quickFilter = _c === void 0 ? {
57
+ open: false,
58
+ loading: false,
59
+ symbol: '',
60
+ type: '',
61
+ items: [],
62
+ } : _c;
63
+ var _d = __read((0, knowledge_widget_ui_1.useScroll)(true), 2), css = _d[0], ref = _d[1];
64
+ var container = (0, knowledge_widget_ui_1.useContainer)();
65
+ var events = container.get('$widget').events;
66
+ var wrapperRef = (0, react_1.useRef)();
67
+ var setWrapperRef = (0, react_1.useCallback)(function (node) {
68
+ if (node) {
69
+ node.addEventListener('keydown', function () {
70
+ var listItemFocused = (0, quick_filter_item_list_1.getFocusedIndex)(node).focusedIndex > -1;
71
+ if (listItemFocused) {
72
+ events.subscribeOnce('router:changed', function () {
73
+ (0, quick_filter_item_list_1.focusInput)(searchContainerRef);
74
+ });
75
+ }
76
+ }, true);
77
+ }
78
+ wrapperRef.current = node;
79
+ return node;
80
+ }, [searchContainerRef]);
81
+ var _e = quickFilter.items, items = _e === void 0 ? [] : _e, symbol = quickFilter.symbol, type = quickFilter.type, open = quickFilter.open, loading = quickFilter.loading;
82
+ if (!open || !symbol) {
83
+ return null;
84
+ }
85
+ var filterPhrase = phrase.slice(phrase.indexOf(symbol) + 1);
86
+ return (react_1.default.createElement(Wrapper, { ref: setWrapperRef, "data-loading": loading, className: (0, widget_utilities_1.appendClassNames)('humany-quick-filter-dropdown', [type === 'guideCategory', 'humany-quick-filter-guide-categories'], [type === 'tag', 'humany-quick-filter-tags']) },
87
+ react_1.default.createElement(Inner, { className: "humany-quick-filter-dropdown-inner", css: css, ref: ref },
88
+ react_1.default.createElement(quick_filter_item_list_1.default, { filterType: type, items: items, filterPhrase: filterPhrase, filterContainer: ref.current, searchContainer: searchContainerRef, inputHasFocus: inputHasFocus })),
89
+ react_1.default.createElement(knowledge_widget_ui_1.Loader, { loading: loading })));
90
+ });
91
+ var Wrapper = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n ", ";\n position: absolute;\n top: calc(100% + ", ");\n left: 0;\n right: 0;\n z-index: 1;\n overflow: hidden;\n"], ["\n ", ";\n position: absolute;\n top: calc(100% + ", ");\n left: 0;\n right: 0;\n z-index: 1;\n overflow: hidden;\n"])), knowledge_widget_ui_1.contentBox, function (p) { var _a; return (_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.normal; });
92
+ var Inner = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n max-height: 300px;\n overflow: auto;\n padding: ", " 0;\n ", "\n ul {\n list-style: none;\n padding: 0;\n margin: 0;\n }\n li div {\n ", "\n }\n"], ["\n max-height: 300px;\n overflow: auto;\n padding: ", " 0;\n ", "\n ul {\n list-style: none;\n padding: 0;\n margin: 0;\n }\n li div {\n ", "\n }\n"])), function (p) { var _a; return (_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.medium; }, function (p) { return p.css; }, function (p) { var _a; return "margin: ".concat((_a = p.theme.sizes) === null || _a === void 0 ? void 0 : _a.normal, " 0;"); });
93
+ var templateObject_1, templateObject_2;