@redsift/pickers 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js ADDED
@@ -0,0 +1,874 @@
1
+ import React, { forwardRef, useContext, useEffect, useState, useReducer, useMemo } from 'react';
2
+ import { usePopoverContext, useMergeRefs, FloatingPortal, StyledPopoverContent, PopoverContent, Popover } from '@redsift/popovers';
3
+ import { baseContainer, FocusWithinGroupContext, Flexbox, ListboxContext, partitionComponents, isComponent, IconButton, FocusWithinGroupActionType, EventKey, ListboxActionType, ListboxReducer, FocusWithinGroup, Text } from '@redsift/design-system';
4
+ import { useLocalizedStringFormatter } from '@react-aria/i18n';
5
+ import { mdiUnfoldMoreHorizontal } from '@redsift/icons';
6
+ import classNames from 'classnames';
7
+ import styled from 'styled-components';
8
+
9
+ function ownKeys(object, enumerableOnly) {
10
+ var keys = Object.keys(object);
11
+ if (Object.getOwnPropertySymbols) {
12
+ var symbols = Object.getOwnPropertySymbols(object);
13
+ enumerableOnly && (symbols = symbols.filter(function (sym) {
14
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
15
+ })), keys.push.apply(keys, symbols);
16
+ }
17
+ return keys;
18
+ }
19
+ function _objectSpread2(target) {
20
+ for (var i = 1; i < arguments.length; i++) {
21
+ var source = null != arguments[i] ? arguments[i] : {};
22
+ i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
23
+ _defineProperty(target, key, source[key]);
24
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
25
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
26
+ });
27
+ }
28
+ return target;
29
+ }
30
+ function _defineProperty(obj, key, value) {
31
+ key = _toPropertyKey(key);
32
+ if (key in obj) {
33
+ Object.defineProperty(obj, key, {
34
+ value: value,
35
+ enumerable: true,
36
+ configurable: true,
37
+ writable: true
38
+ });
39
+ } else {
40
+ obj[key] = value;
41
+ }
42
+ return obj;
43
+ }
44
+ function _extends() {
45
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
46
+ for (var i = 1; i < arguments.length; i++) {
47
+ var source = arguments[i];
48
+ for (var key in source) {
49
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
50
+ target[key] = source[key];
51
+ }
52
+ }
53
+ }
54
+ return target;
55
+ };
56
+ return _extends.apply(this, arguments);
57
+ }
58
+ function _objectWithoutPropertiesLoose(source, excluded) {
59
+ if (source == null) return {};
60
+ var target = {};
61
+ var sourceKeys = Object.keys(source);
62
+ var key, i;
63
+ for (i = 0; i < sourceKeys.length; i++) {
64
+ key = sourceKeys[i];
65
+ if (excluded.indexOf(key) >= 0) continue;
66
+ target[key] = source[key];
67
+ }
68
+ return target;
69
+ }
70
+ function _objectWithoutProperties(source, excluded) {
71
+ if (source == null) return {};
72
+ var target = _objectWithoutPropertiesLoose(source, excluded);
73
+ var key, i;
74
+ if (Object.getOwnPropertySymbols) {
75
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
76
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
77
+ key = sourceSymbolKeys[i];
78
+ if (excluded.indexOf(key) >= 0) continue;
79
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
80
+ target[key] = source[key];
81
+ }
82
+ }
83
+ return target;
84
+ }
85
+ function _toPrimitive(input, hint) {
86
+ if (typeof input !== "object" || input === null) return input;
87
+ var prim = input[Symbol.toPrimitive];
88
+ if (prim !== undefined) {
89
+ var res = prim.call(input, hint || "default");
90
+ if (typeof res !== "object") return res;
91
+ throw new TypeError("@@toPrimitive must return a primitive value.");
92
+ }
93
+ return (hint === "string" ? String : Number)(input);
94
+ }
95
+ function _toPropertyKey(arg) {
96
+ var key = _toPrimitive(arg, "string");
97
+ return typeof key === "symbol" ? key : String(key);
98
+ }
99
+
100
+ /**
101
+ * Component style.
102
+ */
103
+ const StyledComboboxContentHeader = styled.div`
104
+ ${baseContainer}
105
+ `;
106
+
107
+ const _excluded$3 = ["children", "className"];
108
+ const COMPONENT_NAME$8 = 'ComboboxContentHeader';
109
+ const CLASSNAME$8 = 'redsift-combobox-content-header';
110
+ const DEFAULT_PROPS$8 = {};
111
+
112
+ /**
113
+ * The ComboboxContentHeader component.
114
+ */
115
+ const ComboboxContentHeader = /*#__PURE__*/forwardRef((props, ref) => {
116
+ const {
117
+ children,
118
+ className
119
+ } = props,
120
+ forwardedProps = _objectWithoutProperties(props, _excluded$3);
121
+ return /*#__PURE__*/React.createElement(StyledComboboxContentHeader, _extends({}, forwardedProps, {
122
+ className: classNames(ComboboxContentHeader.className, className),
123
+ ref: ref
124
+ }), children);
125
+ });
126
+ ComboboxContentHeader.className = CLASSNAME$8;
127
+ ComboboxContentHeader.defaultProps = DEFAULT_PROPS$8;
128
+ ComboboxContentHeader.displayName = COMPONENT_NAME$8;
129
+
130
+ /**
131
+ * Component style.
132
+ */
133
+ const StyledComboboxContentFooter = styled.div`
134
+ ${baseContainer}
135
+ `;
136
+
137
+ const _excluded$2 = ["children", "className"];
138
+ const COMPONENT_NAME$7 = 'ComboboxContentFooter';
139
+ const CLASSNAME$7 = 'redsift-combobox-content-footer';
140
+ const DEFAULT_PROPS$7 = {};
141
+
142
+ /**
143
+ * The ComboboxContentFooter component.
144
+ */
145
+ const ComboboxContentFooter = /*#__PURE__*/forwardRef((props, ref) => {
146
+ const {
147
+ children,
148
+ className
149
+ } = props,
150
+ forwardedProps = _objectWithoutProperties(props, _excluded$2);
151
+ return /*#__PURE__*/React.createElement(StyledComboboxContentFooter, _extends({}, forwardedProps, {
152
+ className: classNames(ComboboxContentFooter.className, className),
153
+ ref: ref
154
+ }), children);
155
+ });
156
+ ComboboxContentFooter.className = CLASSNAME$7;
157
+ ComboboxContentFooter.defaultProps = DEFAULT_PROPS$7;
158
+ ComboboxContentFooter.displayName = COMPONENT_NAME$7;
159
+
160
+ const _excluded$1 = ["children", "className"];
161
+ const COMPONENT_NAME$6 = 'ComboboxContentListbox';
162
+ const CLASSNAME$6 = 'redsift-combobox-content-listbox';
163
+ const DEFAULT_PROPS$6 = {};
164
+
165
+ /**
166
+ * The ComboboxContentListbox component.
167
+ */
168
+ const ComboboxContentListbox = /*#__PURE__*/forwardRef((props, ref) => {
169
+ const {
170
+ children,
171
+ className
172
+ } = props,
173
+ forwardedProps = _objectWithoutProperties(props, _excluded$1);
174
+ const focusContext = useContext(FocusWithinGroupContext);
175
+ useEffect(() => {
176
+ if (focusContext && focusContext.state.delayedAction && focusContext.state.tabStops.length) {
177
+ focusContext.dispatch(focusContext.state.delayedAction);
178
+ }
179
+ });
180
+ return /*#__PURE__*/React.createElement(Flexbox, _extends({
181
+ className: classNames(ComboboxContentListbox.className, className)
182
+ }, forwardedProps, {
183
+ ref: ref,
184
+ flexDirection: "column",
185
+ gap: "0px",
186
+ margin: "8px 0px",
187
+ style: {
188
+ outline: 'none'
189
+ },
190
+ width: "100%"
191
+ }), children);
192
+ });
193
+ ComboboxContentListbox.className = CLASSNAME$6;
194
+ ComboboxContentListbox.defaultProps = DEFAULT_PROPS$6;
195
+ ComboboxContentListbox.displayName = COMPONENT_NAME$6;
196
+
197
+ const COMPONENT_NAME$5 = 'ComboboxContent';
198
+ const CLASSNAME$5 = 'redsift-combobox-content';
199
+ const DEFAULT_PROPS$5 = {};
200
+
201
+ /**
202
+ * The ComboboxContent component.
203
+ */
204
+ const BaseComboboxContent = /*#__PURE__*/forwardRef((props, ref) => {
205
+ const {
206
+ children,
207
+ className,
208
+ style,
209
+ shouldStayOpenEvenIfEmpty
210
+ } = props;
211
+ const {
212
+ getFloatingProps,
213
+ isOpen,
214
+ handleOpen,
215
+ refs,
216
+ strategy,
217
+ x,
218
+ y
219
+ } = usePopoverContext();
220
+ const popoverRef = useMergeRefs([refs.setFloating, ref]);
221
+ const listboxState = useContext(ListboxContext);
222
+ const focusContext = useContext(FocusWithinGroupContext);
223
+ const [[header], [listbox], [footer]] = partitionComponents(React.Children.toArray(children), [isComponent('ComboboxContentHeader'), isComponent('ComboboxContentListbox'), isComponent('ComboboxContentFooter')]);
224
+ useEffect(() => {
225
+ var _focusContext$state$f, _focusContext$state$f2;
226
+ if (isOpen && (_focusContext$state$f = focusContext.state.filter) !== null && _focusContext$state$f !== void 0 && (_focusContext$state$f2 = _focusContext$state$f.value) !== null && _focusContext$state$f2 !== void 0 && _focusContext$state$f2.length && focusContext.state.tabStops.length === 0 && !shouldStayOpenEvenIfEmpty) {
227
+ handleOpen(false);
228
+ }
229
+ }, [focusContext.state]);
230
+ return /*#__PURE__*/React.createElement(FloatingPortal, {
231
+ id: "redsift-app-container"
232
+ }, isOpen && /*#__PURE__*/React.createElement(StyledPopoverContent, _extends({
233
+ ref: popoverRef,
234
+ style: _objectSpread2({
235
+ position: strategy,
236
+ top: y !== null && y !== void 0 ? y : 0,
237
+ left: x !== null && x !== void 0 ? x : 0
238
+ }, style)
239
+ }, getFloatingProps(props), {
240
+ className: classNames(PopoverContent.className, BaseComboboxContent.className, className),
241
+ "aria-disabled": listboxState.state.isDisabled,
242
+ "aria-multiselectable": listboxState.state.selectionMode === 'multiple'
243
+ }), /*#__PURE__*/React.createElement(Flexbox, {
244
+ flexDirection: "column",
245
+ gap: "0px",
246
+ width: "100%"
247
+ }, header, listbox, footer)));
248
+ });
249
+ BaseComboboxContent.className = CLASSNAME$5;
250
+ BaseComboboxContent.defaultProps = DEFAULT_PROPS$5;
251
+ BaseComboboxContent.displayName = COMPONENT_NAME$5;
252
+ const ComboboxContent = Object.assign(BaseComboboxContent, {
253
+ Header: ComboboxContentHeader,
254
+ Listbox: ComboboxContentListbox,
255
+ Footer: ComboboxContentFooter
256
+ });
257
+
258
+ var collapse$1 = "Collapse";
259
+ var expand$1 = "Expand";
260
+ var enUS = {
261
+ collapse: collapse$1,
262
+ expand: expand$1
263
+ };
264
+
265
+ var collapse = "Réduire";
266
+ var expand = "Développer";
267
+ var frFR = {
268
+ collapse: collapse,
269
+ expand: expand
270
+ };
271
+
272
+ var intlMessages = {
273
+ 'en-US': enUS,
274
+ 'fr-FR': frFR
275
+ };
276
+
277
+ const ComboboxContext = /*#__PURE__*/React.createContext(null);
278
+
279
+ const _excluded = ["aria-controls", "aria-expanded", "aria-haspopup", "role"];
280
+ const COMPONENT_NAME$4 = 'ComboboxTrigger';
281
+ const CLASSNAME$4 = 'redsift-combobox-trigger';
282
+ const DEFAULT_PROPS$4 = {};
283
+
284
+ /**
285
+ * The ComboboxTrigger component.
286
+ */
287
+ const ComboboxTrigger = /*#__PURE__*/forwardRef((props, ref) => {
288
+ const {
289
+ children,
290
+ hideExpandButton,
291
+ openOnFocus
292
+ } = props;
293
+ const stringFormatter = useLocalizedStringFormatter(intlMessages);
294
+ const {
295
+ getReferenceProps,
296
+ isOpen,
297
+ handleOpen: handleOpenPopover,
298
+ refs
299
+ } = usePopoverContext();
300
+ const childrenRef = children.ref;
301
+ const triggerRef = useMergeRefs([refs.setReference, ref, childrenRef]);
302
+ const focusContext = useContext(FocusWithinGroupContext);
303
+ const comboboxState = useContext(ComboboxContext);
304
+ const listboxState = useContext(ListboxContext);
305
+ const renderedChildren = typeof children === 'function' ? children({
306
+ value: comboboxState === null || comboboxState === void 0 ? void 0 : comboboxState.value,
307
+ isOpen
308
+ }) : children;
309
+ const handleChange = value => {
310
+ focusContext.dispatch({
311
+ type: FocusWithinGroupActionType.FILTER_LIST,
312
+ payload: {
313
+ filter: _objectSpread2({
314
+ value: value || ''
315
+ }, comboboxState === null || comboboxState === void 0 ? void 0 : comboboxState.filter)
316
+ }
317
+ });
318
+ comboboxState === null || comboboxState === void 0 ? void 0 : comboboxState.setValue(value);
319
+ };
320
+ const handleKeyDown = event => {
321
+ const code = event.code;
322
+ if (code === 'Escape' || code === 'Tab') {
323
+ if (isOpen) {
324
+ handleOpenPopover(false);
325
+ }
326
+ }
327
+ if (/^.$/u.test(event.key) || code === 'Backspace') {
328
+ if (!isOpen) {
329
+ handleOpenPopover(true);
330
+ }
331
+ }
332
+ if (code === 'ArrowDown') {
333
+ if (!isOpen) {
334
+ handleOpenPopover(true);
335
+ }
336
+ focusContext.dispatch({
337
+ type: FocusWithinGroupActionType.DELAY_ACTION,
338
+ payload: {
339
+ type: FocusWithinGroupActionType.KEY_DOWN_ON_LIST,
340
+ payload: {
341
+ key: focusContext.state.selectedId !== null ? EventKey.ArrowDown : EventKey.Home,
342
+ ctrlKey: event.ctrlKey
343
+ }
344
+ }
345
+ });
346
+ event.preventDefault();
347
+ }
348
+ if (code === 'ArrowUp') {
349
+ if (!isOpen) {
350
+ handleOpenPopover(true);
351
+ }
352
+ focusContext.dispatch({
353
+ type: FocusWithinGroupActionType.DELAY_ACTION,
354
+ payload: {
355
+ type: FocusWithinGroupActionType.KEY_DOWN_ON_LIST,
356
+ payload: {
357
+ key: focusContext.state.selectedId !== null ? EventKey.ArrowUp : EventKey.End,
358
+ ctrlKey: event.ctrlKey
359
+ }
360
+ }
361
+ });
362
+ event.preventDefault();
363
+ }
364
+ if (code === 'Enter') {
365
+ if (isOpen && focusContext.state.selectedId) {
366
+ if (listboxState.state.selectionMode === 'multiple') {
367
+ var _focusContext$state$a, _focusContext$state$a2;
368
+ listboxState.dispatch({
369
+ type: ListboxActionType.TOGGLE,
370
+ payload: {
371
+ value: (_focusContext$state$a = (_focusContext$state$a2 = focusContext.state.activedescendant) === null || _focusContext$state$a2 === void 0 ? void 0 : _focusContext$state$a2[1]) !== null && _focusContext$state$a !== void 0 ? _focusContext$state$a : '',
372
+ activedescendant: focusContext.state.activedescendant
373
+ }
374
+ });
375
+ } else {
376
+ var _focusContext$state$a3, _focusContext$state$a4;
377
+ listboxState.dispatch({
378
+ type: ListboxActionType.SET,
379
+ payload: {
380
+ values: [(_focusContext$state$a3 = (_focusContext$state$a4 = focusContext.state.activedescendant) === null || _focusContext$state$a4 === void 0 ? void 0 : _focusContext$state$a4[1]) !== null && _focusContext$state$a3 !== void 0 ? _focusContext$state$a3 : ''],
381
+ activedescendant: focusContext.state.activedescendant
382
+ }
383
+ });
384
+ }
385
+ }
386
+ }
387
+ };
388
+ const handleOpen = () => {
389
+ if (isOpen) {
390
+ handleOpenPopover(false);
391
+ } else {
392
+ var _focusContext$state$a5, _focusContext$state$a6;
393
+ handleOpenPopover(true);
394
+ focusContext.dispatch({
395
+ type: FocusWithinGroupActionType.DELAY_ACTION,
396
+ payload: {
397
+ type: FocusWithinGroupActionType.FOCUS_ON_LIST,
398
+ payload: {
399
+ id: (_focusContext$state$a5 = (_focusContext$state$a6 = focusContext.state.activedescendant) === null || _focusContext$state$a6 === void 0 ? void 0 : _focusContext$state$a6[0]) !== null && _focusContext$state$a5 !== void 0 ? _focusContext$state$a5 : ''
400
+ }
401
+ }
402
+ });
403
+ }
404
+ };
405
+ useEffect(() => {
406
+ comboboxState === null || comboboxState === void 0 ? void 0 : comboboxState.setValue(listboxState.state.selectedValues[0]);
407
+ handleOpenPopover(false);
408
+ }, [listboxState.state]);
409
+ if (isComponent('TextField')(renderedChildren)) {
410
+ var _focusContext$state$a7;
411
+ const _getReferenceProps = getReferenceProps(_objectSpread2(_objectSpread2({
412
+ ref: triggerRef
413
+ }, props), renderedChildren.props)),
414
+ {
415
+ 'aria-controls': ariaControls,
416
+ 'aria-expanded': ariaExpanded,
417
+ 'aria-haspopup': ariaHaspopup,
418
+ role
419
+ } = _getReferenceProps,
420
+ forwardedProps = _objectWithoutProperties(_getReferenceProps, _excluded);
421
+ return /*#__PURE__*/React.cloneElement(renderedChildren, _objectSpread2(_objectSpread2(_objectSpread2({}, forwardedProps), {}, {
422
+ inputProps: {
423
+ 'aria-activedescendant': isOpen ? (_focusContext$state$a7 = focusContext.state.activedescendant) === null || _focusContext$state$a7 === void 0 ? void 0 : _focusContext$state$a7[0] : undefined,
424
+ 'aria-controls': ariaControls,
425
+ 'aria-expanded': ariaExpanded,
426
+ 'aria-haspopup': ariaHaspopup,
427
+ onKeyDown: handleKeyDown,
428
+ role
429
+ },
430
+ isDisabled: comboboxState === null || comboboxState === void 0 ? void 0 : comboboxState.isDisabled,
431
+ isInvalid: comboboxState === null || comboboxState === void 0 ? void 0 : comboboxState.isInvalid,
432
+ onChange: handleChange
433
+ }, openOnFocus && {
434
+ onFocus: handleOpen
435
+ }), {}, {
436
+ value: comboboxState === null || comboboxState === void 0 ? void 0 : comboboxState.value,
437
+ internal: (value, isDisabled, isInvalid, isRequired) => {
438
+ return /*#__PURE__*/React.createElement(React.Fragment, null, typeof renderedChildren.props.internal === 'function' ? renderedChildren.props.internal(value, isDisabled, isInvalid, isRequired) : renderedChildren.props.internal, hideExpandButton ? null : /*#__PURE__*/React.createElement(IconButton, {
439
+ "aria-label": stringFormatter.format(!isOpen ? 'expand' : 'collapse'),
440
+ color: "question",
441
+ icon: mdiUnfoldMoreHorizontal,
442
+ onClick: handleOpen,
443
+ isDisabled: isDisabled,
444
+ tabIndex: -1
445
+ }));
446
+ }
447
+ }));
448
+ }
449
+ return /*#__PURE__*/React.createElement(React.Fragment, null, renderedChildren);
450
+ });
451
+ ComboboxTrigger.className = CLASSNAME$4;
452
+ ComboboxTrigger.defaultProps = DEFAULT_PROPS$4;
453
+ ComboboxTrigger.displayName = COMPONENT_NAME$4;
454
+
455
+ const COMPONENT_NAME$3 = 'Combobox';
456
+ const CLASSNAME$3 = 'redsift-combobox';
457
+ const DEFAULT_PROPS$3 = {
458
+ filter: {
459
+ type: 'startsWith',
460
+ caseSensitive: false
461
+ },
462
+ minWidth: 'trigger-width'
463
+ };
464
+
465
+ /**
466
+ * The Combobox component.
467
+ */
468
+ const BaseCombobox = props => {
469
+ const {
470
+ defaultValue,
471
+ description,
472
+ descriptionProps,
473
+ filter,
474
+ isDisabled,
475
+ isInvalid,
476
+ onChange,
477
+ value
478
+ } = props;
479
+ const [selectedValue, setValue] = useState(value || defaultValue || '');
480
+ useEffect(() => {
481
+ if (value) {
482
+ state.setValue(value);
483
+ }
484
+ }, [value]);
485
+
486
+ /** Listbox context */
487
+ const [listboxState, listboxDispatch] = useReducer(ListboxReducer, {
488
+ isDisabled,
489
+ selectedValues: [selectedValue]
490
+ });
491
+ const listboxContext = useMemo(() => ({
492
+ state: listboxState,
493
+ dispatch: listboxDispatch
494
+ }), [listboxState]);
495
+
496
+ /** Combobox context. */
497
+ const state = {
498
+ filter,
499
+ value: selectedValue,
500
+ isDisabled: isDisabled || false,
501
+ isInvalid: isInvalid || false,
502
+ setValue(value) {
503
+ if (isDisabled) {
504
+ return;
505
+ }
506
+ const previousValue = selectedValue;
507
+ setValue(value);
508
+ if (value !== previousValue && onChange) {
509
+ onChange(value);
510
+ }
511
+ }
512
+ };
513
+ return /*#__PURE__*/React.createElement(FocusWithinGroup, {
514
+ focusType: "virtual-focus",
515
+ focusOnInit: false
516
+ }, /*#__PURE__*/React.createElement(ComboboxContext.Provider, {
517
+ value: state
518
+ }, /*#__PURE__*/React.createElement(ListboxContext.Provider, {
519
+ value: listboxContext
520
+ }, /*#__PURE__*/React.createElement(Flexbox, {
521
+ flexDirection: "column",
522
+ alignItems: "flex-start",
523
+ gap: "0px"
524
+ }, /*#__PURE__*/React.createElement(Popover, _extends({
525
+ overrideDisplayName: {
526
+ content: 'ComboboxContent',
527
+ trigger: 'ComboboxTrigger'
528
+ },
529
+ placement: "bottom-start",
530
+ role: "listbox"
531
+ }, props)), description && typeof description === 'string' ? /*#__PURE__*/React.createElement(Text, _extends({
532
+ variant: "caption",
533
+ color: isInvalid ? 'error' : 'darkgrey'
534
+ }, descriptionProps), description) : description ? description : null))));
535
+ };
536
+ BaseCombobox.className = CLASSNAME$3;
537
+ BaseCombobox.defaultProps = DEFAULT_PROPS$3;
538
+ BaseCombobox.displayName = COMPONENT_NAME$3;
539
+ const Combobox = Object.assign(BaseCombobox, {
540
+ Trigger: ComboboxTrigger,
541
+ Content: ComboboxContent
542
+ });
543
+
544
+ const COMPONENT_NAME$2 = 'SelectContent';
545
+ const CLASSNAME$2 = 'redsift-select-content';
546
+ const DEFAULT_PROPS$2 = {};
547
+
548
+ /**
549
+ * The SelectContent component.
550
+ */
551
+ const SelectContent = /*#__PURE__*/forwardRef((props, ref) => {
552
+ const {
553
+ children,
554
+ className,
555
+ style
556
+ } = props;
557
+ const {
558
+ getFloatingProps,
559
+ isOpen,
560
+ refs,
561
+ strategy,
562
+ x,
563
+ y
564
+ } = usePopoverContext();
565
+ const popoverRef = useMergeRefs([refs.setFloating, ref]);
566
+ const focusContext = useContext(FocusWithinGroupContext);
567
+ const listboxState = useContext(ListboxContext);
568
+ useEffect(() => {
569
+ if (focusContext && focusContext.state.delayedAction && focusContext.state.tabStops.length) {
570
+ focusContext.dispatch(focusContext.state.delayedAction);
571
+ }
572
+ }, [focusContext.state.delayedAction, focusContext.state.tabStops.length]);
573
+ return /*#__PURE__*/React.createElement(FloatingPortal, {
574
+ id: "redsift-app-container"
575
+ }, isOpen && /*#__PURE__*/React.createElement(StyledPopoverContent, _extends({
576
+ ref: popoverRef,
577
+ style: _objectSpread2({
578
+ position: strategy,
579
+ top: y !== null && y !== void 0 ? y : 0,
580
+ left: x !== null && x !== void 0 ? x : 0
581
+ }, style)
582
+ }, getFloatingProps(props), {
583
+ className: classNames(PopoverContent.className, SelectContent.className, className),
584
+ "aria-disabled": listboxState.state.isDisabled,
585
+ "aria-multiselectable": listboxState.state.selectionMode === 'multiple'
586
+ }), /*#__PURE__*/React.createElement(Flexbox, {
587
+ flexDirection: "column",
588
+ gap: "8px",
589
+ margin: "8px 0px",
590
+ width: "100%"
591
+ }, children)));
592
+ });
593
+ SelectContent.className = CLASSNAME$2;
594
+ SelectContent.defaultProps = DEFAULT_PROPS$2;
595
+ SelectContent.displayName = COMPONENT_NAME$2;
596
+
597
+ const SelectContext = /*#__PURE__*/React.createContext(null);
598
+
599
+ const COMPONENT_NAME$1 = 'SelectTrigger';
600
+ const CLASSNAME$1 = 'redsift-select-trigger';
601
+ const DEFAULT_PROPS$1 = {};
602
+
603
+ /**
604
+ * The SelectTrigger component.
605
+ */
606
+ const SelectTrigger = /*#__PURE__*/forwardRef((props, ref) => {
607
+ const {
608
+ children
609
+ } = props;
610
+ const {
611
+ getReferenceProps,
612
+ isOpen,
613
+ handleOpen,
614
+ refs
615
+ } = usePopoverContext();
616
+ const childrenRef = children.ref;
617
+ const triggerRef = useMergeRefs([refs.setReference, ref, childrenRef]);
618
+ const focusContext = useContext(FocusWithinGroupContext);
619
+ const selectContext = useContext(SelectContext);
620
+ const listboxState = useContext(ListboxContext);
621
+ const renderedChildren = typeof children === 'function' ? children({
622
+ value: selectContext === null || selectContext === void 0 ? void 0 : selectContext.value,
623
+ isOpen
624
+ }) : children;
625
+ const handleKeyDown = event => {
626
+ const code = event.code;
627
+ if (code === 'Escape') {
628
+ if (isOpen) {
629
+ handleOpen(false);
630
+ }
631
+ } else if (code === 'ArrowDown') {
632
+ var _focusContext$state$a;
633
+ if (!isOpen) {
634
+ handleOpen(true);
635
+ }
636
+ if (focusContext.state.selectedId !== null) {
637
+ focusContext.dispatch({
638
+ type: FocusWithinGroupActionType.DELAY_ACTION,
639
+ payload: {
640
+ type: FocusWithinGroupActionType.KEY_DOWN_ON_LIST,
641
+ payload: {
642
+ key: EventKey.ArrowDown,
643
+ ctrlKey: event.ctrlKey
644
+ }
645
+ }
646
+ });
647
+ } else if (!((_focusContext$state$a = focusContext.state.activedescendant) !== null && _focusContext$state$a !== void 0 && _focusContext$state$a[0])) {
648
+ focusContext.dispatch({
649
+ type: FocusWithinGroupActionType.DELAY_ACTION,
650
+ payload: {
651
+ type: FocusWithinGroupActionType.KEY_DOWN_ON_LIST,
652
+ payload: {
653
+ key: EventKey.Home,
654
+ ctrlKey: event.ctrlKey
655
+ }
656
+ }
657
+ });
658
+ } else {
659
+ var _focusContext$state$a2, _focusContext$state$a3;
660
+ focusContext.dispatch({
661
+ type: FocusWithinGroupActionType.DELAY_ACTION,
662
+ payload: {
663
+ type: FocusWithinGroupActionType.FOCUS_ON_LIST,
664
+ payload: {
665
+ id: (_focusContext$state$a2 = (_focusContext$state$a3 = focusContext.state.activedescendant) === null || _focusContext$state$a3 === void 0 ? void 0 : _focusContext$state$a3[0]) !== null && _focusContext$state$a2 !== void 0 ? _focusContext$state$a2 : ''
666
+ }
667
+ }
668
+ });
669
+ }
670
+ event.preventDefault();
671
+ } else if (code === 'ArrowUp') {
672
+ if (!isOpen) {
673
+ handleOpen(true);
674
+ }
675
+ focusContext.dispatch({
676
+ type: FocusWithinGroupActionType.DELAY_ACTION,
677
+ payload: {
678
+ type: FocusWithinGroupActionType.KEY_DOWN_ON_LIST,
679
+ payload: {
680
+ key: focusContext.state.selectedId !== null ? EventKey.ArrowUp : EventKey.Home,
681
+ ctrlKey: event.ctrlKey
682
+ }
683
+ }
684
+ });
685
+ event.preventDefault();
686
+ } else if (code === 'Home') {
687
+ if (!isOpen) {
688
+ handleOpen(true);
689
+ }
690
+ focusContext.dispatch({
691
+ type: FocusWithinGroupActionType.DELAY_ACTION,
692
+ payload: {
693
+ type: FocusWithinGroupActionType.KEY_DOWN_ON_LIST,
694
+ payload: {
695
+ key: EventKey.Home,
696
+ ctrlKey: event.ctrlKey
697
+ }
698
+ }
699
+ });
700
+ event.preventDefault();
701
+ } else if (code === 'End') {
702
+ if (!isOpen) {
703
+ handleOpen(true);
704
+ }
705
+ focusContext.dispatch({
706
+ type: FocusWithinGroupActionType.DELAY_ACTION,
707
+ payload: {
708
+ type: FocusWithinGroupActionType.KEY_DOWN_ON_LIST,
709
+ payload: {
710
+ key: EventKey.End,
711
+ ctrlKey: event.ctrlKey
712
+ }
713
+ }
714
+ });
715
+ event.preventDefault();
716
+ } else if (code === 'Enter') {
717
+ if (isOpen && focusContext.state.selectedId) {
718
+ if (listboxState.state.selectionMode === 'multiple') {
719
+ var _focusContext$state$a4, _focusContext$state$a5;
720
+ listboxState.dispatch({
721
+ type: ListboxActionType.TOGGLE,
722
+ payload: {
723
+ value: (_focusContext$state$a4 = (_focusContext$state$a5 = focusContext.state.activedescendant) === null || _focusContext$state$a5 === void 0 ? void 0 : _focusContext$state$a5[1]) !== null && _focusContext$state$a4 !== void 0 ? _focusContext$state$a4 : '',
724
+ activedescendant: focusContext.state.activedescendant
725
+ }
726
+ });
727
+ } else {
728
+ var _focusContext$state$a6, _focusContext$state$a7;
729
+ listboxState.dispatch({
730
+ type: ListboxActionType.SET,
731
+ payload: {
732
+ values: [(_focusContext$state$a6 = (_focusContext$state$a7 = focusContext.state.activedescendant) === null || _focusContext$state$a7 === void 0 ? void 0 : _focusContext$state$a7[1]) !== null && _focusContext$state$a6 !== void 0 ? _focusContext$state$a6 : ''],
733
+ activedescendant: focusContext.state.activedescendant
734
+ }
735
+ });
736
+ }
737
+ }
738
+ }
739
+ };
740
+ const handleClick = event => {
741
+ event.preventDefault();
742
+ if (isOpen) {
743
+ handleOpen(false);
744
+ } else {
745
+ var _focusContext$state$a8, _focusContext$state$a9;
746
+ handleOpen(true);
747
+ focusContext.dispatch({
748
+ type: FocusWithinGroupActionType.DELAY_ACTION,
749
+ payload: {
750
+ type: FocusWithinGroupActionType.FOCUS_ON_LIST,
751
+ payload: {
752
+ id: (_focusContext$state$a8 = (_focusContext$state$a9 = focusContext.state.activedescendant) === null || _focusContext$state$a9 === void 0 ? void 0 : _focusContext$state$a9[0]) !== null && _focusContext$state$a8 !== void 0 ? _focusContext$state$a8 : ''
753
+ }
754
+ }
755
+ });
756
+ }
757
+ };
758
+ useEffect(() => {
759
+ selectContext === null || selectContext === void 0 ? void 0 : selectContext.setValue(listboxState.state.selectedValues[0]);
760
+ handleOpen(false);
761
+ }, [listboxState.state]);
762
+ if (isComponent('Button')(renderedChildren)) {
763
+ var _focusContext$state$a10;
764
+ return /*#__PURE__*/React.cloneElement(renderedChildren, _objectSpread2(_objectSpread2(_objectSpread2({}, getReferenceProps(_objectSpread2(_objectSpread2({
765
+ ref: triggerRef
766
+ }, props), renderedChildren.props))), {}, {
767
+ role: 'combobox',
768
+ 'aria-activedescendant': isOpen ? (_focusContext$state$a10 = focusContext.state.activedescendant) === null || _focusContext$state$a10 === void 0 ? void 0 : _focusContext$state$a10[0] : undefined,
769
+ isDisabled: selectContext === null || selectContext === void 0 ? void 0 : selectContext.isDisabled
770
+ }, (selectContext === null || selectContext === void 0 ? void 0 : selectContext.isInvalid) === true && {
771
+ color: 'error'
772
+ }), {}, {
773
+ onKeyDown: handleKeyDown,
774
+ onClick: handleClick,
775
+ isActive: isOpen
776
+ }, typeof children !== 'function' && (selectContext === null || selectContext === void 0 ? void 0 : selectContext.value) && {
777
+ children: selectContext.value
778
+ }));
779
+ }
780
+ return /*#__PURE__*/React.createElement(React.Fragment, null, renderedChildren);
781
+ });
782
+ SelectTrigger.className = CLASSNAME$1;
783
+ SelectTrigger.defaultProps = DEFAULT_PROPS$1;
784
+ SelectTrigger.displayName = COMPONENT_NAME$1;
785
+
786
+ const COMPONENT_NAME = 'Select';
787
+ const CLASSNAME = 'redsift-select';
788
+ const DEFAULT_PROPS = {
789
+ minWidth: 'trigger-width'
790
+ };
791
+
792
+ /**
793
+ * The Select component.
794
+ */
795
+ const BaseSelect = props => {
796
+ const {
797
+ defaultValue,
798
+ isDisabled,
799
+ onChange,
800
+ value,
801
+ label,
802
+ labelProps,
803
+ description,
804
+ descriptionProps,
805
+ isInvalid
806
+ } = props;
807
+ const [selectedValue, setValue] = useState(value || defaultValue || '');
808
+ useEffect(() => {
809
+ if (value) {
810
+ state.setValue(value);
811
+ }
812
+ }, [value]);
813
+
814
+ /** Listbox context */
815
+ const [listboxState, listboxDispatch] = useReducer(ListboxReducer, {
816
+ isDisabled,
817
+ selectedValues: [selectedValue]
818
+ });
819
+ const listboxContext = useMemo(() => ({
820
+ state: listboxState,
821
+ dispatch: listboxDispatch
822
+ }), [listboxState]);
823
+
824
+ /** Select context. */
825
+ const state = {
826
+ value: selectedValue,
827
+ isDisabled: isDisabled || false,
828
+ isInvalid: isInvalid || false,
829
+ setValue(value) {
830
+ if (isDisabled) {
831
+ return;
832
+ }
833
+ const previousValue = selectedValue;
834
+ setValue(value);
835
+ if (value !== previousValue && onChange) {
836
+ onChange(value);
837
+ }
838
+ }
839
+ };
840
+ return /*#__PURE__*/React.createElement(FocusWithinGroup, {
841
+ focusType: "virtual-focus",
842
+ focusOnInit: false
843
+ }, /*#__PURE__*/React.createElement(SelectContext.Provider, {
844
+ value: state
845
+ }, /*#__PURE__*/React.createElement(ListboxContext.Provider, {
846
+ value: listboxContext
847
+ }, /*#__PURE__*/React.createElement(Flexbox, {
848
+ flexDirection: "column",
849
+ alignItems: "flex-start",
850
+ gap: "0px"
851
+ }, label && typeof label === 'string' ? /*#__PURE__*/React.createElement(Text, _extends({
852
+ color: isInvalid ? 'error' : 'black'
853
+ }, labelProps), label) : label ? label : null, /*#__PURE__*/React.createElement(Popover, _extends({
854
+ overrideDisplayName: {
855
+ content: 'SelectContent',
856
+ trigger: 'SelectTrigger'
857
+ },
858
+ placement: "bottom-start",
859
+ role: "listbox"
860
+ }, props)), description && typeof description === 'string' ? /*#__PURE__*/React.createElement(Text, _extends({
861
+ variant: "caption",
862
+ color: isInvalid ? 'error' : 'darkgrey'
863
+ }, descriptionProps), description) : description ? description : null))));
864
+ };
865
+ BaseSelect.className = CLASSNAME;
866
+ BaseSelect.defaultProps = DEFAULT_PROPS;
867
+ BaseSelect.displayName = COMPONENT_NAME;
868
+ const Select = Object.assign(BaseSelect, {
869
+ Trigger: SelectTrigger,
870
+ Content: SelectContent
871
+ });
872
+
873
+ export { BaseCombobox, BaseComboboxContent, BaseSelect, Combobox, ComboboxContent, ComboboxContentFooter, ComboboxContentHeader, ComboboxContentListbox, ComboboxTrigger, Select, SelectContent, SelectTrigger };
874
+ //# sourceMappingURL=index.js.map