@dbcdk/react-components 0.0.56 → 0.0.58
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/dist/components/forms/input/Input.js +5 -2
- package/dist/components/forms/input/Input.module.css +6 -2
- package/dist/components/forms/multi-select/MultiSelect.js +1 -1
- package/dist/components/forms/select/Select.js +1 -1
- package/dist/components/forms/typeahead/Typeahead.js +84 -7
- package/dist/components/popover/Popover.d.ts +1 -0
- package/dist/components/popover/Popover.js +17 -2
- package/package.json +1 -1
|
@@ -28,6 +28,8 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
|
|
|
28
28
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
29
29
|
}, [autoFocus]);
|
|
30
30
|
const hasButton = Boolean(onButtonClick || buttonLabel || buttonIcon);
|
|
31
|
+
const hasVisibleClear = Boolean(onClear && inputProps.value);
|
|
32
|
+
const hasInlineClear = Boolean(hasVisibleClear && endAdornment);
|
|
31
33
|
const rootStyle = {
|
|
32
34
|
...(style !== null && style !== void 0 ? style : {}),
|
|
33
35
|
...(minWidth ? { ['--input-min-width']: minWidth } : null),
|
|
@@ -43,7 +45,8 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
|
|
|
43
45
|
return (_jsx(InputContainer, { label: label, htmlFor: inputId, fullWidth: fullWidth, error: error, helpText: helpText, orientation: orientation, labelWidth: labelWidth, required: required, modified: modified, children: _jsxs("div", { style: rootStyle, className: [
|
|
44
46
|
styles.container,
|
|
45
47
|
fullWidth ? styles.fullWidth : '',
|
|
46
|
-
|
|
48
|
+
hasVisibleClear ? styles.withClear : '',
|
|
49
|
+
hasInlineClear ? styles.withInlineClear : '',
|
|
47
50
|
hasButton ? styles.withButton : '',
|
|
48
51
|
className !== null && className !== void 0 ? className : '',
|
|
49
52
|
]
|
|
@@ -59,6 +62,6 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
|
|
|
59
62
|
.filter(Boolean)
|
|
60
63
|
.join(' '), "data-forminput": "field", "data-modified": modified ? 'true' : undefined, "aria-disabled": inputProps.disabled ? 'true' : undefined, ...(tooltip ? triggerProps : {}), children: [icon && _jsx("span", { className: styles.icon, children: icon }), startAdornment && _jsx("span", { className: styles.startAdornment, children: startAdornment }), _jsx("input", { ...inputProps, id: inputId, ref: mergeRefs(inputRef, ref), className: [styles.input, inputSize ? styles[inputSize] : '', inputClassName !== null && inputClassName !== void 0 ? inputClassName : '']
|
|
61
64
|
.filter(Boolean)
|
|
62
|
-
.join(' ') }), endAdornment &&
|
|
65
|
+
.join(' ') }), (hasInlineClear || endAdornment) && (_jsxs("span", { className: styles.endAdornment, children: [hasInlineClear && onClear ? _jsx(ClearButton, { onClick: onClear }) : null, endAdornment] })), hasVisibleClear && !hasInlineClear && onClear ? (_jsx(ClearButton, { onClick: onClear, absolute: true })) : null] }), hasButton && (_jsxs(Button, { onClick: onButtonClick, className: styles.trailingButton, type: "button", variant: trailingButtonVariant, size: inputSize, children: [buttonIcon !== null && buttonIcon !== void 0 ? buttonIcon : null, buttonLabel !== null && buttonLabel !== void 0 ? buttonLabel : null] }))] }) }));
|
|
63
66
|
});
|
|
64
67
|
Input.displayName = 'Input';
|
|
@@ -77,6 +77,10 @@
|
|
|
77
77
|
padding-inline-end: calc(var(--spacing-xxs) + 16px + var(--spacing-xxs));
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
.withInlineClear .input {
|
|
81
|
+
padding-inline-end: var(--spacing-xs);
|
|
82
|
+
}
|
|
83
|
+
|
|
80
84
|
/* Global focus reset - variants own visible focus treatment */
|
|
81
85
|
.input:focus-visible {
|
|
82
86
|
outline: none;
|
|
@@ -395,6 +399,6 @@
|
|
|
395
399
|
.endAdornment {
|
|
396
400
|
display: flex;
|
|
397
401
|
align-items: center;
|
|
398
|
-
|
|
399
|
-
|
|
402
|
+
margin-right: var(--spacing-xxs);
|
|
403
|
+
color: var(--color-fg-subtle);
|
|
400
404
|
}
|
|
@@ -101,7 +101,7 @@ export function MultiSelect({ options, selectedValues = [], onChange, placeholde
|
|
|
101
101
|
else {
|
|
102
102
|
setSearchQuery('');
|
|
103
103
|
}
|
|
104
|
-
}, dataCy: dataCy, fullWidth: fullWidth, autoFocusContent: false, returnFocus: true, trigger: (onClick, icon, isOpen) => (_jsx(Button, { variant: variant, onClick: onClick, onKeyDown: handleCombinedKeyDown, size: size, fullWidth: fullWidth, disabled: disabled, "aria-haspopup": "menu", "aria-expanded": !!isOpen, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [_jsx("span", { children: children !== null && children !== void 0 ? children : placeholder }), selectedValues.length > 0 ? _jsx(Chip, { size: "sm", children: selectedValues.length }) : null] }), _jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [onClear && selectedValues.length > 0 ? _jsx(ClearButton, { onClick: onClear }) : null, icon] })] }) })), children: _jsxs(Menu, { onKeyDown: handleCombinedKeyDown, children: [searchable ? (_jsx(Menu.Item, { children: _jsx(Input, { ref: searchInputRef, value: searchQuery, onChange: e => setSearchQuery(e.target.value), onKeyDown: handleCombinedKeyDown, placeholder: searchPlaceholder, icon: _jsx(Search, { size: 16 }), fullWidth: true }) })) : null, filteredOptions.map((option, index) => {
|
|
104
|
+
}, dataCy: dataCy, fullWidth: fullWidth, autoFocusContent: false, returnFocus: true, trigger: (onClick, icon, isOpen) => (_jsx(Button, { variant: variant, onClick: onClick, onKeyDown: handleCombinedKeyDown, size: size, fullWidth: fullWidth, disabled: disabled, "aria-haspopup": "menu", "aria-expanded": !!isOpen, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [_jsx("span", { children: children !== null && children !== void 0 ? children : placeholder }), selectedValues.length > 0 ? _jsx(Chip, { size: "sm", children: selectedValues.length }) : null] }), _jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [onClear && selectedValues.length > 0 ? _jsx(ClearButton, { onClick: onClear }) : null, _jsx("span", { style: { color: 'var(--color-fg-subtle)', display: 'inline-flex' }, children: icon })] })] }) })), children: _jsxs(Menu, { onKeyDown: handleCombinedKeyDown, children: [searchable ? (_jsx(Menu.Item, { children: _jsx(Input, { ref: searchInputRef, value: searchQuery, onChange: e => setSearchQuery(e.target.value), onKeyDown: handleCombinedKeyDown, placeholder: searchPlaceholder, icon: _jsx(Search, { size: 16 }), fullWidth: true }) })) : null, filteredOptions.map((option, index) => {
|
|
105
105
|
const isSelected = selectedSet.has(option.value);
|
|
106
106
|
const isActive = index === activeIndex;
|
|
107
107
|
return (_jsx(Menu.Item, { active: isActive, children: _jsxs("button", { ref: el => {
|
|
@@ -168,7 +168,7 @@ export function Select({ label, error, helpText, orientation = 'vertical', label
|
|
|
168
168
|
returnFocus: true, trigger: (toggle, icon, isOpen) => (_jsx(Button, { disabled: disabled, ...(tooltipEnabled ? triggerProps : {}), id: controlId, "data-cy": dataCy !== null && dataCy !== void 0 ? dataCy : 'select-button', onKeyDown: handleKeyDown, fullWidth: fullWidth, variant: variant, onClick: e => {
|
|
169
169
|
resetActiveToSelected();
|
|
170
170
|
toggle(e);
|
|
171
|
-
}, size: size, type: "button", "data-forminput": true, "aria-haspopup": "listbox", "aria-expanded": !!isOpen, "aria-controls": listboxId, "aria-invalid": Boolean(error) || undefined, "aria-describedby": describedBy, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsx("span", { children: selected ? selected.label : _jsx("span", { className: "dbc-muted-text", children: placeholder }) }), _jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [onClear && selected && _jsx(ClearButton, { onClick: onClear }), icon] })] }) })), children: _jsx(Menu, { onKeyDown: handleKeyDown, role: "listbox", children: options.map((opt, index) => {
|
|
171
|
+
}, size: size, type: "button", "data-forminput": true, "aria-haspopup": "listbox", "aria-expanded": !!isOpen, "aria-controls": listboxId, "aria-invalid": Boolean(error) || undefined, "aria-describedby": describedBy, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsx("span", { children: selected ? selected.label : _jsx("span", { className: "dbc-muted-text", children: placeholder }) }), _jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [onClear && selected && _jsx(ClearButton, { onClick: onClear }), _jsx("span", { style: { color: 'var(--color-fg-subtle)', display: 'inline-flex' }, children: icon })] })] }) })), children: _jsx(Menu, { onKeyDown: handleKeyDown, role: "listbox", children: options.map((opt, index) => {
|
|
172
172
|
const isSelected = typeof opt.value === 'object' && typeof selectedValue === 'object' && datakey
|
|
173
173
|
? (selectedValue === null || selectedValue === void 0 ? void 0 : selectedValue[datakey]) === opt.value[datakey]
|
|
174
174
|
: opt.value === selectedValue;
|
|
@@ -9,12 +9,14 @@ import { Popover } from '../../../components/popover/Popover';
|
|
|
9
9
|
import styles from './Typeahead.module.css';
|
|
10
10
|
export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'chips', multiSelectedValuesDisplayMode = 'hidden', multiSelectedValueChipContent = 'label', selectedValue = null, onChange, placeholder, variant = 'outlined', disabled = false, fullWidth = false, onClear, emptyMessage = 'Ingen resultater', filterOptions, inputProps, inputSize, width, minWidth, autoComplete, autoCorrect, autoCapitalize, spellCheck, popoverAnchorRef, }) {
|
|
11
11
|
var _a;
|
|
12
|
+
const rootRef = useRef(null);
|
|
12
13
|
const inputRef = useRef(null);
|
|
13
14
|
const listboxRef = useRef(null);
|
|
15
|
+
const popoverContentRef = useRef(null);
|
|
14
16
|
const optionRefs = useRef([]);
|
|
15
17
|
const interactingWithOptionsRef = useRef(false);
|
|
16
18
|
const listboxId = useId();
|
|
17
|
-
const { onFocus: inputPropsOnFocus, onBlur: inputPropsOnBlur, onKeyDown: inputPropsOnKeyDown, onMouseDown: inputPropsOnMouseDown, onClear: inputPropsOnClear, startAdornment: inputPropsStartAdornment, ...passthroughInputProps } = inputProps !== null && inputProps !== void 0 ? inputProps : {};
|
|
19
|
+
const { onFocus: inputPropsOnFocus, onBlur: inputPropsOnBlur, onKeyDown: inputPropsOnKeyDown, onMouseDown: inputPropsOnMouseDown, onClear: inputPropsOnClear, startAdornment: inputPropsStartAdornment, endAdornment: inputPropsEndAdornment, ...passthroughInputProps } = inputProps !== null && inputProps !== void 0 ? inputProps : {};
|
|
18
20
|
const selectedOption = useMemo(() => {
|
|
19
21
|
var _a;
|
|
20
22
|
if (mode === 'multi')
|
|
@@ -105,6 +107,75 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
105
107
|
const activeEl = optionRefs.current[activeIndex];
|
|
106
108
|
(_a = activeEl === null || activeEl === void 0 ? void 0 : activeEl.scrollIntoView) === null || _a === void 0 ? void 0 : _a.call(activeEl, { block: 'nearest' });
|
|
107
109
|
}, [open, activeIndex, filteredOptions]);
|
|
110
|
+
const getFocusableElements = React.useCallback(() => {
|
|
111
|
+
const selector = [
|
|
112
|
+
'a[href]',
|
|
113
|
+
'button:not([disabled])',
|
|
114
|
+
'input:not([disabled])',
|
|
115
|
+
'select:not([disabled])',
|
|
116
|
+
'textarea:not([disabled])',
|
|
117
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
118
|
+
].join(',');
|
|
119
|
+
const seen = new Set();
|
|
120
|
+
const focusables = [];
|
|
121
|
+
for (const container of [rootRef.current, popoverContentRef.current]) {
|
|
122
|
+
if (!container)
|
|
123
|
+
continue;
|
|
124
|
+
const elements = container.matches(selector)
|
|
125
|
+
? [container]
|
|
126
|
+
: Array.from(container.querySelectorAll(selector));
|
|
127
|
+
for (const element of elements) {
|
|
128
|
+
if (seen.has(element) ||
|
|
129
|
+
element.getAttribute('aria-hidden') === 'true' ||
|
|
130
|
+
element.tabIndex < 0) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
seen.add(element);
|
|
134
|
+
focusables.push(element);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return focusables;
|
|
138
|
+
}, []);
|
|
139
|
+
const isFocusWithinTypeahead = React.useCallback((target) => {
|
|
140
|
+
var _a, _b;
|
|
141
|
+
if (!(target instanceof Node))
|
|
142
|
+
return false;
|
|
143
|
+
return Boolean(((_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) || ((_b = popoverContentRef.current) === null || _b === void 0 ? void 0 : _b.contains(target)));
|
|
144
|
+
}, []);
|
|
145
|
+
const handleTabKeyDown = React.useCallback((event) => {
|
|
146
|
+
var _a, _b, _c;
|
|
147
|
+
if (event.key !== 'Tab' || !open)
|
|
148
|
+
return;
|
|
149
|
+
const focusables = getFocusableElements();
|
|
150
|
+
if (focusables.length === 0)
|
|
151
|
+
return;
|
|
152
|
+
const eventTarget = event.target instanceof HTMLElement
|
|
153
|
+
? event.target
|
|
154
|
+
: document.activeElement;
|
|
155
|
+
const activeElement = eventTarget && focusables.includes(eventTarget)
|
|
156
|
+
? eventTarget
|
|
157
|
+
: ((_a = document.activeElement) !== null && _a !== void 0 ? _a : null);
|
|
158
|
+
const activeIndexInScope = activeElement ? focusables.indexOf(activeElement) : -1;
|
|
159
|
+
const boundaryIndex = event.shiftKey ? 0 : focusables.length - 1;
|
|
160
|
+
const boundaryElement = focusables[boundaryIndex];
|
|
161
|
+
if (mode === 'multi') {
|
|
162
|
+
if (activeIndexInScope === -1) {
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
(_b = focusables[0]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
event.preventDefault();
|
|
168
|
+
const nextIndex = event.shiftKey
|
|
169
|
+
? (activeIndexInScope - 1 + focusables.length) % focusables.length
|
|
170
|
+
: (activeIndexInScope + 1) % focusables.length;
|
|
171
|
+
(_c = focusables[nextIndex]) === null || _c === void 0 ? void 0 : _c.focus();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (activeIndexInScope !== -1 && activeElement === boundaryElement) {
|
|
175
|
+
setOpen(false);
|
|
176
|
+
setActiveIndex(-1);
|
|
177
|
+
}
|
|
178
|
+
}, [open, getFocusableElements, mode]);
|
|
108
179
|
const commitSelection = (option) => {
|
|
109
180
|
var _a, _b;
|
|
110
181
|
if (mode === 'multi') {
|
|
@@ -144,7 +215,9 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
144
215
|
onChange(null);
|
|
145
216
|
}
|
|
146
217
|
};
|
|
147
|
-
const handleBlur = () => {
|
|
218
|
+
const handleBlur = (nextFocusedTarget) => {
|
|
219
|
+
if (isFocusWithinTypeahead(nextFocusedTarget))
|
|
220
|
+
return;
|
|
148
221
|
if (mode === 'multi') {
|
|
149
222
|
if (interactingWithOptionsRef.current) {
|
|
150
223
|
interactingWithOptionsRef.current = false;
|
|
@@ -261,7 +334,7 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
261
334
|
return;
|
|
262
335
|
}
|
|
263
336
|
};
|
|
264
|
-
return (_jsxs("div", { style: {
|
|
337
|
+
return (_jsxs("div", { ref: rootRef, style: {
|
|
265
338
|
display: 'flex',
|
|
266
339
|
flexDirection: 'column',
|
|
267
340
|
gap: mode === 'multi' &&
|
|
@@ -284,9 +357,9 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
284
357
|
else {
|
|
285
358
|
setActiveIndex(-1);
|
|
286
359
|
}
|
|
287
|
-
}, fullWidth: fullWidth, autoFocusContent: false, returnFocus: false, trigger: openPopover => {
|
|
360
|
+
}, fullWidth: fullWidth, autoFocusContent: false, returnFocus: false, overlayRef: popoverContentRef, trigger: (openPopover, icon) => {
|
|
288
361
|
var _a, _b, _c, _d, _e;
|
|
289
|
-
return (_jsx(Input, { ...passthroughInputProps, ref: inputRef, value: inputValue, startAdornment: multiSelectionAdornment || inputPropsStartAdornment ? (_jsxs(_Fragment, { children: [multiSelectionAdornment, inputPropsStartAdornment] })) : undefined, onFocus: e => {
|
|
362
|
+
return (_jsx(Input, { ...passthroughInputProps, ref: inputRef, value: inputValue, startAdornment: multiSelectionAdornment || inputPropsStartAdornment ? (_jsxs(_Fragment, { children: [multiSelectionAdornment, inputPropsStartAdornment] })) : undefined, endAdornment: inputPropsEndAdornment || icon ? (_jsxs(_Fragment, { children: [inputPropsEndAdornment, icon] })) : undefined, onFocus: e => {
|
|
290
363
|
inputPropsOnFocus === null || inputPropsOnFocus === void 0 ? void 0 : inputPropsOnFocus(e);
|
|
291
364
|
if (e.defaultPrevented)
|
|
292
365
|
return;
|
|
@@ -325,9 +398,12 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
325
398
|
inputPropsOnBlur === null || inputPropsOnBlur === void 0 ? void 0 : inputPropsOnBlur(e);
|
|
326
399
|
if (e.defaultPrevented)
|
|
327
400
|
return;
|
|
328
|
-
handleBlur();
|
|
401
|
+
handleBlur(e.relatedTarget);
|
|
329
402
|
}, onKeyDown: e => {
|
|
330
403
|
inputPropsOnKeyDown === null || inputPropsOnKeyDown === void 0 ? void 0 : inputPropsOnKeyDown(e);
|
|
404
|
+
if (e.defaultPrevented)
|
|
405
|
+
return;
|
|
406
|
+
handleTabKeyDown(e);
|
|
331
407
|
if (e.defaultPrevented)
|
|
332
408
|
return;
|
|
333
409
|
handleKeyDown(e);
|
|
@@ -363,11 +439,12 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
363
439
|
interactingWithOptionsRef.current = true;
|
|
364
440
|
e.preventDefault();
|
|
365
441
|
},
|
|
442
|
+
onKeyDown: e => handleTabKeyDown(e),
|
|
366
443
|
}, label: _jsx("span", { children: option.label }), onCheckedChange: () => commitSelection(option) }, option.value)) : (_jsx(Menu.Item, { active: isActive, selected: isSelected, children: _jsx("button", { ref: node => {
|
|
367
444
|
optionRefs.current[index] = node;
|
|
368
445
|
}, id: optionId, type: "button", role: "option", "aria-selected": isSelected, onMouseEnter: () => setActiveIndex(index), onMouseDown: e => {
|
|
369
446
|
e.preventDefault();
|
|
370
|
-
}, onClick: () => commitSelection(option), children: _jsx("span", { children: option.label }) }) }, option.value));
|
|
447
|
+
}, onKeyDown: e => handleTabKeyDown(e), onClick: () => commitSelection(option), children: _jsx("span", { children: option.label }) }) }, option.value));
|
|
371
448
|
})) : (_jsx(Menu.Item, { disabled: true, children: emptyMessage })) }) }), mode === 'multi' &&
|
|
372
449
|
multiSelectedValuesDisplayMode === 'below-input' &&
|
|
373
450
|
selectedOptions.length > 0 && (_jsx("div", { style: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ChevronDown, ChevronUp } from 'lucide-react';
|
|
4
|
+
import * as React from 'react';
|
|
4
5
|
import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useLayoutEffect, useRef, useState, } from 'react';
|
|
5
6
|
import { createPortal } from 'react-dom';
|
|
6
7
|
import styles from './Popover.module.css';
|
|
@@ -37,7 +38,7 @@ function parseMinWidthPx(minWidth, elForEm) {
|
|
|
37
38
|
}
|
|
38
39
|
return 0;
|
|
39
40
|
}
|
|
40
|
-
export const Popover = forwardRef(function Popover({ trigger: Trigger, children, open, defaultOpen = false, onOpenChange, contentId, minWidth = '200px', matchTriggerWidth = true, viewportPadding = 8, edgeBuffer = 100, dataCy, fullWidth = false, autoFocusContent = false, returnFocus = true, anchorRef, }, ref) {
|
|
41
|
+
export const Popover = forwardRef(function Popover({ trigger: Trigger, children, open, defaultOpen = false, onOpenChange, contentId, minWidth = '200px', matchTriggerWidth = true, viewportPadding = 8, edgeBuffer = 100, dataCy, fullWidth = false, autoFocusContent = false, returnFocus = true, anchorRef, overlayRef, }, ref) {
|
|
41
42
|
const internalId = useId();
|
|
42
43
|
const resolvedContentId = contentId !== null && contentId !== void 0 ? contentId : `popover-${internalId}`;
|
|
43
44
|
const isControlled = open !== undefined;
|
|
@@ -216,9 +217,23 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
216
217
|
(_b = (_a = triggerElRef.current) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
217
218
|
}, [isOpen, returnFocus]);
|
|
218
219
|
const icon = isOpen ? _jsx(ChevronUp, { size: 20 }) : _jsx(ChevronDown, { size: 20 });
|
|
220
|
+
const setOverlayRef = React.useCallback((node) => {
|
|
221
|
+
if (!overlayRef)
|
|
222
|
+
return;
|
|
223
|
+
if (typeof overlayRef === 'function') {
|
|
224
|
+
overlayRef(node);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const mutableRef = overlayRef;
|
|
228
|
+
mutableRef.current = node;
|
|
229
|
+
}, [overlayRef]);
|
|
219
230
|
return (_jsxs("div", { className: [styles.container, fullWidth ? styles.fullWidth : ''].filter(Boolean).join(' '), ref: containerRef, children: [Trigger(togglePopover, icon, isOpen), mounted &&
|
|
220
231
|
isOpen &&
|
|
221
|
-
createPortal(_jsx("div", { id: resolvedContentId, ref:
|
|
232
|
+
createPortal(_jsx("div", { id: resolvedContentId, ref: node => {
|
|
233
|
+
const mutableContentRef = contentRef;
|
|
234
|
+
mutableContentRef.current = node;
|
|
235
|
+
setOverlayRef(node);
|
|
236
|
+
}, className: styles.content, style: {
|
|
222
237
|
top: pos.top,
|
|
223
238
|
left: pos.left,
|
|
224
239
|
// Content-driven sizing by default.
|