@commercetools-uikit/filters 19.15.0 → 19.16.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.
@@ -5,16 +5,35 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var react = require('@emotion/react');
6
6
  var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
7
7
  require('prop-types');
8
+ var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
9
+ var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
10
+ var _findInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/find');
11
+ var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
12
+ var _sortInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/sort');
13
+ var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/includes');
14
+ var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
15
+ var react$1 = require('react');
8
16
  var Popover = require('@radix-ui/react-popover');
17
+ var CollapsibleMotion = require('@commercetools-uikit/collapsible-motion');
18
+ var designSystem = require('@commercetools-uikit/design-system');
9
19
  var FlatButton = require('@commercetools-uikit/flat-button');
10
- var SelectInput = require('@commercetools-uikit/select-input');
11
20
  var icons = require('@commercetools-uikit/icons');
12
- var react$1 = require('react');
21
+ var SelectInput = require('@commercetools-uikit/select-input');
13
22
  var Spacings = require('@commercetools-uikit/spacings');
14
- var designSystem = require('@commercetools-uikit/design-system');
15
23
  var reactIntl = require('react-intl');
16
24
  var jsxRuntime = require('@emotion/react/jsx-runtime');
17
- var CollapsibleMotion = require('@commercetools-uikit/collapsible-motion');
25
+ var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
26
+ var _objectWithoutProperties = require('@babel/runtime-corejs3/helpers/objectWithoutProperties');
27
+ var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
28
+ var _Array$from = require('@babel/runtime-corejs3/core-js-stable/array/from');
29
+ var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
30
+ var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
31
+ var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
32
+ var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
33
+ var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
34
+ var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
35
+ var SecondaryIconButton = require('@commercetools-uikit/secondary-icon-button');
36
+ var IconButton = require('@commercetools-uikit/icon-button');
18
37
 
19
38
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
20
39
 
@@ -36,11 +55,317 @@ function _interopNamespace(e) {
36
55
  return Object.freeze(n);
37
56
  }
38
57
 
58
+ var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
59
+ var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
60
+ var _findInstanceProperty__default = /*#__PURE__*/_interopDefault(_findInstanceProperty);
61
+ var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
62
+ var _sortInstanceProperty__default = /*#__PURE__*/_interopDefault(_sortInstanceProperty);
63
+ var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
64
+ var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
39
65
  var Popover__namespace = /*#__PURE__*/_interopNamespace(Popover);
66
+ var CollapsibleMotion__default = /*#__PURE__*/_interopDefault(CollapsibleMotion);
40
67
  var FlatButton__default = /*#__PURE__*/_interopDefault(FlatButton);
41
68
  var SelectInput__default = /*#__PURE__*/_interopDefault(SelectInput);
42
69
  var Spacings__default = /*#__PURE__*/_interopDefault(Spacings);
43
- var CollapsibleMotion__default = /*#__PURE__*/_interopDefault(CollapsibleMotion);
70
+ var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
71
+ var _Array$from__default = /*#__PURE__*/_interopDefault(_Array$from);
72
+ var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
73
+ var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
74
+ var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
75
+ var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
76
+ var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
77
+ var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
78
+ var SecondaryIconButton__default = /*#__PURE__*/_interopDefault(SecondaryIconButton);
79
+ var IconButton__default = /*#__PURE__*/_interopDefault(IconButton);
80
+
81
+ var messages$1 = reactIntl.defineMessages({
82
+ clearAllButtonLabel: {
83
+ id: 'UIKit.ClearAllButton.clearAllButtonLabel',
84
+ description: 'Label for the clear all button',
85
+ defaultMessage: 'Clear all'
86
+ }
87
+ });
88
+
89
+ const footerContainerStyles = /*#__PURE__*/react.css("border-top:", designSystem.designTokens.borderWidth1, " solid ", designSystem.designTokens.colorNeutral90, ";padding-top:", designSystem.designTokens.spacing20, ";display:grid;grid-template-columns:1fr 1fr;align-items:center;width:100%;div:last-of-type{display:flex;justify-content:flex-end;}" + ("" ), "" );
90
+ const Footer = _ref => {
91
+ let renderApplyButton = _ref.renderApplyButton,
92
+ onClearRequest = _ref.onClearRequest;
93
+ const intl = reactIntl.useIntl();
94
+ if (!renderApplyButton && !onClearRequest) return null;
95
+ return jsxRuntime.jsxs("footer", {
96
+ css: footerContainerStyles,
97
+ children: [jsxRuntime.jsx("div", {
98
+ children: renderApplyButton && renderApplyButton()
99
+ }), jsxRuntime.jsx("div", {
100
+ children: onClearRequest && jsxRuntime.jsx(FlatButton__default["default"], {
101
+ icon: jsxRuntime.jsx(icons.CloseBoldIcon, {}),
102
+ tone: "secondary",
103
+ onClick: onClearRequest,
104
+ label: intl.formatMessage(messages$1.clearAllButtonLabel)
105
+ })
106
+ })]
107
+ });
108
+ };
109
+ Footer.propTypes = {};
110
+ Footer.displayName = 'Footer';
111
+ var Footer$1 = Footer;
112
+
113
+ const headerContainerStyles = /*#__PURE__*/react.css("color:", designSystem.designTokens.colorNeutral40, ";font-weight:", designSystem.designTokens.fontWeight500, ";font-size:", designSystem.designTokens.fontSize20, ";line-height:", designSystem.designTokens.lineHeight20, ";display:grid;grid-template-columns:1fr min-content;align-items:center;padding-bottom:", designSystem.designTokens.spacing10, ";border-bottom:1px solid ", designSystem.designTokens.colorNeutral90, ";width:100%;" + ("" ), "" );
114
+ const selectInputStyles = /*#__PURE__*/react.css("flex:0 0 auto;max-width:", designSystem.designTokens.constraint3, ";margin-left:", designSystem.designTokens.spacing20, ";" + ("" ), "" );
115
+ const sortButtonMargin = /*#__PURE__*/react.css("margin-right:", designSystem.designTokens.spacing40, ";" + ("" ), "" );
116
+ const operatorInputContainer = {
117
+ name: "1ckoci3",
118
+ styles: "word-break:break-word;display:flex;align-items:center"
119
+ } ;
120
+ const Header = props => {
121
+ const _useState = react$1.useState(false),
122
+ _useState2 = _slicedToArray(_useState, 2),
123
+ isActive = _useState2[0],
124
+ setIsActive = _useState2[1];
125
+ return jsxRuntime.jsxs("header", {
126
+ css: headerContainerStyles,
127
+ children: [jsxRuntime.jsxs("div", {
128
+ css: [operatorInputContainer, props.onSortRequest && sortButtonMargin, "" , "" ],
129
+ children: [jsxRuntime.jsx("div", {
130
+ children: props.label
131
+ }), props.renderOperatorsInput && jsxRuntime.jsx("div", {
132
+ css: selectInputStyles,
133
+ children: props.renderOperatorsInput()
134
+ })]
135
+ }), props.onSortRequest && jsxRuntime.jsx(IconButton__default["default"], {
136
+ size: "20",
137
+ theme: isActive ? 'info' : 'default',
138
+ label: "Sort",
139
+ icon: jsxRuntime.jsx(icons.SortingIcon, {}),
140
+ isToggleButton: true,
141
+ onClick: e => {
142
+ setIsActive(!isActive);
143
+ return props.onSortRequest && props.onSortRequest(e);
144
+ }
145
+ })]
146
+ });
147
+ };
148
+ Header.propTypes = {};
149
+ var Header$1 = Header;
150
+
151
+ const triggerWrapper = /*#__PURE__*/react.css("color:", designSystem.designTokens.colorNeutral40, ";background-color:", designSystem.designTokens.colorSurface, ";font-size:", designSystem.designTokens.fontSize20, ";font-weight:", designSystem.designTokens.fontWeight500, ";line-height:", designSystem.designTokens.lineHeight20, ";position:relative;display:inline-flex;align-items:center;gap:", designSystem.designTokens.spacing20, ";padding:3px ", designSystem.designTokens.spacing25, ";border-radius:", designSystem.designTokens.borderRadius20, ";box-shadow:0 0 0 ", designSystem.designTokens.borderWidth1, " ", designSystem.designTokens.colorNeutral85, ";cursor:pointer;height:", designSystem.designTokens.spacing50, ";max-width:min(100%, ", designSystem.designTokens.constraint13, ");align-self:flex-start;&:hover{background-color:", designSystem.designTokens.colorPrimary98, ";.ui-kit-filter-trigger-badge-container{background:linear-gradient(\n to right,\n transparent,\n ", designSystem.designTokens.colorPrimary98, " 25%\n );}}" + ("" ), "" );
152
+ const disabled = /*#__PURE__*/react.css("color:", designSystem.designTokens.colorNeutral40, ";background-color:", designSystem.designTokens.colorNeutral95, ";cursor:not-allowed;&:hover{background-color:", designSystem.designTokens.colorNeutral95, ";.ui-kit-filter-trigger-badge-container{background:linear-gradient(\n to right,\n transparent,\n ", designSystem.designTokens.colorNeutral95, " 25%\n );}}.ui-kit-filter-trigger-badge-container{background:linear-gradient(\n to right,\n transparent,\n ", designSystem.designTokens.colorNeutral95, " 25%\n );}>*{pointer-events:none;}" + ("" ), "" );
153
+ const mainActionButton = /*#__PURE__*/react.css("background:transparent;border:0;position:absolute;inset:0;z-index:1;border-radius:", designSystem.designTokens.borderRadius20, ";&:focus{box-shadow:0 0 0 2px ", designSystem.designTokens.colorPrimary40, ";}" + ("" ), "" );
154
+ const removeButton = /*#__PURE__*/react.css("position:relative;z-index:2;flex-grow:0;flex-shrink:0;display:flex;svg{fill:", designSystem.designTokens.colorNeutral40, "!important;&:hover{fill:", designSystem.designTokens.colorPrimary40, "!important;}}" + ("" ), "" );
155
+ const label = /*#__PURE__*/react.css("flex:0 0 auto;overflow:hidden;text-overflow:ellipsis;cursor:inherit;white-space:nowrap;max-width:", designSystem.designTokens.constraint6, ";" + ("" ), "" );
156
+ const operatorContainer = /*#__PURE__*/react.css("font-style:italic;font-weight:300;margin-left:", designSystem.designTokens.spacing20, ";" + ("" ), "" );
157
+ const valuesContainer = /*#__PURE__*/react.css("display:flex;align-items:center;justify-content:flex-start;gap:", designSystem.designTokens.spacing10, ";overflow:hidden;position:relative;padding-left:0;margin:0;" + ("" ), "" );
158
+ const badgeContainer = /*#__PURE__*/react.css("position:absolute;right:0;display:flex;align-items:center;padding-left:", designSystem.designTokens.spacing30, ";background:linear-gradient(\n to right,\n transparent,\n ", designSystem.designTokens.colorSurface, " 25%\n );" + ("" ), "" );
159
+
160
+ const badgeStyles = /*#__PURE__*/react.css("font-size:", designSystem.designTokens.fontSize20, ";font-weight:", designSystem.designTokens.fontWeight500, ";line-height:", designSystem.designTokens.lineHeight20, ";color:", designSystem.designTokens.colorSurface, ";background-color:", designSystem.designTokens.colorInfo, ";padding:0 calc(", designSystem.designTokens.spacing05, " + ", designSystem.designTokens.spacing10, ");border-radius:", designSystem.designTokens.borderRadius20, ";display:inline-flex;flex-direction:column;justify-content:center;align-items:center;height:", designSystem.designTokens.spacing40, ";" + ("" ), "" );
161
+ const disabledBadgeStyles = /*#__PURE__*/react.css("background-color:", designSystem.designTokens.colorNeutral, ";" + ("" ), "" );
162
+ function Badge(props) {
163
+ return jsxRuntime.jsx("span", {
164
+ "aria-label": props['aria-label'],
165
+ css: [badgeStyles, props.isDisabled && disabledBadgeStyles, "" , "" ],
166
+ id: props.id,
167
+ role: "status",
168
+ children: props.label
169
+ });
170
+ }
171
+
172
+ const chipStyles = /*#__PURE__*/react.css("font-size:", designSystem.designTokens.fontSize20, ";font-weight:", designSystem.designTokens.fontWeight400, ";line-height:", designSystem.designTokens.lineHeight20, ";color:", designSystem.designTokens.colorPrimary20, ";background-color:", designSystem.designTokens.colorPrimary95, ";height:", designSystem.designTokens.spacing40, ";padding:0 ", designSystem.designTokens.spacing20, ";border-radius:calc(\n ", designSystem.designTokens.borderRadius20, " - ", designSystem.designTokens.borderRadius4, "\n );display:inline-flex;justify-content:center;align-items:center;list-style:none;white-space:nowrap;" + ("" ), "" );
173
+ const disabledChipStyles = /*#__PURE__*/react.css("color:", designSystem.designTokens.colorNeutral40, ";background-color:", designSystem.designTokens.colorNeutral90, ";" + ("" ), "" );
174
+ function Chip(props) {
175
+ return jsxRuntime.jsx("li", {
176
+ css: [chipStyles, props.isDisabled && disabledChipStyles, "" , "" ],
177
+ children: props.label
178
+ });
179
+ }
180
+ Chip.propTypes = {};
181
+
182
+ const _excluded = ["filterKey", "label", "operatorLabel", "appliedFilterValues", "isDisabled", "isPersistent", "onRemoveRequest"];
183
+ function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
184
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context3, _context4; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context3 = ownKeys(Object(t), !0)).call(_context3, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context4 = ownKeys(Object(t))).call(_context4, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
185
+ const useScrollObserver = values => {
186
+ const _useState = react$1.useState(false),
187
+ _useState2 = _slicedToArray(_useState, 2),
188
+ isOverflowing = _useState2[0],
189
+ setIsOverflowing = _useState2[1];
190
+ const _useState3 = react$1.useState(0),
191
+ _useState4 = _slicedToArray(_useState3, 2),
192
+ overflowCount = _useState4[0],
193
+ setOverflowCount = _useState4[1];
194
+ const containerRef = react$1.useRef(null);
195
+ const setContainerRef = react$1.useCallback(node => {
196
+ if (node) {
197
+ containerRef.current = node;
198
+ const clientWidth = node.clientWidth,
199
+ scrollWidth = node.scrollWidth,
200
+ children = node.children;
201
+ const hasOverflow = scrollWidth > clientWidth;
202
+ setIsOverflowing(hasOverflow);
203
+ let visibleChipCount = 0;
204
+ if (hasOverflow) {
205
+ var _context;
206
+ _forEachInstanceProperty__default["default"](_context = _Array$from__default["default"](children)).call(_context, child => {
207
+ var _context2;
208
+ const childRect = child.getBoundingClientRect();
209
+ const containerRect = node.getBoundingClientRect();
210
+ if (
211
+ // if the right hand side of the child is past the right of the container
212
+ childRect.right <= containerRect.right &&
213
+ // and it's not the badge
214
+ !_includesInstanceProperty__default["default"](_context2 = _Array$from__default["default"](child.classList)).call(_context2, 'ui-kit-filter-trigger-badge-container')) {
215
+ ++visibleChipCount;
216
+ }
217
+ });
218
+ }
219
+ setOverflowCount(values.length - visibleChipCount);
220
+ }
221
+ }, [values]);
222
+ return {
223
+ isOverflowing,
224
+ overflowCount,
225
+ setContainerRef
226
+ };
227
+ };
228
+ const TriggerButton = /*#__PURE__*/react$1.forwardRef(function TriggerButton(props, ref) {
229
+ const filterKey = props.filterKey,
230
+ label$1 = props.label,
231
+ operatorLabel = props.operatorLabel,
232
+ appliedFilterValues = props.appliedFilterValues,
233
+ isDisabled = props.isDisabled,
234
+ isPersistent = props.isPersistent,
235
+ onRemoveRequest = props.onRemoveRequest,
236
+ rest = _objectWithoutProperties(props, _excluded);
237
+ const values = appliedFilterValues || [];
238
+ const filtersApplied = values.length > 0;
239
+ const _useScrollObserver = useScrollObserver(values),
240
+ isOverflowing = _useScrollObserver.isOverflowing,
241
+ overflowCount = _useScrollObserver.overflowCount,
242
+ setContainerRef = _useScrollObserver.setContainerRef;
243
+ return jsxRuntime.jsxs("div", {
244
+ css: [triggerWrapper, isDisabled && disabled, "" , "" ],
245
+ children: [jsxRuntime.jsxs("label", {
246
+ css: label,
247
+ htmlFor: `${filterKey}-menu-trigger`,
248
+ id: `${filterKey}-menu-label`,
249
+ children: [label$1, ":", operatorLabel && jsxRuntime.jsx("span", {
250
+ css: operatorContainer,
251
+ children: operatorLabel
252
+ })]
253
+ }), filtersApplied && jsxRuntime.jsxs("ul", {
254
+ ref: setContainerRef,
255
+ css: valuesContainer,
256
+ "aria-label": `${filterKey} selected values`,
257
+ "aria-live": "polite",
258
+ children: [_mapInstanceProperty__default["default"](values).call(values, value => jsxRuntime.jsx(Chip, {
259
+ label: value.label,
260
+ isDisabled: isDisabled
261
+ }, value.value)), isOverflowing && overflowCount && jsxRuntime.jsx("li", {
262
+ className: "ui-kit-filter-trigger-badge-container",
263
+ css: badgeContainer,
264
+ children: jsxRuntime.jsx(Badge, {
265
+ id: "ui-kit-filter-trigger-overflow-count-badge",
266
+ label: `+${overflowCount}`,
267
+ isDisabled: isDisabled
268
+ })
269
+ })]
270
+ }), !filtersApplied && jsxRuntime.jsx(icons.CaretDownIcon, {
271
+ "aria-label": `toggle filter menu icon`,
272
+ size: "small",
273
+ color: "neutral60"
274
+ }), jsxRuntime.jsx("button", _objectSpread(_objectSpread({
275
+ css: [mainActionButton, "" , "" ],
276
+ ref: ref,
277
+ id: `${filterKey}-menu-trigger`,
278
+ "aria-disabled": isDisabled,
279
+ "aria-labelledby": `${filterKey}-menu-label`
280
+ }, rest), isDisabled && {
281
+ tabIndex: -1,
282
+ disabled: true,
283
+ readOnly: true
284
+ })), filtersApplied && onRemoveRequest && !isPersistent && jsxRuntime.jsx("div", {
285
+ css: [removeButton, "" , "" ],
286
+ children: jsxRuntime.jsx(SecondaryIconButton__default["default"], {
287
+ icon: jsxRuntime.jsx(icons.CloseBoldIcon, {}),
288
+ size: "10",
289
+ label: `remove ${label$1} filter`,
290
+ isDisabled: props.isDisabled,
291
+ onClick: e => {
292
+ e.stopPropagation();
293
+ onRemoveRequest(e);
294
+ }
295
+ })
296
+ })]
297
+ });
298
+ });
299
+ var TriggerButton$1 = TriggerButton;
300
+
301
+ const FOCUSABLE_CSS_SELECTOR = `a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), *[tabindex], *[contenteditable]`;
302
+
303
+ /**
304
+ * Find the first focusable element in the given container,
305
+ * such as the first focusable list item.
306
+ * @param {HTMLElement} container
307
+ * @returns {HTMLElement | null}
308
+ */
309
+ function findFirstFocusable(container) {
310
+ return container.querySelector(FOCUSABLE_CSS_SELECTOR);
311
+ }
312
+ const menuStyles = /*#__PURE__*/react.css("display:flex;flex-direction:column;align-items:flex-start;gap:", designSystem.designTokens.spacing30, ";width:", designSystem.designTokens.constraint6, ";max-height:", designSystem.designTokens.constraint10, ";padding:", designSystem.designTokens.spacing20, " ", designSystem.designTokens.spacing30, ";background-color:", designSystem.designTokens.colorSurface, ";border:1px solid ", designSystem.designTokens.colorSurface, ";border-radius:", designSystem.designTokens.borderRadius8, ";box-shadow:", designSystem.designTokens.shadow18, ";animation-duration:", designSystem.designTokens.transitionStandard, ";will-change:'transform, opacity';margin-top:", designSystem.designTokens.spacing10, ";position:relative;z-index:5;" + ("" ), "" );
313
+ const menuBodyStyle = {
314
+ name: "pw6q3u",
315
+ styles: "width:100%;overflow:hidden auto"
316
+ } ;
317
+ function FilterMenu(props) {
318
+ const menuBodyRef = react$1.useRef(null);
319
+ const focusMenuBody = react$1.useCallback(e => {
320
+ if (menuBodyRef.current) {
321
+ const firstFocusableElementInMenuBody = findFirstFocusable(menuBodyRef.current);
322
+ if (firstFocusableElementInMenuBody) {
323
+ e.preventDefault();
324
+ firstFocusableElementInMenuBody.focus();
325
+ }
326
+ }
327
+ }, [menuBodyRef]);
328
+ return jsxRuntime.jsxs(Popover__namespace.Root, {
329
+ defaultOpen: props.isDisabled ? false : props.defaultOpen,
330
+ onOpenChange: open => {
331
+ if (!open && !props.appliedFilterValues?.length && !props.isPersistent && props.onRemoveRequest) {
332
+ props.onRemoveRequest();
333
+ }
334
+ },
335
+ children: [jsxRuntime.jsx(Popover__namespace.Trigger, {
336
+ asChild: true,
337
+ children: jsxRuntime.jsx(TriggerButton$1, {
338
+ filterKey: props.filterKey,
339
+ label: props.label,
340
+ operatorLabel: props.operatorLabel,
341
+ appliedFilterValues: props.appliedFilterValues,
342
+ isDisabled: props.isDisabled,
343
+ isPersistent: props.isPersistent,
344
+ onRemoveRequest: props.onRemoveRequest
345
+ })
346
+ }), jsxRuntime.jsx(Popover__namespace.Portal, {
347
+ children: jsxRuntime.jsxs(Popover__namespace.Content, {
348
+ side: "bottom",
349
+ align: "start",
350
+ css: menuStyles,
351
+ onOpenAutoFocus: focusMenuBody,
352
+ children: [jsxRuntime.jsx(Header$1, {
353
+ label: props.label,
354
+ renderOperatorsInput: props.renderOperatorsInput,
355
+ onSortRequest: props.onSortRequest
356
+ }), jsxRuntime.jsx("div", {
357
+ css: menuBodyStyle,
358
+ ref: menuBodyRef,
359
+ children: props.renderMenuBody()
360
+ }), jsxRuntime.jsx(Footer$1, {
361
+ onClearRequest: props.onClearRequest,
362
+ renderApplyButton: props.renderApplyButton
363
+ })]
364
+ })
365
+ })]
366
+ });
367
+ }
368
+ FilterMenu.propTypes = {};
44
369
 
45
370
  var messages = reactIntl.defineMessages({
46
371
  addFilterButtonLabel: {
@@ -60,24 +385,108 @@ var messages = reactIntl.defineMessages({
60
385
  }
61
386
  });
62
387
 
63
- const menuStyles = /*#__PURE__*/react.css("display:flex;flex-direction:column;align-items:flex-start;gap:", designSystem.designTokens.spacing30, ";width:", designSystem.designTokens.constraint6, ";padding:", designSystem.designTokens.spacing20, " ", designSystem.designTokens.spacing30, ";background-color:", designSystem.designTokens.colorSurface, ";border:1px solid ", designSystem.designTokens.colorSurface, ";border-radius:", designSystem.designTokens.borderRadius8, ";box-shadow:", designSystem.designTokens.shadow18, ";animation-duration:", designSystem.designTokens.transitionStandard, ";will-change:'transform, opacity';margin-top:", designSystem.designTokens.spacing10, ";position:relative;z-index:5;" + ("" ), "" );
64
-
65
- const horizontalDividerStyles = /*#__PURE__*/react.css("width:100%;height:1px;border:1px solid ", designSystem.designTokens.colorNeutral90, ";margin-top:", designSystem.designTokens.spacing25, ";margin-bottom:", designSystem.designTokens.spacing30, ";" + ("" ), "" );
388
+ const horizontalDividerStyles = /*#__PURE__*/react.css("color:", designSystem.designTokens.colorNeutral90, ";background-color:", designSystem.designTokens.colorNeutral90, ";width:100%;height:1px;border:0;margin-top:", designSystem.designTokens.spacing25, ";margin-bottom:", designSystem.designTokens.spacing30, ";" + ("" ), "" );
66
389
  const verticalDividerStyles = /*#__PURE__*/react.css("width:1px;height:", designSystem.designTokens.spacing30, ";background-color:", designSystem.designTokens.colorNeutral90, ";margin:0 ", designSystem.designTokens.spacing20, " 0 ", designSystem.designTokens.spacing20, ";" + ("" ), "" );
67
- const menuListStyles = /*#__PURE__*/react.css("width:100%;display:flex;align-items:center;gap:", designSystem.designTokens.spacing20, ";" + ("" ), "" );
68
- var _ref2 = {
390
+ const menuListStyles = /*#__PURE__*/react.css("width:100%;display:flex;flex-wrap:wrap;align-items:center;gap:", designSystem.designTokens.spacing20, ";" + ("" ), "" );
391
+ function getFilterOptions(filters, filterGroups) {
392
+ let filterOptions = [];
393
+ // define option groups
394
+ if (filterGroups) {
395
+ filterOptions = _mapInstanceProperty__default["default"](filterGroups).call(filterGroups, filterGroup => ({
396
+ label: filterGroup.label,
397
+ key: filterGroup.key,
398
+ options: []
399
+ }));
400
+ }
401
+ return _reduceInstanceProperty__default["default"](filters).call(filters, (filterOptions, filter) => {
402
+ const formattedOption = {
403
+ value: filter.key,
404
+ label: filter.label,
405
+ isDisabled: filter.isDisabled
406
+ };
407
+ //if theres a groupkey, filterGroups, and the groupKey matches a filterGroup, add option to its group
408
+ if (filter.groupKey && filterGroups) {
409
+ const optionGroup = _findInstanceProperty__default["default"](filterOptions).call(filterOptions, option => 'key' in option && option.key === filter.groupKey);
410
+ if (optionGroup && 'options' in optionGroup) {
411
+ optionGroup.options.push(formattedOption);
412
+ return filterOptions;
413
+ }
414
+ }
415
+ // otherwise add option directly
416
+ return [formattedOption, ...filterOptions];
417
+ }, filterOptions);
418
+ }
419
+ var _ref9 = {
69
420
  name: "1lv1yo7",
70
421
  styles: "display:inline-flex"
71
422
  } ;
72
- function Filters(props) {
423
+ function Filters(_ref) {
424
+ var _context, _context2;
425
+ let appliedFilters = _ref.appliedFilters,
426
+ filters = _ref.filters,
427
+ filterGroups = _ref.filterGroups,
428
+ onClearAllRequest = _ref.onClearAllRequest,
429
+ onAddFilterRequest = _ref.onAddFilterRequest,
430
+ renderSearchComponent = _ref.renderSearchComponent,
431
+ _ref$defaultOpen = _ref.defaultOpen,
432
+ defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen;
73
433
  const intl = reactIntl.useIntl();
74
- const _useState = react$1.useState(false),
434
+ const _useState = react$1.useState(defaultOpen),
75
435
  _useState2 = _slicedToArray(_useState, 2),
76
- showAddFilters = _useState2[0],
77
- setShowAddFilters = _useState2[1];
436
+ showFilterControls = _useState2[0],
437
+ setShowFilterControls = _useState2[1];
78
438
  const handleFiltersClick = () => {
79
- setShowAddFilters(currState => !currState);
439
+ setShowFilterControls(currState => !currState);
80
440
  };
441
+ /**
442
+ * persisted filters: always visible
443
+ * applied filters: filters for which values have been selected
444
+ * visible filters = persisted + applied
445
+ *
446
+ * visibleFiltersFromProps = filters visible based on props
447
+ * localVisibleFilters = filters actually visible in component currently
448
+ */
449
+ const persistedFilterKeys = _mapInstanceProperty__default["default"](_context = _filterInstanceProperty__default["default"](filters).call(filters, _ref2 => {
450
+ let isPersistent = _ref2.isPersistent;
451
+ return isPersistent;
452
+ })).call(_context, filter => filter.key);
453
+ const persistedFiltersRef = react$1.useRef(persistedFilterKeys);
454
+ const appliedFilterKeys = _mapInstanceProperty__default["default"](appliedFilters).call(appliedFilters, _ref3 => {
455
+ let filterKey = _ref3.filterKey;
456
+ return filterKey;
457
+ });
458
+
459
+ // applied filters must have corresponding filter in `props.filters`,
460
+ const visibleFiltersFromProps = _sortInstanceProperty__default["default"](_context2 = _filterInstanceProperty__default["default"](filters).call(filters, _ref4 => {
461
+ let key = _ref4.key,
462
+ isPersistent = _ref4.isPersistent;
463
+ const isVisible = Boolean(isPersistent) || _includesInstanceProperty__default["default"](appliedFilterKeys).call(appliedFilterKeys, key);
464
+ return isVisible;
465
+ })
466
+ // persistent filters should be first in filter list
467
+ ).call(_context2, _ref5 => {
468
+ let isPersistent = _ref5.isPersistent;
469
+ return isPersistent ? -1 : 1;
470
+ });
471
+
472
+ // set initial state as visibleFiltersFromProps
473
+ const _useState3 = react$1.useState(_mapInstanceProperty__default["default"](visibleFiltersFromProps).call(visibleFiltersFromProps, _ref6 => {
474
+ let key = _ref6.key;
475
+ return key;
476
+ })),
477
+ _useState4 = _slicedToArray(_useState3, 2),
478
+ localVisibleFilters = _useState4[0],
479
+ setLocalVisibleFilters = _useState4[1];
480
+
481
+ //update localVisibleFilters if persisted filter count changes
482
+ if (persistedFiltersRef.current.length !== persistedFilterKeys.length) {
483
+ setLocalVisibleFilters(_mapInstanceProperty__default["default"](visibleFiltersFromProps).call(visibleFiltersFromProps, _ref7 => {
484
+ let key = _ref7.key;
485
+ return key;
486
+ }));
487
+ persistedFiltersRef.current = persistedFilterKeys;
488
+ }
489
+ const removeFilter = filterKey => setLocalVisibleFilters(currentVisibleFilters => _filterInstanceProperty__default["default"](currentVisibleFilters).call(currentVisibleFilters, visibleFilterKey => visibleFilterKey !== filterKey));
81
490
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
82
491
  children: [jsxRuntime.jsxs(Spacings__default["default"].Inline, {
83
492
  scale: "m",
@@ -86,53 +495,104 @@ function Filters(props) {
86
495
  css: /*#__PURE__*/react.css({
87
496
  maxWidth: `${designSystem.designTokens.constraint16}`
88
497
  }, "" , "" ),
89
- children: props.renderSearchComponent()
90
- }), jsxRuntime.jsx(FlatButton__default["default"], {
91
- "data-testid": "filters-button",
92
- label: intl.formatMessage(messages.filtersButtonLabel),
93
- icon: jsxRuntime.jsx(icons.FilterIcon, {}),
94
- onClick: handleFiltersClick
498
+ children: renderSearchComponent
499
+ }), jsxRuntime.jsxs(Spacings__default["default"].Inline, {
500
+ scale: "s",
501
+ alignItems: "center",
502
+ children: [jsxRuntime.jsx(FlatButton__default["default"], {
503
+ label: intl.formatMessage(messages.filtersButtonLabel),
504
+ icon: jsxRuntime.jsx(icons.FilterIcon, {}),
505
+ onClick: handleFiltersClick
506
+ }), appliedFilters.length > 1 && !showFilterControls && jsxRuntime.jsx(Badge, {
507
+ id: 'uikit-filters-selected-filter-count',
508
+ label: `${appliedFilters.length}`
509
+ })]
95
510
  })]
96
- }), jsxRuntime.jsx("div", {
511
+ }), jsxRuntime.jsx("hr", {
97
512
  css: horizontalDividerStyles
98
513
  }), jsxRuntime.jsx(CollapsibleMotion__default["default"], {
99
- isClosed: !showAddFilters,
100
- onToggle: () => setShowAddFilters(!showAddFilters),
101
- children: _ref => {
102
- let registerContentNode = _ref.registerContentNode,
103
- containerStyles = _ref.containerStyles;
514
+ isClosed: !showFilterControls,
515
+ onToggle: () => setShowFilterControls(!showFilterControls),
516
+ children: _ref8 => {
517
+ let registerContentNode = _ref8.registerContentNode,
518
+ containerStyles = _ref8.containerStyles;
104
519
  return jsxRuntime.jsx("div", {
105
520
  style: containerStyles,
106
521
  children: jsxRuntime.jsxs("div", {
107
522
  ref: registerContentNode,
108
523
  css: menuListStyles,
109
- children: [jsxRuntime.jsxs(Popover__namespace.Root, {
524
+ "aria-live": "polite",
525
+ children: [_mapInstanceProperty__default["default"](localVisibleFilters).call(localVisibleFilters, activeFilter => {
526
+ const activeFilterConfig = _findInstanceProperty__default["default"](filters).call(filters, filter => filter.key === activeFilter);
527
+ return jsxRuntime.jsx(FilterMenu, {
528
+ filterKey: activeFilterConfig.key,
529
+ label: activeFilterConfig.label,
530
+ operatorLabel: activeFilterConfig.operatorLabel,
531
+ isPersistent: activeFilterConfig.isPersistent,
532
+ isDisabled: activeFilterConfig.isDisabled,
533
+ renderMenuBody: activeFilterConfig.filterMenuConfiguration.renderMenuBody,
534
+ renderOperatorsInput: activeFilterConfig.filterMenuConfiguration.renderOperatorsInput,
535
+ renderApplyButton: activeFilterConfig.filterMenuConfiguration.renderApplyButton,
536
+ appliedFilterValues: _findInstanceProperty__default["default"](appliedFilters).call(appliedFilters, appliedFilter => activeFilter === appliedFilter.filterKey)?.values,
537
+ onClearRequest: activeFilterConfig.filterMenuConfiguration.onClearRequest,
538
+ onRemoveRequest: e => {
539
+ removeFilter(activeFilter);
540
+ activeFilterConfig.filterMenuConfiguration.onClearRequest(e);
541
+ },
542
+ onSortRequest: activeFilterConfig.filterMenuConfiguration.onSortRequest,
543
+ defaultOpen: activeFilterConfig.isPersistent || localVisibleFilters.length === visibleFiltersFromProps.length ? false : true
544
+ }, activeFilterConfig.key);
545
+ }), jsxRuntime.jsxs(Popover__namespace.Root, {
110
546
  children: [jsxRuntime.jsx(Popover__namespace.Trigger, {
111
547
  asChild: true,
112
548
  children: jsxRuntime.jsx("div", {
113
- css: _ref2,
549
+ css: _ref9,
114
550
  children: jsxRuntime.jsx(FlatButton__default["default"], {
115
- "data-testid": "add-filter-button",
116
551
  label: intl.formatMessage(messages.addFilterButtonLabel),
117
552
  icon: jsxRuntime.jsx(icons.PlusBoldIcon, {}),
118
- onClick: () => setShowAddFilters(true)
553
+ onClick: e => {
554
+ if (onAddFilterRequest) {
555
+ onAddFilterRequest(e);
556
+ }
557
+ setShowFilterControls(true);
558
+ }
119
559
  })
120
560
  })
121
561
  }), jsxRuntime.jsx(Popover__namespace.Portal, {
122
562
  children: jsxRuntime.jsx(Popover__namespace.Content, {
123
563
  side: "bottom",
124
564
  align: "start",
125
- css: menuStyles,
126
- children: jsxRuntime.jsx(SelectInput__default["default"], {})
565
+ css: [menuStyles, menuBodyStyle, "" , "" ],
566
+ children: jsxRuntime.jsx(SelectInput__default["default"], {
567
+ id: "ui-kit-add-filters-select",
568
+ name: "select filters",
569
+ "aria-label": "select filters",
570
+ appearance: "filter",
571
+ options: getFilterOptions(filters, filterGroups),
572
+ onChange: e => {
573
+ var _context3;
574
+ setLocalVisibleFilters(_concatInstanceProperty__default["default"](_context3 = Array.prototype).call(_context3, e.target.value ? e.target.value : []));
575
+ },
576
+ value: localVisibleFilters,
577
+ isMulti: true
578
+ // @ts-ignore
579
+ ,
580
+ isOptionDisabled: option => option.isDisabled
581
+ })
127
582
  })
128
583
  })]
129
- }), jsxRuntime.jsx("div", {
130
- css: verticalDividerStyles
131
- }), jsxRuntime.jsx(FlatButton__default["default"], {
132
- icon: jsxRuntime.jsx(icons.CloseBoldIcon, {}),
133
- label: intl.formatMessage(messages.clearAllFiltersButtonLabel),
134
- onClick: props.onClearAllRequest,
135
- tone: "secondary"
584
+ }), appliedFilters.length > 1 && jsxRuntime.jsxs(jsxRuntime.Fragment, {
585
+ children: [jsxRuntime.jsx("div", {
586
+ css: verticalDividerStyles
587
+ }), jsxRuntime.jsx(FlatButton__default["default"], {
588
+ icon: jsxRuntime.jsx(icons.CloseBoldIcon, {}),
589
+ label: intl.formatMessage(messages.clearAllFiltersButtonLabel),
590
+ onClick: e => {
591
+ onClearAllRequest(e);
592
+ setLocalVisibleFilters(persistedFilterKeys);
593
+ },
594
+ tone: "secondary"
595
+ })]
136
596
  })]
137
597
  })
138
598
  });
@@ -144,7 +604,7 @@ Filters.propTypes = {};
144
604
  Filters.displayName = 'Filters';
145
605
 
146
606
  // NOTE: This string will be replaced on build time with the package version.
147
- var version = "19.15.0";
607
+ var version = "19.16.0";
148
608
 
149
609
  exports["default"] = Filters;
150
610
  exports.version = version;