@reltio/components 1.4.1938 → 1.4.1940
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/cjs/AttributesFiltersButton/AttributesFiltersButton.d.ts +4 -1
- package/cjs/AttributesFiltersButton/AttributesFiltersButton.js +9 -8
- package/cjs/AttributesFiltersButton/AttributesFiltersButton.test.js +15 -0
- package/cjs/EmptyState/styles.d.ts +1 -1
- package/cjs/SearchInput/SearchInput.d.ts +2 -1
- package/cjs/SearchInput/SearchInput.js +4 -2
- package/cjs/SearchInput/SearchInput.spec.js +115 -35
- package/cjs/types/index.d.ts +1 -0
- package/esm/AttributesFiltersButton/AttributesFiltersButton.d.ts +4 -1
- package/esm/AttributesFiltersButton/AttributesFiltersButton.js +9 -8
- package/esm/AttributesFiltersButton/AttributesFiltersButton.test.js +15 -0
- package/esm/EmptyState/styles.d.ts +1 -1
- package/esm/SearchInput/SearchInput.d.ts +2 -1
- package/esm/SearchInput/SearchInput.js +4 -2
- package/esm/SearchInput/SearchInput.spec.js +115 -35
- package/esm/types/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -16,10 +16,13 @@ type Props = {
|
|
|
16
16
|
onTogglePopup?: (open: boolean) => void;
|
|
17
17
|
isFiltersApplied?: boolean;
|
|
18
18
|
dataReltioId?: string;
|
|
19
|
+
ButtonIcon?: React.ElementType;
|
|
19
20
|
onFilterAttributeChange?: (attrSelectInfo: AttributeSelectionInfo) => void;
|
|
20
21
|
onClear?: () => void;
|
|
21
22
|
onCancel?: () => void;
|
|
22
23
|
onApply?: () => void;
|
|
24
|
+
popoverAnchorRef?: React.MutableRefObject<HTMLDivElement>;
|
|
25
|
+
title?: string;
|
|
23
26
|
};
|
|
24
|
-
declare const _default: React.MemoExoticComponent<({ filters: filtersProp, classes, attributesTypesGroups, attributesTypesGroupFilter, onChange, components, children, onTogglePopup, isFiltersApplied: isFiltersAppliedProp, dataReltioId, onFilterAttributeChange, onCancel, onClear, onApply }: Props) => JSX.Element>;
|
|
27
|
+
declare const _default: React.MemoExoticComponent<({ filters: filtersProp, classes, attributesTypesGroups, attributesTypesGroupFilter, onChange, components, children, onTogglePopup, isFiltersApplied: isFiltersAppliedProp, dataReltioId, onFilterAttributeChange, onCancel, onClear, onApply, ButtonIcon, popoverAnchorRef, title }: Props) => JSX.Element>;
|
|
25
28
|
export default _default;
|
|
@@ -39,11 +39,12 @@ var AttributesFiltersBuilder_1 = require("../AttributesFiltersBuilder");
|
|
|
39
39
|
var ActionButtons_1 = require("./components/ActionButtons/");
|
|
40
40
|
var styles_1 = require("./styles");
|
|
41
41
|
var AttributesFiltersButton = function (_a) {
|
|
42
|
-
var
|
|
42
|
+
var _b;
|
|
43
|
+
var filtersProp = _a.filters, classes = _a.classes, attributesTypesGroups = _a.attributesTypesGroups, attributesTypesGroupFilter = _a.attributesTypesGroupFilter, onChange = _a.onChange, components = _a.components, children = _a.children, onTogglePopup = _a.onTogglePopup, isFiltersAppliedProp = _a.isFiltersApplied, dataReltioId = _a.dataReltioId, onFilterAttributeChange = _a.onFilterAttributeChange, onCancel = _a.onCancel, onClear = _a.onClear, onApply = _a.onApply, _c = _a.ButtonIcon, ButtonIcon = _c === void 0 ? FilterList_1.default : _c, popoverAnchorRef = _a.popoverAnchorRef, title = _a.title;
|
|
43
44
|
var styles = (0, styles_1.useStyles)();
|
|
44
45
|
var buttonRef = (0, react_1.useRef)();
|
|
45
|
-
var
|
|
46
|
-
var
|
|
46
|
+
var _d = (0, react_1.useState)(false), isOpen = _d[0], setIsOpen = _d[1];
|
|
47
|
+
var _e = (0, react_1.useState)([]), filters = _e[0], setFilters = _e[1];
|
|
47
48
|
var isFiltersApplied = isFiltersAppliedProp !== null && isFiltersAppliedProp !== void 0 ? isFiltersAppliedProp : !!(0, mdm_sdk_1.buildFilterQueryString)()(filtersProp);
|
|
48
49
|
var buttonColor = isFiltersApplied ? 'primary' : 'inherit';
|
|
49
50
|
var togglePopup = function () {
|
|
@@ -72,19 +73,19 @@ var AttributesFiltersButton = function (_a) {
|
|
|
72
73
|
}, [onClear]);
|
|
73
74
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
74
75
|
react_1.default.createElement(Button_1.default, { "data-reltio-id": dataReltioId, ref: buttonRef, color: buttonColor, classes: {
|
|
75
|
-
root: styles.triggerButton,
|
|
76
|
+
root: (0, classnames_1.default)(styles.triggerButton, classes === null || classes === void 0 ? void 0 : classes.triggerButton),
|
|
76
77
|
textPrimary: styles.changedFiltersIndicator
|
|
77
78
|
}, onClick: togglePopup },
|
|
78
|
-
react_1.default.createElement(
|
|
79
|
-
react_1.default.createElement(Popover_1.default, { open: isOpen, classes: { paper: (0, classnames_1.default)(styles.popupContent, classes === null || classes === void 0 ? void 0 : classes.filterPopup) }, anchorEl: buttonRef.current, onClose: togglePopup, anchorOrigin: {
|
|
79
|
+
react_1.default.createElement(ButtonIcon, { color: buttonColor })),
|
|
80
|
+
react_1.default.createElement(Popover_1.default, { open: isOpen, classes: { paper: (0, classnames_1.default)(styles.popupContent, classes === null || classes === void 0 ? void 0 : classes.filterPopup) }, anchorEl: (_b = popoverAnchorRef === null || popoverAnchorRef === void 0 ? void 0 : popoverAnchorRef.current) !== null && _b !== void 0 ? _b : buttonRef.current, onClose: togglePopup, anchorOrigin: {
|
|
80
81
|
vertical: 'bottom',
|
|
81
|
-
horizontal: 'right'
|
|
82
|
+
horizontal: (popoverAnchorRef === null || popoverAnchorRef === void 0 ? void 0 : popoverAnchorRef.current) ? 'left' : 'right'
|
|
82
83
|
}, transformOrigin: {
|
|
83
84
|
vertical: 'top',
|
|
84
85
|
horizontal: 'left'
|
|
85
86
|
} },
|
|
86
87
|
react_1.default.createElement(react_1.default.Fragment, null,
|
|
87
|
-
react_1.default.createElement(Typography_1.default, { variant: "h6" }, ui_i18n_1.default.text('Filter')),
|
|
88
|
+
react_1.default.createElement(Typography_1.default, { variant: "h6" }, title !== null && title !== void 0 ? title : ui_i18n_1.default.text('Filter')),
|
|
88
89
|
react_1.default.createElement("div", { className: styles.filtersBuilderWrapper },
|
|
89
90
|
children,
|
|
90
91
|
react_1.default.createElement(AttributesFiltersBuilder_1.AttributesFiltersBuilder, { attributesTypesGroups: attributesTypesGroups, attributesTypesGroupFilter: attributesTypesGroupFilter, filters: filters, onChange: setFilters, components: components, onFilterAttributeChange: onFilterAttributeChange, classes: classes })),
|
|
@@ -247,4 +247,19 @@ describe('AttributesFiltersButton tests', function () {
|
|
|
247
247
|
}
|
|
248
248
|
});
|
|
249
249
|
}); });
|
|
250
|
+
it('should use title if defined', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
251
|
+
var title, user;
|
|
252
|
+
return __generator(this, function (_a) {
|
|
253
|
+
switch (_a.label) {
|
|
254
|
+
case 0:
|
|
255
|
+
title = 'TestTitle';
|
|
256
|
+
user = setUp(__assign(__assign({}, defaultProps), { title: title })).user;
|
|
257
|
+
return [4 /*yield*/, user.click(react_2.screen.getByRole('button'))];
|
|
258
|
+
case 1:
|
|
259
|
+
_a.sent();
|
|
260
|
+
expect(react_2.screen.getByText(title)).toBeInTheDocument();
|
|
261
|
+
return [2 /*return*/];
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}); });
|
|
250
265
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"button" | "text" | "small" | "root" | "
|
|
1
|
+
export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"button" | "text" | "small" | "root" | "embedded" | "root_small" | "full" | "textBox" | "secondaryText">;
|
|
@@ -7,6 +7,7 @@ type Props = InputProps & {
|
|
|
7
7
|
rootRef?: React.MutableRefObject<HTMLInputElement>;
|
|
8
8
|
height: number;
|
|
9
9
|
placeholder?: string;
|
|
10
|
+
endAdornmentContent?: React.ReactNode;
|
|
10
11
|
};
|
|
11
|
-
declare const _default: React.MemoExoticComponent<({ value, autofocus, onSearch, rootRef, classes, height, placeholder, ...otherProps }: Props) => JSX.Element>;
|
|
12
|
+
declare const _default: React.MemoExoticComponent<({ value, autofocus, onSearch, rootRef, classes, height, placeholder, endAdornmentContent, ...otherProps }: Props) => JSX.Element>;
|
|
12
13
|
export default _default;
|
|
@@ -60,13 +60,15 @@ var events_1 = require("../helpers/events");
|
|
|
60
60
|
var SmallIconButton_1 = require("../SmallIconButton");
|
|
61
61
|
var styles_1 = require("./styles");
|
|
62
62
|
var SearchInput = function (_a) {
|
|
63
|
-
var value = _a.value, autofocus = _a.autofocus, _b = _a.onSearch, onSearch = _b === void 0 ? ramda_1.identity : _b, rootRef = _a.rootRef, _c = _a.classes, classes = _c === void 0 ? {} : _c, height = _a.height, _d = _a.placeholder, placeholder = _d === void 0 ? ui_i18n_1.default.text('Search') : _d, otherProps = __rest(_a, ["value", "autofocus", "onSearch", "rootRef", "classes", "height", "placeholder"]);
|
|
63
|
+
var value = _a.value, autofocus = _a.autofocus, _b = _a.onSearch, onSearch = _b === void 0 ? ramda_1.identity : _b, rootRef = _a.rootRef, _c = _a.classes, classes = _c === void 0 ? {} : _c, height = _a.height, _d = _a.placeholder, placeholder = _d === void 0 ? ui_i18n_1.default.text('Search') : _d, endAdornmentContent = _a.endAdornmentContent, otherProps = __rest(_a, ["value", "autofocus", "onSearch", "rootRef", "classes", "height", "placeholder", "endAdornmentContent"]);
|
|
64
64
|
var styles = (0, styles_1.useStyles)({ height: height });
|
|
65
65
|
var _e = (0, react_1.useState)(''), localValue = _e[0], setLocalValue = _e[1];
|
|
66
66
|
var updateValue = (0, ramda_1.pipe)((0, ramda_1.tap)(onSearch), setLocalValue);
|
|
67
67
|
var clearValue = function () { return updateValue(''); };
|
|
68
68
|
var inputValue = (0, ramda_1.isNil)(value) ? localValue : value;
|
|
69
69
|
return (react_1.default.createElement(Input_1.default, __assign({ startAdornment: react_1.default.createElement(InputAdornment_1.default, { position: "start" },
|
|
70
|
-
react_1.default.createElement(Search_1.default, { className: styles.icon })), endAdornment: react_1.default.createElement(InputAdornment_1.default, { position: "end" },
|
|
70
|
+
react_1.default.createElement(Search_1.default, { className: styles.icon })), endAdornment: react_1.default.createElement(InputAdornment_1.default, { position: "end" },
|
|
71
|
+
inputValue.length > 0 && (react_1.default.createElement(SmallIconButton_1.SmallIconButton, { icon: Close_1.default, className: styles.clearButton, onClick: clearValue })),
|
|
72
|
+
endAdornmentContent), autoFocus: autofocus, classes: __assign(__assign({}, classes), { input: (0, classnames_1.default)(styles.input, classes.input), root: (0, classnames_1.default)(styles.container, classes.root) }), placeholder: placeholder, value: inputValue, onChange: (0, ramda_1.pipe)(events_1.getValue, updateValue), disableUnderline: true, ref: rootRef }, otherProps)));
|
|
71
73
|
};
|
|
72
74
|
exports.default = (0, react_1.memo)(SearchInput);
|
|
@@ -10,55 +10,135 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
};
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
12
|
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
13
49
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
50
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
51
|
};
|
|
16
52
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
53
|
var react_1 = __importDefault(require("react"));
|
|
18
|
-
var
|
|
19
|
-
var
|
|
20
|
-
var SmallIconButton_1 = require("../SmallIconButton");
|
|
54
|
+
var react_2 = require("@testing-library/react");
|
|
55
|
+
var user_event_1 = __importDefault(require("@testing-library/user-event"));
|
|
21
56
|
var SearchInput_1 = __importDefault(require("./SearchInput"));
|
|
57
|
+
var test_utils_1 = require("../test-utils");
|
|
22
58
|
describe('SearchInput tests', function () {
|
|
59
|
+
var onSearch = jest.fn();
|
|
23
60
|
var defaultProps = {
|
|
24
61
|
value: '',
|
|
25
62
|
autofocus: true,
|
|
26
|
-
onSearch:
|
|
63
|
+
onSearch: onSearch,
|
|
27
64
|
height: 40
|
|
28
65
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
var onSearch = jest.fn();
|
|
37
|
-
var component = (0, enzyme_1.shallow)(react_1.default.createElement(SearchInput_1.default, __assign({}, defaultProps, { onSearch: onSearch })));
|
|
38
|
-
var input = component.find(Input_1.default);
|
|
39
|
-
input.simulate('change', { target: { value: 'test' } });
|
|
40
|
-
expect(onSearch).toBeCalledWith('test');
|
|
41
|
-
});
|
|
42
|
-
it('should call onSearch prop on clear input', function () {
|
|
43
|
-
var onSearch = jest.fn();
|
|
44
|
-
var component = (0, enzyme_1.mount)(react_1.default.createElement(SearchInput_1.default, __assign({}, defaultProps, { onSearch: onSearch, value: 'test' })));
|
|
45
|
-
component.find(SmallIconButton_1.SmallIconButton).find('button').simulate('click');
|
|
46
|
-
expect(onSearch).toBeCalledWith('');
|
|
66
|
+
var setUp = function (props) {
|
|
67
|
+
if (props === void 0) { props = defaultProps; }
|
|
68
|
+
var user = user_event_1.default.setup();
|
|
69
|
+
return __assign({ user: user }, (0, react_2.render)(react_1.default.createElement(SearchInput_1.default, __assign({}, props))));
|
|
70
|
+
};
|
|
71
|
+
afterEach(function () {
|
|
72
|
+
jest.clearAllMocks();
|
|
47
73
|
});
|
|
48
|
-
it('should
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
74
|
+
it('should render all components', function () {
|
|
75
|
+
setUp();
|
|
76
|
+
expect(react_2.screen.getByRole('textbox')).toBeInTheDocument();
|
|
77
|
+
expect(react_2.screen.getByPlaceholderText('Search')).toBeInTheDocument();
|
|
78
|
+
expect((0, test_utils_1.getMuiIconByName)('Search')).toBeInTheDocument();
|
|
52
79
|
});
|
|
53
|
-
it('should
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
it('should call onSearch prop on change', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
81
|
+
var user, searchValue;
|
|
82
|
+
return __generator(this, function (_a) {
|
|
83
|
+
switch (_a.label) {
|
|
84
|
+
case 0:
|
|
85
|
+
user = setUp(__assign(__assign({}, defaultProps), { value: null })).user;
|
|
86
|
+
searchValue = 'searchValue';
|
|
87
|
+
return [4 /*yield*/, user.type(react_2.screen.getByRole('textbox'), searchValue)];
|
|
88
|
+
case 1:
|
|
89
|
+
_a.sent();
|
|
90
|
+
expect(onSearch).toHaveBeenLastCalledWith(searchValue);
|
|
91
|
+
return [2 /*return*/];
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}); });
|
|
95
|
+
it('should call onSearch prop on clear input', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
96
|
+
var user;
|
|
97
|
+
return __generator(this, function (_a) {
|
|
98
|
+
switch (_a.label) {
|
|
99
|
+
case 0:
|
|
100
|
+
user = setUp(__assign(__assign({}, defaultProps), { value: 'test' })).user;
|
|
101
|
+
return [4 /*yield*/, user.click(react_2.screen.getByRole('button'))];
|
|
102
|
+
case 1:
|
|
103
|
+
_a.sent();
|
|
104
|
+
expect(onSearch).toBeCalledWith('');
|
|
105
|
+
return [2 /*return*/];
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}); });
|
|
109
|
+
it('should not fail when onSearch prop is undefined', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
110
|
+
var user;
|
|
111
|
+
return __generator(this, function (_a) {
|
|
112
|
+
switch (_a.label) {
|
|
113
|
+
case 0:
|
|
114
|
+
user = setUp().user;
|
|
115
|
+
return [4 /*yield*/, user.type(react_2.screen.getByRole('textbox'), 'q')];
|
|
116
|
+
case 1:
|
|
117
|
+
_a.sent();
|
|
118
|
+
return [2 /*return*/];
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}); });
|
|
122
|
+
it('should forward props to Input', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
123
|
+
var onKeyDown, onFocus, user;
|
|
124
|
+
return __generator(this, function (_a) {
|
|
125
|
+
switch (_a.label) {
|
|
126
|
+
case 0:
|
|
127
|
+
onKeyDown = jest.fn();
|
|
128
|
+
onFocus = jest.fn();
|
|
129
|
+
user = setUp(__assign(__assign({}, defaultProps), { fullWidth: true, onKeyDown: onKeyDown, onFocus: onFocus })).user;
|
|
130
|
+
return [4 /*yield*/, user.type(react_2.screen.getByRole('textbox'), 'q')];
|
|
131
|
+
case 1:
|
|
132
|
+
_a.sent();
|
|
133
|
+
expect(onKeyDown).toHaveBeenCalled();
|
|
134
|
+
expect(onFocus).toHaveBeenCalled();
|
|
135
|
+
return [2 /*return*/];
|
|
136
|
+
}
|
|
62
137
|
});
|
|
138
|
+
}); });
|
|
139
|
+
it('should use provided endAdornmentContent', function () {
|
|
140
|
+
var endAdornmentContent = react_1.default.createElement("div", null, "testContent");
|
|
141
|
+
setUp(__assign(__assign({}, defaultProps), { endAdornmentContent: endAdornmentContent }));
|
|
142
|
+
expect(react_2.screen.getByText('testContent')).toBeInTheDocument();
|
|
63
143
|
});
|
|
64
144
|
});
|
package/cjs/types/index.d.ts
CHANGED
|
@@ -16,10 +16,13 @@ type Props = {
|
|
|
16
16
|
onTogglePopup?: (open: boolean) => void;
|
|
17
17
|
isFiltersApplied?: boolean;
|
|
18
18
|
dataReltioId?: string;
|
|
19
|
+
ButtonIcon?: React.ElementType;
|
|
19
20
|
onFilterAttributeChange?: (attrSelectInfo: AttributeSelectionInfo) => void;
|
|
20
21
|
onClear?: () => void;
|
|
21
22
|
onCancel?: () => void;
|
|
22
23
|
onApply?: () => void;
|
|
24
|
+
popoverAnchorRef?: React.MutableRefObject<HTMLDivElement>;
|
|
25
|
+
title?: string;
|
|
23
26
|
};
|
|
24
|
-
declare const _default: React.MemoExoticComponent<({ filters: filtersProp, classes, attributesTypesGroups, attributesTypesGroupFilter, onChange, components, children, onTogglePopup, isFiltersApplied: isFiltersAppliedProp, dataReltioId, onFilterAttributeChange, onCancel, onClear, onApply }: Props) => JSX.Element>;
|
|
27
|
+
declare const _default: React.MemoExoticComponent<({ filters: filtersProp, classes, attributesTypesGroups, attributesTypesGroupFilter, onChange, components, children, onTogglePopup, isFiltersApplied: isFiltersAppliedProp, dataReltioId, onFilterAttributeChange, onCancel, onClear, onApply, ButtonIcon, popoverAnchorRef, title }: Props) => JSX.Element>;
|
|
25
28
|
export default _default;
|
|
@@ -11,11 +11,12 @@ import { AttributesFiltersBuilder } from '../AttributesFiltersBuilder';
|
|
|
11
11
|
import { ActionButtons } from './components/ActionButtons/';
|
|
12
12
|
import { useStyles } from './styles';
|
|
13
13
|
var AttributesFiltersButton = function (_a) {
|
|
14
|
-
var
|
|
14
|
+
var _b;
|
|
15
|
+
var filtersProp = _a.filters, classes = _a.classes, attributesTypesGroups = _a.attributesTypesGroups, attributesTypesGroupFilter = _a.attributesTypesGroupFilter, onChange = _a.onChange, components = _a.components, children = _a.children, onTogglePopup = _a.onTogglePopup, isFiltersAppliedProp = _a.isFiltersApplied, dataReltioId = _a.dataReltioId, onFilterAttributeChange = _a.onFilterAttributeChange, onCancel = _a.onCancel, onClear = _a.onClear, onApply = _a.onApply, _c = _a.ButtonIcon, ButtonIcon = _c === void 0 ? FilterIcon : _c, popoverAnchorRef = _a.popoverAnchorRef, title = _a.title;
|
|
15
16
|
var styles = useStyles();
|
|
16
17
|
var buttonRef = useRef();
|
|
17
|
-
var
|
|
18
|
-
var
|
|
18
|
+
var _d = useState(false), isOpen = _d[0], setIsOpen = _d[1];
|
|
19
|
+
var _e = useState([]), filters = _e[0], setFilters = _e[1];
|
|
19
20
|
var isFiltersApplied = isFiltersAppliedProp !== null && isFiltersAppliedProp !== void 0 ? isFiltersAppliedProp : !!buildFilterQueryString()(filtersProp);
|
|
20
21
|
var buttonColor = isFiltersApplied ? 'primary' : 'inherit';
|
|
21
22
|
var togglePopup = function () {
|
|
@@ -44,19 +45,19 @@ var AttributesFiltersButton = function (_a) {
|
|
|
44
45
|
}, [onClear]);
|
|
45
46
|
return (React.createElement(React.Fragment, null,
|
|
46
47
|
React.createElement(Button, { "data-reltio-id": dataReltioId, ref: buttonRef, color: buttonColor, classes: {
|
|
47
|
-
root: styles.triggerButton,
|
|
48
|
+
root: classNames(styles.triggerButton, classes === null || classes === void 0 ? void 0 : classes.triggerButton),
|
|
48
49
|
textPrimary: styles.changedFiltersIndicator
|
|
49
50
|
}, onClick: togglePopup },
|
|
50
|
-
React.createElement(
|
|
51
|
-
React.createElement(Popover, { open: isOpen, classes: { paper: classNames(styles.popupContent, classes === null || classes === void 0 ? void 0 : classes.filterPopup) }, anchorEl: buttonRef.current, onClose: togglePopup, anchorOrigin: {
|
|
51
|
+
React.createElement(ButtonIcon, { color: buttonColor })),
|
|
52
|
+
React.createElement(Popover, { open: isOpen, classes: { paper: classNames(styles.popupContent, classes === null || classes === void 0 ? void 0 : classes.filterPopup) }, anchorEl: (_b = popoverAnchorRef === null || popoverAnchorRef === void 0 ? void 0 : popoverAnchorRef.current) !== null && _b !== void 0 ? _b : buttonRef.current, onClose: togglePopup, anchorOrigin: {
|
|
52
53
|
vertical: 'bottom',
|
|
53
|
-
horizontal: 'right'
|
|
54
|
+
horizontal: (popoverAnchorRef === null || popoverAnchorRef === void 0 ? void 0 : popoverAnchorRef.current) ? 'left' : 'right'
|
|
54
55
|
}, transformOrigin: {
|
|
55
56
|
vertical: 'top',
|
|
56
57
|
horizontal: 'left'
|
|
57
58
|
} },
|
|
58
59
|
React.createElement(React.Fragment, null,
|
|
59
|
-
React.createElement(Typography, { variant: "h6" }, i18n.text('Filter')),
|
|
60
|
+
React.createElement(Typography, { variant: "h6" }, title !== null && title !== void 0 ? title : i18n.text('Filter')),
|
|
60
61
|
React.createElement("div", { className: styles.filtersBuilderWrapper },
|
|
61
62
|
children,
|
|
62
63
|
React.createElement(AttributesFiltersBuilder, { attributesTypesGroups: attributesTypesGroups, attributesTypesGroupFilter: attributesTypesGroupFilter, filters: filters, onChange: setFilters, components: components, onFilterAttributeChange: onFilterAttributeChange, classes: classes })),
|
|
@@ -242,4 +242,19 @@ describe('AttributesFiltersButton tests', function () {
|
|
|
242
242
|
}
|
|
243
243
|
});
|
|
244
244
|
}); });
|
|
245
|
+
it('should use title if defined', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
246
|
+
var title, user;
|
|
247
|
+
return __generator(this, function (_a) {
|
|
248
|
+
switch (_a.label) {
|
|
249
|
+
case 0:
|
|
250
|
+
title = 'TestTitle';
|
|
251
|
+
user = setUp(__assign(__assign({}, defaultProps), { title: title })).user;
|
|
252
|
+
return [4 /*yield*/, user.click(screen.getByRole('button'))];
|
|
253
|
+
case 1:
|
|
254
|
+
_a.sent();
|
|
255
|
+
expect(screen.getByText(title)).toBeInTheDocument();
|
|
256
|
+
return [2 /*return*/];
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}); });
|
|
245
260
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"button" | "text" | "small" | "root" | "
|
|
1
|
+
export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"button" | "text" | "small" | "root" | "embedded" | "root_small" | "full" | "textBox" | "secondaryText">;
|
|
@@ -7,6 +7,7 @@ type Props = InputProps & {
|
|
|
7
7
|
rootRef?: React.MutableRefObject<HTMLInputElement>;
|
|
8
8
|
height: number;
|
|
9
9
|
placeholder?: string;
|
|
10
|
+
endAdornmentContent?: React.ReactNode;
|
|
10
11
|
};
|
|
11
|
-
declare const _default: React.MemoExoticComponent<({ value, autofocus, onSearch, rootRef, classes, height, placeholder, ...otherProps }: Props) => JSX.Element>;
|
|
12
|
+
declare const _default: React.MemoExoticComponent<({ value, autofocus, onSearch, rootRef, classes, height, placeholder, endAdornmentContent, ...otherProps }: Props) => JSX.Element>;
|
|
12
13
|
export default _default;
|
|
@@ -32,13 +32,15 @@ import { getValue } from '../helpers/events';
|
|
|
32
32
|
import { SmallIconButton } from '../SmallIconButton';
|
|
33
33
|
import { useStyles } from './styles';
|
|
34
34
|
var SearchInput = function (_a) {
|
|
35
|
-
var value = _a.value, autofocus = _a.autofocus, _b = _a.onSearch, onSearch = _b === void 0 ? identity : _b, rootRef = _a.rootRef, _c = _a.classes, classes = _c === void 0 ? {} : _c, height = _a.height, _d = _a.placeholder, placeholder = _d === void 0 ? i18n.text('Search') : _d, otherProps = __rest(_a, ["value", "autofocus", "onSearch", "rootRef", "classes", "height", "placeholder"]);
|
|
35
|
+
var value = _a.value, autofocus = _a.autofocus, _b = _a.onSearch, onSearch = _b === void 0 ? identity : _b, rootRef = _a.rootRef, _c = _a.classes, classes = _c === void 0 ? {} : _c, height = _a.height, _d = _a.placeholder, placeholder = _d === void 0 ? i18n.text('Search') : _d, endAdornmentContent = _a.endAdornmentContent, otherProps = __rest(_a, ["value", "autofocus", "onSearch", "rootRef", "classes", "height", "placeholder", "endAdornmentContent"]);
|
|
36
36
|
var styles = useStyles({ height: height });
|
|
37
37
|
var _e = useState(''), localValue = _e[0], setLocalValue = _e[1];
|
|
38
38
|
var updateValue = pipe(tap(onSearch), setLocalValue);
|
|
39
39
|
var clearValue = function () { return updateValue(''); };
|
|
40
40
|
var inputValue = isNil(value) ? localValue : value;
|
|
41
41
|
return (React.createElement(Input, __assign({ startAdornment: React.createElement(InputAdornment, { position: "start" },
|
|
42
|
-
React.createElement(SearchIcon, { className: styles.icon })), endAdornment: React.createElement(InputAdornment, { position: "end" },
|
|
42
|
+
React.createElement(SearchIcon, { className: styles.icon })), endAdornment: React.createElement(InputAdornment, { position: "end" },
|
|
43
|
+
inputValue.length > 0 && (React.createElement(SmallIconButton, { icon: CloseIcon, className: styles.clearButton, onClick: clearValue })),
|
|
44
|
+
endAdornmentContent), autoFocus: autofocus, classes: __assign(__assign({}, classes), { input: classNames(styles.input, classes.input), root: classNames(styles.container, classes.root) }), placeholder: placeholder, value: inputValue, onChange: pipe(getValue, updateValue), disableUnderline: true, ref: rootRef }, otherProps)));
|
|
43
45
|
};
|
|
44
46
|
export default memo(SearchInput);
|
|
@@ -9,51 +9,131 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
12
48
|
import React from 'react';
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import { SmallIconButton } from '../SmallIconButton';
|
|
49
|
+
import { render, screen } from '@testing-library/react';
|
|
50
|
+
import userEvent from '@testing-library/user-event';
|
|
16
51
|
import SearchInput from './SearchInput';
|
|
52
|
+
import { getMuiIconByName } from '../test-utils';
|
|
17
53
|
describe('SearchInput tests', function () {
|
|
54
|
+
var onSearch = jest.fn();
|
|
18
55
|
var defaultProps = {
|
|
19
56
|
value: '',
|
|
20
57
|
autofocus: true,
|
|
21
|
-
onSearch:
|
|
58
|
+
onSearch: onSearch,
|
|
22
59
|
height: 40
|
|
23
60
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
var onSearch = jest.fn();
|
|
32
|
-
var component = shallow(React.createElement(SearchInput, __assign({}, defaultProps, { onSearch: onSearch })));
|
|
33
|
-
var input = component.find(Input);
|
|
34
|
-
input.simulate('change', { target: { value: 'test' } });
|
|
35
|
-
expect(onSearch).toBeCalledWith('test');
|
|
36
|
-
});
|
|
37
|
-
it('should call onSearch prop on clear input', function () {
|
|
38
|
-
var onSearch = jest.fn();
|
|
39
|
-
var component = mount(React.createElement(SearchInput, __assign({}, defaultProps, { onSearch: onSearch, value: 'test' })));
|
|
40
|
-
component.find(SmallIconButton).find('button').simulate('click');
|
|
41
|
-
expect(onSearch).toBeCalledWith('');
|
|
61
|
+
var setUp = function (props) {
|
|
62
|
+
if (props === void 0) { props = defaultProps; }
|
|
63
|
+
var user = userEvent.setup();
|
|
64
|
+
return __assign({ user: user }, render(React.createElement(SearchInput, __assign({}, props))));
|
|
65
|
+
};
|
|
66
|
+
afterEach(function () {
|
|
67
|
+
jest.clearAllMocks();
|
|
42
68
|
});
|
|
43
|
-
it('should
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
69
|
+
it('should render all components', function () {
|
|
70
|
+
setUp();
|
|
71
|
+
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
|
72
|
+
expect(screen.getByPlaceholderText('Search')).toBeInTheDocument();
|
|
73
|
+
expect(getMuiIconByName('Search')).toBeInTheDocument();
|
|
47
74
|
});
|
|
48
|
-
it('should
|
|
49
|
-
var
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
75
|
+
it('should call onSearch prop on change', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
76
|
+
var user, searchValue;
|
|
77
|
+
return __generator(this, function (_a) {
|
|
78
|
+
switch (_a.label) {
|
|
79
|
+
case 0:
|
|
80
|
+
user = setUp(__assign(__assign({}, defaultProps), { value: null })).user;
|
|
81
|
+
searchValue = 'searchValue';
|
|
82
|
+
return [4 /*yield*/, user.type(screen.getByRole('textbox'), searchValue)];
|
|
83
|
+
case 1:
|
|
84
|
+
_a.sent();
|
|
85
|
+
expect(onSearch).toHaveBeenLastCalledWith(searchValue);
|
|
86
|
+
return [2 /*return*/];
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}); });
|
|
90
|
+
it('should call onSearch prop on clear input', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
91
|
+
var user;
|
|
92
|
+
return __generator(this, function (_a) {
|
|
93
|
+
switch (_a.label) {
|
|
94
|
+
case 0:
|
|
95
|
+
user = setUp(__assign(__assign({}, defaultProps), { value: 'test' })).user;
|
|
96
|
+
return [4 /*yield*/, user.click(screen.getByRole('button'))];
|
|
97
|
+
case 1:
|
|
98
|
+
_a.sent();
|
|
99
|
+
expect(onSearch).toBeCalledWith('');
|
|
100
|
+
return [2 /*return*/];
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}); });
|
|
104
|
+
it('should not fail when onSearch prop is undefined', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
105
|
+
var user;
|
|
106
|
+
return __generator(this, function (_a) {
|
|
107
|
+
switch (_a.label) {
|
|
108
|
+
case 0:
|
|
109
|
+
user = setUp().user;
|
|
110
|
+
return [4 /*yield*/, user.type(screen.getByRole('textbox'), 'q')];
|
|
111
|
+
case 1:
|
|
112
|
+
_a.sent();
|
|
113
|
+
return [2 /*return*/];
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}); });
|
|
117
|
+
it('should forward props to Input', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
118
|
+
var onKeyDown, onFocus, user;
|
|
119
|
+
return __generator(this, function (_a) {
|
|
120
|
+
switch (_a.label) {
|
|
121
|
+
case 0:
|
|
122
|
+
onKeyDown = jest.fn();
|
|
123
|
+
onFocus = jest.fn();
|
|
124
|
+
user = setUp(__assign(__assign({}, defaultProps), { fullWidth: true, onKeyDown: onKeyDown, onFocus: onFocus })).user;
|
|
125
|
+
return [4 /*yield*/, user.type(screen.getByRole('textbox'), 'q')];
|
|
126
|
+
case 1:
|
|
127
|
+
_a.sent();
|
|
128
|
+
expect(onKeyDown).toHaveBeenCalled();
|
|
129
|
+
expect(onFocus).toHaveBeenCalled();
|
|
130
|
+
return [2 /*return*/];
|
|
131
|
+
}
|
|
57
132
|
});
|
|
133
|
+
}); });
|
|
134
|
+
it('should use provided endAdornmentContent', function () {
|
|
135
|
+
var endAdornmentContent = React.createElement("div", null, "testContent");
|
|
136
|
+
setUp(__assign(__assign({}, defaultProps), { endAdornmentContent: endAdornmentContent }));
|
|
137
|
+
expect(screen.getByText('testContent')).toBeInTheDocument();
|
|
58
138
|
});
|
|
59
139
|
});
|
package/esm/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reltio/components",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.1940",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE FILE",
|
|
5
5
|
"main": "./cjs/index.js",
|
|
6
6
|
"module": "./esm/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"@fluentui/react-context-selector": "^9.1.26",
|
|
9
9
|
"@react-google-maps/api": "2.7.0",
|
|
10
10
|
"@react-sigma/core": "3.4.0",
|
|
11
|
-
"@reltio/mdm-sdk": "^1.4.
|
|
11
|
+
"@reltio/mdm-sdk": "^1.4.1854",
|
|
12
12
|
"d3-cloud": "^1.2.5",
|
|
13
13
|
"d3-geo": "^2.0.1",
|
|
14
14
|
"d3-hierarchy": "^2.0.0",
|