@homecode/ui 5.11.0 → 5.13.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/dist/esm/src/components/FormattedText/FormattedText.js +17 -6
- package/dist/esm/src/components/Input/Input.js +73 -2
- package/dist/esm/src/components/NestedMenu/NestedMenu.js +41 -42
- package/dist/esm/src/components/NestedMenu/NestedMenu.styl.js +2 -2
- package/dist/esm/src/components/Popup/Popup.helpers.js +1 -5
- package/dist/esm/src/components/Popup/Popup.js +114 -62
- package/dist/esm/src/components/Popup/Popup.styl.js +1 -1
- package/dist/esm/src/components/PromptComposer/PromptComposer.styl.js +2 -2
- package/dist/esm/src/components/Select/Select2.js +1 -1
- package/dist/esm/src/components/TextShimmer/TextShimmer.js +5 -6
- package/dist/esm/src/components/TextShimmer/TextShimmer.styl.js +1 -1
- package/dist/esm/src/components/TextWithDeferTooltip/TextWithDeferTooltip.js +34 -3
- package/dist/esm/types/src/components/FormattedText/FormattedText.test.d.ts +1 -0
- package/dist/esm/types/src/components/Input/Input.d.ts +1 -0
- package/dist/esm/types/src/components/Input/Input.test.d.ts +1 -0
- package/dist/esm/types/src/components/Input/Input.types.d.ts +2 -0
- package/dist/esm/types/src/components/NestedMenu/NestedMenu.d.ts +1 -1
- package/dist/esm/types/src/components/NestedMenu/NestedMenu.types.d.ts +4 -0
- package/dist/esm/types/src/components/Popup/Popup.d.ts +13 -5
- package/dist/esm/types/src/components/Select/Select.d.ts +1 -0
- package/package.json +1 -1
|
@@ -80,7 +80,7 @@ function applyInjectors(text, injectors) {
|
|
|
80
80
|
}
|
|
81
81
|
function FormattedText({ text, className, onButtonClick, }) {
|
|
82
82
|
const injectLines = (content) => {
|
|
83
|
-
const matches = content.match(
|
|
83
|
+
const matches = content.match(/(^|\n)---[ \t]*(?:\n|$)/);
|
|
84
84
|
if (!matches)
|
|
85
85
|
return null;
|
|
86
86
|
return {
|
|
@@ -204,9 +204,17 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
204
204
|
length: matches[0].length,
|
|
205
205
|
};
|
|
206
206
|
};
|
|
207
|
-
const
|
|
208
|
-
|
|
207
|
+
const injectBreaks = (content) => {
|
|
208
|
+
const index = content.indexOf('\n');
|
|
209
|
+
if (index < 0)
|
|
209
210
|
return null;
|
|
211
|
+
return {
|
|
212
|
+
elem: jsx("br", {}),
|
|
213
|
+
index,
|
|
214
|
+
length: 1,
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
const injectButtons = (content) => {
|
|
210
218
|
const matches = content.match(/\[(.*?):(.*?)\|([^\]]+)\]/);
|
|
211
219
|
if (!matches)
|
|
212
220
|
return null;
|
|
@@ -216,7 +224,9 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
216
224
|
.split('|');
|
|
217
225
|
const [varName, value] = data.split(':');
|
|
218
226
|
return {
|
|
219
|
-
elem: (jsx(Button, { variant: "default", size: "s", round: true, onClick:
|
|
227
|
+
elem: (jsx(Button, { variant: "default", size: "s", round: true, onClick: onButtonClick
|
|
228
|
+
? () => onButtonClick({ text: label, [varName]: value })
|
|
229
|
+
: undefined, children: label })),
|
|
220
230
|
index: matches.index,
|
|
221
231
|
length: matches[0].length,
|
|
222
232
|
};
|
|
@@ -260,10 +270,10 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
260
270
|
};
|
|
261
271
|
};
|
|
262
272
|
const injectTables = (content) => {
|
|
263
|
-
const withSep = content.match(/(\n|^)(\|[^\n]
|
|
273
|
+
const withSep = content.match(/(\n|^)(\|[^\n]+\|[ \t]*\n)(\|[\t :-]+(?:\|[\t :-]+)*\|[ \t]*\n)((?:\|[^\n]+\|[ \t]*\n?)+)/);
|
|
264
274
|
const withoutSep = withSep
|
|
265
275
|
? null
|
|
266
|
-
: content.match(/(\n|^)(\|[^\n]
|
|
276
|
+
: content.match(/(\n|^)(\|[^\n]+\|[ \t]*\n)((?:\|[^\n]+\|[ \t]*\n?)+)/);
|
|
267
277
|
const matches = withSep || withoutSep;
|
|
268
278
|
if (!matches)
|
|
269
279
|
return null;
|
|
@@ -317,6 +327,7 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
317
327
|
injectBullet,
|
|
318
328
|
injectNumbered,
|
|
319
329
|
injectButtons,
|
|
330
|
+
injectBreaks,
|
|
320
331
|
]) }));
|
|
321
332
|
}
|
|
322
333
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { forwardRef, useRef, useState, useMemo, useEffect, createElement } from 'react';
|
|
2
|
+
import { forwardRef, useRef, useState, useMemo, useEffect, useLayoutEffect, createElement } from 'react';
|
|
3
3
|
import cn from 'classnames';
|
|
4
4
|
import { Label } from '../Label/Label.js';
|
|
5
5
|
import { RequiredStar } from '../RequiredStar/RequiredStar.js';
|
|
@@ -16,6 +16,38 @@ const TEXTAREA_SCROLL_TOP_OFFSET = {
|
|
|
16
16
|
m: 40,
|
|
17
17
|
l: 50,
|
|
18
18
|
};
|
|
19
|
+
function isNativeTextField(el) {
|
|
20
|
+
return el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement;
|
|
21
|
+
}
|
|
22
|
+
function resolveNativeTextField(el) {
|
|
23
|
+
if (isNativeTextField(el))
|
|
24
|
+
return el;
|
|
25
|
+
if (el instanceof Element) {
|
|
26
|
+
const nested = el.querySelector('input, textarea');
|
|
27
|
+
if (isNativeTextField(nested))
|
|
28
|
+
return nested;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function selectContentEditable(el) {
|
|
33
|
+
const selection = window.getSelection();
|
|
34
|
+
if (!selection)
|
|
35
|
+
return;
|
|
36
|
+
const range = document.createRange();
|
|
37
|
+
range.selectNodeContents(el);
|
|
38
|
+
selection.removeAllRanges();
|
|
39
|
+
selection.addRange(range);
|
|
40
|
+
}
|
|
41
|
+
function selectAllOnElement(el) {
|
|
42
|
+
const field = resolveNativeTextField(el);
|
|
43
|
+
if (field && typeof field.select === 'function') {
|
|
44
|
+
field.select();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (el instanceof HTMLElement && el.isContentEditable) {
|
|
48
|
+
selectContentEditable(el);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
19
51
|
const Input = forwardRef((props, ref) => {
|
|
20
52
|
const inputRef = useRef(null);
|
|
21
53
|
const setRef = (element) => {
|
|
@@ -27,7 +59,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
27
59
|
ref.current = element;
|
|
28
60
|
}
|
|
29
61
|
};
|
|
30
|
-
const { type = 'text', size = 'm', variant = 'default', value, defaultValue = '', onChange, onFocus, onBlur, onClear, onInput, changeOnEnd, checkAutofill, hasClear, required, hideRequiredStar, disabled, error, label, placeholder, addonLeft, addonRight, clearPaddingLeft, clearPaddingRight, forceLabelOnTop, scrollProps, step = 1, round, autoFocus, className, fitContentWidth, } = props;
|
|
62
|
+
const { type = 'text', size = 'm', variant = 'default', value, defaultValue = '', onChange, onFocus, onBlur, onClear, onInput, changeOnEnd, checkAutofill, hasClear, required, hideRequiredStar, disabled, error, label, placeholder, addonLeft, addonRight, clearPaddingLeft, clearPaddingRight, forceLabelOnTop, scrollProps, step = 1, round, autoFocus, className, fitContentWidth, selectAllOnFocus, } = props;
|
|
31
63
|
const updateAutoComplete = () => {
|
|
32
64
|
const form = inputRef.current?.closest('form');
|
|
33
65
|
const val = form?.getAttribute('autocomplete');
|
|
@@ -39,6 +71,8 @@ const Input = forwardRef((props, ref) => {
|
|
|
39
71
|
const elem = inputRef.current;
|
|
40
72
|
if (!isFocused || !elem || type !== 'text')
|
|
41
73
|
return;
|
|
74
|
+
if (elem.selectionStart !== elem.selectionEnd)
|
|
75
|
+
return;
|
|
42
76
|
elem.selectionStart = cursorPos.current;
|
|
43
77
|
elem.selectionEnd = cursorPos.current;
|
|
44
78
|
};
|
|
@@ -57,6 +91,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
57
91
|
const hasValue = isNumber || Boolean(value || inputValue || defaultValue);
|
|
58
92
|
const isLabelOnTop = forceLabelOnTop || Boolean(addonLeft) || hasValue || isFocused;
|
|
59
93
|
const cursorPos = useRef(0);
|
|
94
|
+
const selectAllOnFocusPending = useRef(false);
|
|
60
95
|
const getValue = (val = inputValue) => {
|
|
61
96
|
if (type === 'number') {
|
|
62
97
|
if (val)
|
|
@@ -136,6 +171,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
136
171
|
onChangeValue(val, e);
|
|
137
172
|
};
|
|
138
173
|
const onChangeValue = (value, e) => {
|
|
174
|
+
selectAllOnFocusPending.current = false;
|
|
139
175
|
if (!isNumber && inputRef.current) {
|
|
140
176
|
cursorPos.current = inputRef.current.selectionStart;
|
|
141
177
|
}
|
|
@@ -159,8 +195,23 @@ const Input = forwardRef((props, ref) => {
|
|
|
159
195
|
const handleFocus = e => {
|
|
160
196
|
setIsFocused(true);
|
|
161
197
|
onFocus?.(e);
|
|
198
|
+
if (!selectAllOnFocus)
|
|
199
|
+
return;
|
|
200
|
+
selectAllOnFocusPending.current = true;
|
|
201
|
+
selectAllOnElement(inputRef.current ?? e.target);
|
|
202
|
+
};
|
|
203
|
+
const handleMouseDown = e => {
|
|
204
|
+
props.controlProps?.onMouseDown?.(e);
|
|
205
|
+
if (!selectAllOnFocus || isFocusedRef.current)
|
|
206
|
+
return;
|
|
207
|
+
e.preventDefault();
|
|
208
|
+
const el = e.currentTarget;
|
|
209
|
+
if (el instanceof HTMLElement)
|
|
210
|
+
el.focus();
|
|
211
|
+
selectAllOnElement(el);
|
|
162
212
|
};
|
|
163
213
|
const handleBlur = e => {
|
|
214
|
+
selectAllOnFocusPending.current = false;
|
|
164
215
|
if (changeOnEnd)
|
|
165
216
|
onTypingEnd();
|
|
166
217
|
const val = getValue(e?.target?.value);
|
|
@@ -181,6 +232,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
181
232
|
onChange: handleChange,
|
|
182
233
|
onFocus: handleFocus,
|
|
183
234
|
onBlur: handleBlur,
|
|
235
|
+
...(selectAllOnFocus ? { onMouseDown: handleMouseDown } : null),
|
|
184
236
|
};
|
|
185
237
|
if (isTextArea) {
|
|
186
238
|
controlProps.contentEditable = true;
|
|
@@ -208,8 +260,10 @@ const Input = forwardRef((props, ref) => {
|
|
|
208
260
|
disabled,
|
|
209
261
|
props.controlProps,
|
|
210
262
|
handleChange,
|
|
263
|
+
handleMouseDown,
|
|
211
264
|
onFocus,
|
|
212
265
|
onBlur,
|
|
266
|
+
selectAllOnFocus,
|
|
213
267
|
isTextArea,
|
|
214
268
|
onTextAreaInput,
|
|
215
269
|
placeholder,
|
|
@@ -271,6 +325,23 @@ const Input = forwardRef((props, ref) => {
|
|
|
271
325
|
if (isTextArea)
|
|
272
326
|
setTextareaValue(String(value ?? ''));
|
|
273
327
|
}, []);
|
|
328
|
+
useLayoutEffect(() => {
|
|
329
|
+
if (!selectAllOnFocus || !selectAllOnFocusPending.current)
|
|
330
|
+
return;
|
|
331
|
+
if (!isFocused)
|
|
332
|
+
return;
|
|
333
|
+
const field = resolveNativeTextField(inputRef.current);
|
|
334
|
+
if (field) {
|
|
335
|
+
if (!field.value || typeof field.select !== 'function')
|
|
336
|
+
return;
|
|
337
|
+
field.select();
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const node = inputRef.current;
|
|
341
|
+
if (node instanceof HTMLElement && node.isContentEditable && node.innerText) {
|
|
342
|
+
selectContentEditable(node);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
274
345
|
const Control = isTextArea ? 'span' : 'input';
|
|
275
346
|
const classes = cn(S.root, isTextArea && S.isTextArea, S[`size-${size}`], S[`variant-${variant}`], isFocused && S.isFocused, error && S.hasError, hasClear && S.hasClear, disabled && S.isDisabled, round && S.round, fitContentWidth && !isTextArea && S.fitContentWidth, className);
|
|
276
347
|
return (jsxs("div", { className: classes, children: [jsxs("label", { className: cn(S.main, clearPaddingLeft && S.clearPaddingLeft, clearPaddingRight && S.clearPaddingRight), children: [jsx("div", { className: S.border, suppressHydrationWarning: true, style: { clipPath: labelClipPath } }, "border"), renderAddon('left'), wrapControl(jsxs(Fragment, { children: [createElement(Control, { ...controlProps, className: cn(S.control, controlProps?.className), ref: setRef, key: "control" }), isTextArea &&
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
-
import {
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
4
|
import { Icon } from '../Icon/Icon.js';
|
|
5
|
+
import { Popup } from '../Popup/Popup.js';
|
|
5
6
|
import S from './NestedMenu.styl.js';
|
|
6
7
|
|
|
7
8
|
const MOBILE_MQ = '(max-width: 720px)';
|
|
8
9
|
const HOVER_MQ = '(hover: hover) and (pointer: fine)';
|
|
10
|
+
const ICON_SIZE = { xs: 'xs', s: 'xs', m: 'xs', l: 's', xl: 'm' };
|
|
9
11
|
function useMedia(query) {
|
|
10
12
|
const [matches, setMatches] = useState(() => typeof window !== 'undefined' && window.matchMedia(query).matches);
|
|
11
13
|
useEffect(() => {
|
|
@@ -27,14 +29,13 @@ function NestedMenuItemRow({ children, className, danger, disabled, href, target
|
|
|
27
29
|
}
|
|
28
30
|
return (jsx("button", { type: "button", className: classes, disabled: disabled, onClick: onClick, children: children }));
|
|
29
31
|
}
|
|
30
|
-
function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end', className, }) {
|
|
31
|
-
const rootRef = useRef(null);
|
|
32
|
+
function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end', size = 'm', className, popupProps, }) {
|
|
32
33
|
const [activeId, setActiveId] = useState(null);
|
|
33
|
-
const [flipLeft, setFlipLeft] = useState(false);
|
|
34
|
-
const hoverTimer = useRef(0);
|
|
35
34
|
const stacked = useMedia(MOBILE_MQ);
|
|
36
35
|
const canHover = useMedia(HOVER_MQ);
|
|
37
36
|
const active = items.find(item => item.id === activeId);
|
|
37
|
+
const iconSize = ICON_SIZE[size];
|
|
38
|
+
const contentClass = cn(S.content, S[`size-${size}`]);
|
|
38
39
|
function close() {
|
|
39
40
|
onOpenChange(false);
|
|
40
41
|
setActiveId(null);
|
|
@@ -54,40 +55,9 @@ function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end'
|
|
|
54
55
|
if (e.key === 'Escape')
|
|
55
56
|
close();
|
|
56
57
|
};
|
|
57
|
-
const onPointer = (e) => {
|
|
58
|
-
if (!rootRef.current?.contains(e.target))
|
|
59
|
-
close();
|
|
60
|
-
};
|
|
61
58
|
document.addEventListener('keydown', onKey);
|
|
62
|
-
document.
|
|
63
|
-
return () => {
|
|
64
|
-
document.removeEventListener('keydown', onKey);
|
|
65
|
-
document.removeEventListener('pointerdown', onPointer);
|
|
66
|
-
};
|
|
59
|
+
return () => document.removeEventListener('keydown', onKey);
|
|
67
60
|
}, [open]);
|
|
68
|
-
useLayoutEffect(() => {
|
|
69
|
-
if (!open || !rootRef.current)
|
|
70
|
-
return;
|
|
71
|
-
const rect = rootRef.current.getBoundingClientRect();
|
|
72
|
-
setFlipLeft(window.innerWidth - rect.right < 280);
|
|
73
|
-
}, [open, activeId]);
|
|
74
|
-
useEffect(() => () => window.clearTimeout(hoverTimer.current), []);
|
|
75
|
-
function onItemEnter(id) {
|
|
76
|
-
if (!canHover || stacked)
|
|
77
|
-
return;
|
|
78
|
-
window.clearTimeout(hoverTimer.current);
|
|
79
|
-
const item = items.find(entry => entry.id === id);
|
|
80
|
-
if (item?.disabled || !item?.submenu) {
|
|
81
|
-
setActiveId(null);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
openSub(id, false);
|
|
85
|
-
}
|
|
86
|
-
function onItemLeave() {
|
|
87
|
-
if (!canHover || stacked)
|
|
88
|
-
return;
|
|
89
|
-
hoverTimer.current = window.setTimeout(() => setActiveId(null), 160);
|
|
90
|
-
}
|
|
91
61
|
function onItemClick(id) {
|
|
92
62
|
const item = items.find(entry => entry.id === id);
|
|
93
63
|
if (!item || item.disabled)
|
|
@@ -97,18 +67,47 @@ function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end'
|
|
|
97
67
|
close();
|
|
98
68
|
return;
|
|
99
69
|
}
|
|
100
|
-
if (
|
|
70
|
+
if (!item.submenu)
|
|
71
|
+
return;
|
|
72
|
+
if (activeId === id && !stacked && !canHover) {
|
|
101
73
|
setActiveId(null);
|
|
102
74
|
return;
|
|
103
75
|
}
|
|
104
76
|
openSub(id, true);
|
|
105
77
|
}
|
|
78
|
+
function renderItemButton(item) {
|
|
79
|
+
return (jsxs("button", { type: "button", className: cn(S.item, activeId === item.id && S.itemActive, item.danger && S.itemDanger, item.disabled && S.itemDisabled, item.wrap && S.multiline, item.className), role: "menuitem", disabled: item.disabled, "aria-haspopup": item.submenu ? 'menu' : undefined, "aria-expanded": item.submenu ? activeId === item.id : undefined, onClick: () => onItemClick(item.id), children: [item.icon && (jsx("span", { className: S.icon, "aria-hidden": true, children: item.icon })), jsx("span", { className: S.label, children: item.label }), item.hint != null && item.hint !== '' && (jsx("span", { className: S.hint, children: item.hint })), item.submenu && (jsx(Icon, { className: S.chevron, type: "chevronRight", size: iconSize }))] }));
|
|
80
|
+
}
|
|
106
81
|
function renderItems() {
|
|
107
|
-
return items.map(item =>
|
|
108
|
-
|
|
109
|
-
|
|
82
|
+
return items.map(item => {
|
|
83
|
+
if (item.submenu && !stacked) {
|
|
84
|
+
return (jsx(Popup, { ...popupProps, className: cn(S.itemPopup, popupProps?.className), size: size, hoverControl: canHover, isOpen: activeId === item.id, onOpen: () => openSub(item.id, true), onClose: () => {
|
|
85
|
+
setActiveId(current => (current === item.id ? null : current));
|
|
86
|
+
}, direction: align === 'end' ? 'left-top' : 'right-top', trigger: renderItemButton(item), triggerProps: {
|
|
87
|
+
...popupProps?.triggerProps,
|
|
88
|
+
className: cn(S.itemTrigger, popupProps?.triggerProps?.className),
|
|
89
|
+
}, contentProps: {
|
|
90
|
+
...popupProps?.contentProps,
|
|
91
|
+
className: cn(contentClass, popupProps?.contentProps?.className),
|
|
92
|
+
}, content: jsx("div", { className: S.list, role: "menu", children: item.submenu }) }, item.id));
|
|
93
|
+
}
|
|
94
|
+
return (jsx("div", { className: S.itemWrap, onPointerEnter: () => {
|
|
95
|
+
if (canHover && !stacked)
|
|
96
|
+
setActiveId(null);
|
|
97
|
+
}, children: renderItemButton(item) }, item.id));
|
|
98
|
+
});
|
|
110
99
|
}
|
|
111
|
-
return (
|
|
100
|
+
return (jsx(Popup, { ...popupProps, className: cn(S.root, className, popupProps?.className), size: size, isOpen: open, onOpen: () => onOpenChange(true), onClose: () => {
|
|
101
|
+
onOpenChange(false);
|
|
102
|
+
setActiveId(null);
|
|
103
|
+
}, direction: align === 'end' ? 'bottom-left' : 'bottom-right', trigger: trigger, triggerProps: {
|
|
104
|
+
...popupProps?.triggerProps,
|
|
105
|
+
className: cn(S.trigger, popupProps?.triggerProps?.className),
|
|
106
|
+
onClick: () => onOpenChange(!open),
|
|
107
|
+
}, contentProps: {
|
|
108
|
+
...popupProps?.contentProps,
|
|
109
|
+
className: cn(contentClass, popupProps?.contentProps?.className),
|
|
110
|
+
}, content: jsx("div", { className: S.list, role: "menu", children: stacked && active ? (jsxs("div", { className: S.stacked, children: [jsxs("button", { type: "button", className: S.back, onClick: () => setActiveId(null), children: [jsx(Icon, { type: "chevronLeft", size: iconSize }), jsx("span", { className: S.label, children: active.label })] }), jsx("div", { className: S.stackedBody, children: active.submenu })] })) : (renderItems()) }) }));
|
|
112
111
|
}
|
|
113
112
|
const NestedMenu = Object.assign(NestedMenuComponent, {
|
|
114
113
|
Item: NestedMenuItemRow,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".NestedMenu_root__ybyGA{display:inline-flex
|
|
4
|
-
var S = {"root":"NestedMenu_root__ybyGA","trigger":"NestedMenu_trigger__zBeNI","
|
|
3
|
+
var css_248z = ".NestedMenu_root__ybyGA,.NestedMenu_trigger__zBeNI{display:inline-flex}.NestedMenu_content__OyLXN{box-sizing:border-box;max-width:280px;min-width:200px;padding:4px}.NestedMenu_list__Q55Aa{display:flex;flex-direction:column;gap:1px}.NestedMenu_itemPopup__kMaxU{display:block;width:100%}.NestedMenu_itemTrigger__a7XHw{cursor:inherit;display:block;width:100%}.NestedMenu_itemWrap__Qmc0B{position:relative}.NestedMenu_back__dNsDV,.NestedMenu_item__tgbZm,.NestedMenu_row__48g5c{align-items:center;background:none;border:none;border-radius:6px;color:inherit;cursor:pointer;display:flex;font:inherit;font-weight:500;gap:8px;letter-spacing:.01em;line-height:1.3;text-align:left;text-decoration:none;width:100%}.NestedMenu_back__dNsDV:hover,.NestedMenu_item__tgbZm:hover,.NestedMenu_row__48g5c:hover{background:var(--accent-color-alpha-50)}.NestedMenu_back__dNsDV.NestedMenu_itemActive__RfPZH,.NestedMenu_item__tgbZm.NestedMenu_itemActive__RfPZH,.NestedMenu_row__48g5c.NestedMenu_itemActive__RfPZH{background:var(--accent-color-alpha-100)}.NestedMenu_back__dNsDV.NestedMenu_itemDisabled__evVk1,.NestedMenu_back__dNsDV:disabled,.NestedMenu_item__tgbZm.NestedMenu_itemDisabled__evVk1,.NestedMenu_item__tgbZm:disabled,.NestedMenu_row__48g5c.NestedMenu_itemDisabled__evVk1,.NestedMenu_row__48g5c:disabled{cursor:default;opacity:.55;pointer-events:none}.NestedMenu_itemDanger__oAJbP{color:var(--active-color)}.NestedMenu_itemDanger__oAJbP .NestedMenu_icon__4g2Yp{color:inherit;opacity:1}.NestedMenu_icon__4g2Yp{display:inline-flex;flex-shrink:0;opacity:.55}.NestedMenu_icon__4g2Yp svg{display:block}.NestedMenu_label__Jnm6l{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.NestedMenu_hint__hotNP{flex-shrink:0;font-weight:400;opacity:.5}.NestedMenu_multiline__MDdk-{grid-row-gap:2px;align-items:start;display:grid;grid-template-columns:auto minmax(0,1fr);min-width:252px;row-gap:2px}.NestedMenu_multiline__MDdk- .NestedMenu_label__Jnm6l{overflow:visible;text-overflow:clip}.NestedMenu_multiline__MDdk- .NestedMenu_hint__hotNP{grid-column:2;min-width:0;white-space:normal}.NestedMenu_chevron__8i-Po{flex-shrink:0;opacity:.45}.NestedMenu_row__48g5c svg{color:var(--active-color);flex-shrink:0}.NestedMenu_stacked__rMiOi{display:flex;flex-direction:column;max-height:min(360px,calc(100vh - 24px));overflow-y:auto}.NestedMenu_back__dNsDV{font-weight:650;margin-bottom:2px}.NestedMenu_stackedBody__Fbkma{min-width:0}.NestedMenu_size-s__2n2te .NestedMenu_back__dNsDV,.NestedMenu_size-s__2n2te .NestedMenu_item__tgbZm,.NestedMenu_size-s__2n2te .NestedMenu_row__48g5c,.NestedMenu_size-xs__yUJ0q .NestedMenu_back__dNsDV,.NestedMenu_size-xs__yUJ0q .NestedMenu_item__tgbZm,.NestedMenu_size-xs__yUJ0q .NestedMenu_row__48g5c{font-size:12px;gap:6px;padding:4px 8px}.NestedMenu_size-s__2n2te.NestedMenu_content__OyLXN,.NestedMenu_size-xs__yUJ0q.NestedMenu_content__OyLXN{min-width:176px;padding:3px}.NestedMenu_size-s__2n2te .NestedMenu_back__dNsDV svg,.NestedMenu_size-s__2n2te .NestedMenu_chevron__8i-Po,.NestedMenu_size-s__2n2te .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-s__2n2te .NestedMenu_row__48g5c svg,.NestedMenu_size-xs__yUJ0q .NestedMenu_back__dNsDV svg,.NestedMenu_size-xs__yUJ0q .NestedMenu_chevron__8i-Po,.NestedMenu_size-xs__yUJ0q .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-xs__yUJ0q .NestedMenu_row__48g5c svg{height:10px;width:10px}.NestedMenu_size-m__B8zm5 .NestedMenu_back__dNsDV,.NestedMenu_size-m__B8zm5 .NestedMenu_item__tgbZm,.NestedMenu_size-m__B8zm5 .NestedMenu_row__48g5c{font-size:13px;padding:6px 10px}.NestedMenu_size-l__1FrvQ .NestedMenu_back__dNsDV,.NestedMenu_size-l__1FrvQ .NestedMenu_item__tgbZm,.NestedMenu_size-l__1FrvQ .NestedMenu_row__48g5c{font-size:16px;gap:10px;padding:10px 14px}.NestedMenu_size-l__1FrvQ.NestedMenu_content__OyLXN{max-width:320px;min-width:240px;padding:6px}.NestedMenu_size-l__1FrvQ .NestedMenu_back__dNsDV svg,.NestedMenu_size-l__1FrvQ .NestedMenu_chevron__8i-Po,.NestedMenu_size-l__1FrvQ .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-l__1FrvQ .NestedMenu_row__48g5c svg{height:18px;width:18px}.NestedMenu_size-xl__jiXmT .NestedMenu_back__dNsDV,.NestedMenu_size-xl__jiXmT .NestedMenu_item__tgbZm,.NestedMenu_size-xl__jiXmT .NestedMenu_row__48g5c{font-size:18px;gap:12px;padding:12px 16px}.NestedMenu_size-xl__jiXmT.NestedMenu_content__OyLXN{max-width:360px;min-width:260px;padding:8px}.NestedMenu_size-xl__jiXmT .NestedMenu_back__dNsDV svg,.NestedMenu_size-xl__jiXmT .NestedMenu_chevron__8i-Po,.NestedMenu_size-xl__jiXmT .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-xl__jiXmT .NestedMenu_row__48g5c svg{height:22px;width:22px}";
|
|
4
|
+
var S = {"root":"NestedMenu_root__ybyGA","trigger":"NestedMenu_trigger__zBeNI","content":"NestedMenu_content__OyLXN","list":"NestedMenu_list__Q55Aa","itemPopup":"NestedMenu_itemPopup__kMaxU","itemTrigger":"NestedMenu_itemTrigger__a7XHw","itemWrap":"NestedMenu_itemWrap__Qmc0B","item":"NestedMenu_item__tgbZm","row":"NestedMenu_row__48g5c","back":"NestedMenu_back__dNsDV","itemActive":"NestedMenu_itemActive__RfPZH","itemDisabled":"NestedMenu_itemDisabled__evVk1","itemDanger":"NestedMenu_itemDanger__oAJbP","icon":"NestedMenu_icon__4g2Yp","label":"NestedMenu_label__Jnm6l","hint":"NestedMenu_hint__hotNP","multiline":"NestedMenu_multiline__MDdk-","chevron":"NestedMenu_chevron__8i-Po","stacked":"NestedMenu_stacked__rMiOi","stackedBody":"NestedMenu_stackedBody__Fbkma","size-xs":"NestedMenu_size-xs__yUJ0q","size-s":"NestedMenu_size-s__2n2te","size-m":"NestedMenu_size-m__B8zm5","size-l":"NestedMenu_size-l__1FrvQ","size-xl":"NestedMenu_size-xl__jiXmT"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -118,10 +118,6 @@ const getPopupId = (elem, attr = 'data-popup-id') => {
|
|
|
118
118
|
const id = elem.getAttribute(attr);
|
|
119
119
|
return id ? parseInt(id, 10) : null;
|
|
120
120
|
};
|
|
121
|
-
function isLastChild(rootId, id) {
|
|
122
|
-
const ids = childs[rootId];
|
|
123
|
-
return ids && ids[ids.length - 1] === id;
|
|
124
|
-
}
|
|
125
121
|
function setChild(rootId, id) {
|
|
126
122
|
if (!childs[rootId])
|
|
127
123
|
childs[rootId] = [];
|
|
@@ -133,4 +129,4 @@ function unsetChild(rootId, id) {
|
|
|
133
129
|
delete childs[rootId];
|
|
134
130
|
}
|
|
135
131
|
|
|
136
|
-
export { ZERO_BOUNDARY_FIT, childs, constrainAxisShift, domRectToEdges, edgesWidth, fitRectToBoundary, getId, getPopupId, intersectEdges, isEditable,
|
|
132
|
+
export { ZERO_BOUNDARY_FIT, childs, constrainAxisShift, domRectToEdges, edgesWidth, fitRectToBoundary, getId, getPopupId, intersectEdges, isEditable, popupBoundaryEdges, popupBoundaryPadding, setChild, shiftMarginsIntoBounds, shrinkEdgesUniform, unsetChild, viewportClientRectEdges };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { ZERO_BOUNDARY_FIT, getId, getPopupId, popupBoundaryEdges, popupBoundaryPadding, edgesWidth, fitRectToBoundary,
|
|
2
|
+
import { ZERO_BOUNDARY_FIT, getId, getPopupId, popupBoundaryEdges, popupBoundaryPadding, edgesWidth, fitRectToBoundary, childs, isEditable, setChild, unsetChild } from './Popup.helpers.js';
|
|
3
3
|
import { observe, unobserve } from '../../tools/resizeObserver.js';
|
|
4
4
|
import { Component, createRef } from 'react';
|
|
5
5
|
import { Paranja } from '../Paranja/Paranja.js';
|
|
@@ -8,7 +8,6 @@ import { config } from '../../tools/config.js';
|
|
|
8
8
|
import S from './Popup.styl.js';
|
|
9
9
|
import Time from 'timen';
|
|
10
10
|
import cn from 'classnames';
|
|
11
|
-
import debounce from '../../tools/debounce.js';
|
|
12
11
|
import { getCoords } from '../../tools/dom.js';
|
|
13
12
|
import { isBrowser } from '../../tools/env.js';
|
|
14
13
|
import throttle from '../../tools/throttle.js';
|
|
@@ -16,6 +15,7 @@ import throttle from '../../tools/throttle.js';
|
|
|
16
15
|
const ANIMATION_DURATION = 100;
|
|
17
16
|
const OFFSET_GAP = 10;
|
|
18
17
|
const BOUNDARY_FIT_EPSILON = 1;
|
|
18
|
+
const HOVER_CLOSE_DELAY = 160;
|
|
19
19
|
class Popup extends Component {
|
|
20
20
|
rootElem = createRef();
|
|
21
21
|
triggerElem = createRef();
|
|
@@ -33,11 +33,12 @@ class Popup extends Component {
|
|
|
33
33
|
};
|
|
34
34
|
focused = false;
|
|
35
35
|
isOpening = false;
|
|
36
|
+
openedByHover = false;
|
|
36
37
|
pointerPressed = false;
|
|
37
|
-
subscribedHoverControl = false;
|
|
38
38
|
subscribedSizeChange = false;
|
|
39
39
|
pointerDownTarget = null;
|
|
40
40
|
isPointerPressedInside = false;
|
|
41
|
+
hoverCloseUnsub = null;
|
|
41
42
|
id;
|
|
42
43
|
parentPopupContent;
|
|
43
44
|
timers = Time.create();
|
|
@@ -63,7 +64,7 @@ class Popup extends Component {
|
|
|
63
64
|
this.id = getId();
|
|
64
65
|
}
|
|
65
66
|
componentDidMount() {
|
|
66
|
-
const {
|
|
67
|
+
const { focusControl } = this.props;
|
|
67
68
|
const vv = isBrowser ? window.visualViewport : null;
|
|
68
69
|
if (vv) {
|
|
69
70
|
vv.addEventListener('resize', this.onBoundaryGeometryChange);
|
|
@@ -81,8 +82,6 @@ class Popup extends Component {
|
|
|
81
82
|
document.addEventListener('keydown', this.onDocKeyDown, true);
|
|
82
83
|
document.addEventListener('keyup', this.onDocKeyUp);
|
|
83
84
|
}
|
|
84
|
-
if (hoverControl)
|
|
85
|
-
this.subscribeHoverControl();
|
|
86
85
|
this.subscribeScroll();
|
|
87
86
|
if (this.state.isOpen &&
|
|
88
87
|
this.state.isContentVisible &&
|
|
@@ -95,15 +94,11 @@ class Popup extends Component {
|
|
|
95
94
|
this.scheduleComputeShift();
|
|
96
95
|
}, 100);
|
|
97
96
|
componentDidUpdate(prevProps, prevState) {
|
|
98
|
-
const { isOpen, disabled
|
|
97
|
+
const { isOpen, disabled } = this.props;
|
|
99
98
|
if (disabled !== prevProps.disabled) {
|
|
100
99
|
this.setState({ isOpen: false }); // close when receive disabled=true
|
|
101
100
|
return;
|
|
102
101
|
}
|
|
103
|
-
if (!prevProps.hoverControl && hoverControl)
|
|
104
|
-
this.subscribeHoverControl();
|
|
105
|
-
if (prevProps.hoverControl && !hoverControl)
|
|
106
|
-
this.unsubscribeHoverControl();
|
|
107
102
|
if (typeof isOpen === 'boolean' && isOpen !== prevProps.isOpen) {
|
|
108
103
|
isOpen ? this.open() : this.close();
|
|
109
104
|
}
|
|
@@ -138,7 +133,7 @@ class Popup extends Component {
|
|
|
138
133
|
if (this.scrollParent) {
|
|
139
134
|
this.scrollParent.removeEventListener('scroll', this.close);
|
|
140
135
|
}
|
|
141
|
-
this.
|
|
136
|
+
this.cancelHoverClose();
|
|
142
137
|
this.unsubscribeSizeChange();
|
|
143
138
|
this.unsubscribeScroll();
|
|
144
139
|
}
|
|
@@ -162,20 +157,6 @@ class Popup extends Component {
|
|
|
162
157
|
unobserve(this.triggerElem.current);
|
|
163
158
|
unobserve(this.containerElem);
|
|
164
159
|
}
|
|
165
|
-
subscribeHoverControl() {
|
|
166
|
-
if (this.subscribedHoverControl)
|
|
167
|
-
return;
|
|
168
|
-
this.subscribedHoverControl = true;
|
|
169
|
-
document.addEventListener('pointermove', this.checkHover);
|
|
170
|
-
document.addEventListener('pointerup', this.checkHover);
|
|
171
|
-
}
|
|
172
|
-
unsubscribeHoverControl() {
|
|
173
|
-
if (!this.subscribedHoverControl)
|
|
174
|
-
return;
|
|
175
|
-
this.subscribedHoverControl = false;
|
|
176
|
-
document.removeEventListener('pointermove', this.checkHover);
|
|
177
|
-
document.removeEventListener('pointerup', this.checkHover);
|
|
178
|
-
}
|
|
179
160
|
updateBounds() {
|
|
180
161
|
if (!this.containerElem)
|
|
181
162
|
return;
|
|
@@ -268,33 +249,6 @@ class Popup extends Component {
|
|
|
268
249
|
this.setState({ boundaryFit });
|
|
269
250
|
}
|
|
270
251
|
}
|
|
271
|
-
checkHover = debounce((e) => {
|
|
272
|
-
if (this.isPointerPressedInside)
|
|
273
|
-
return;
|
|
274
|
-
const { isOpen, rootPopupId } = this.state;
|
|
275
|
-
const overTrigger = this.isPointerOver(e.target, S.trigger);
|
|
276
|
-
const overContent = this.isPointerOver(e.target, S.content);
|
|
277
|
-
if (!isOpen) {
|
|
278
|
-
if (overTrigger)
|
|
279
|
-
this.open();
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
// isOpen
|
|
283
|
-
if (overTrigger || overContent)
|
|
284
|
-
return;
|
|
285
|
-
if (typeof rootPopupId === 'number') {
|
|
286
|
-
if (isLastChild(rootPopupId, this.id)) {
|
|
287
|
-
this.close();
|
|
288
|
-
unsetChild(rootPopupId, this.id);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
const isOverAnyPopupContent = e.target.closest(`.${S.content}`);
|
|
293
|
-
if (!isOverAnyPopupContent || !childs[this.id]?.length) {
|
|
294
|
-
this.close();
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}, 100);
|
|
298
252
|
isControllable = () => typeof this.props.isOpen === 'boolean';
|
|
299
253
|
isLastClickInside = () => this.pointerDownTarget &&
|
|
300
254
|
(this.pointerDownTarget.closest(`.${S.trigger}`) ||
|
|
@@ -305,12 +259,81 @@ class Popup extends Component {
|
|
|
305
259
|
this.timers.after(100, () => (this.pointerDownTarget = null));
|
|
306
260
|
};
|
|
307
261
|
onDocPointerUp = (e) => {
|
|
308
|
-
|
|
309
|
-
this.close();
|
|
262
|
+
const pressedInside = this.isPointerPressedInside;
|
|
310
263
|
this.isPointerPressedInside = false;
|
|
264
|
+
if (!this.state.isOpen || pressedInside)
|
|
265
|
+
return;
|
|
266
|
+
if (this.isHoverInside(e.target))
|
|
267
|
+
return;
|
|
268
|
+
this.close();
|
|
311
269
|
};
|
|
312
270
|
isPointerOver(target, elem) {
|
|
313
|
-
return target
|
|
271
|
+
return (target instanceof Element &&
|
|
272
|
+
target.closest(`.${elem}[data-popup-id="${this.id}"]`));
|
|
273
|
+
}
|
|
274
|
+
isHoverInside(target) {
|
|
275
|
+
return (this.isPointerOver(target, S.trigger) ||
|
|
276
|
+
this.isPointerOver(target, S.content));
|
|
277
|
+
}
|
|
278
|
+
isRelatedHover(target) {
|
|
279
|
+
if (!(target instanceof Element))
|
|
280
|
+
return false;
|
|
281
|
+
if (this.isHoverInside(target))
|
|
282
|
+
return true;
|
|
283
|
+
const popupEl = target.closest('[data-popup-id]');
|
|
284
|
+
if (!popupEl)
|
|
285
|
+
return false;
|
|
286
|
+
const id = getPopupId(popupEl);
|
|
287
|
+
if (id == null || id === this.id)
|
|
288
|
+
return false;
|
|
289
|
+
if (childs[this.id]?.includes(id))
|
|
290
|
+
return true;
|
|
291
|
+
const { rootPopupId } = this.state;
|
|
292
|
+
return rootPopupId != null && childs[rootPopupId]?.includes(id);
|
|
293
|
+
}
|
|
294
|
+
cancelHoverClose() {
|
|
295
|
+
this.hoverCloseUnsub?.();
|
|
296
|
+
this.hoverCloseUnsub = null;
|
|
297
|
+
}
|
|
298
|
+
scheduleHoverClose() {
|
|
299
|
+
this.cancelHoverClose();
|
|
300
|
+
this.hoverCloseUnsub = Time.after(HOVER_CLOSE_DELAY, () => {
|
|
301
|
+
this.hoverCloseUnsub = null;
|
|
302
|
+
this.close();
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
onHoverEnter = () => {
|
|
306
|
+
if (!this.props.hoverControl)
|
|
307
|
+
return;
|
|
308
|
+
this.cancelHoverClose();
|
|
309
|
+
if (!this.state.isOpen) {
|
|
310
|
+
this.openedByHover = true;
|
|
311
|
+
this.open();
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
onHoverLeave = (e) => {
|
|
315
|
+
if (!this.props.hoverControl)
|
|
316
|
+
return;
|
|
317
|
+
if (this.isRelatedHover(e.relatedTarget)) {
|
|
318
|
+
this.cancelHoverClose();
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
this.scheduleHoverClose();
|
|
322
|
+
};
|
|
323
|
+
bindHoverHandlers(props = {}) {
|
|
324
|
+
const enter = props.onPointerEnter;
|
|
325
|
+
const leave = props.onPointerLeave;
|
|
326
|
+
return {
|
|
327
|
+
...props,
|
|
328
|
+
onPointerEnter: (e) => {
|
|
329
|
+
this.onHoverEnter();
|
|
330
|
+
enter?.(e);
|
|
331
|
+
},
|
|
332
|
+
onPointerLeave: (e) => {
|
|
333
|
+
this.onHoverLeave(e);
|
|
334
|
+
leave?.(e);
|
|
335
|
+
},
|
|
336
|
+
};
|
|
314
337
|
}
|
|
315
338
|
onScroll = throttle(e => {
|
|
316
339
|
if (!this.state.isOpen) {
|
|
@@ -347,8 +370,12 @@ class Popup extends Component {
|
|
|
347
370
|
};
|
|
348
371
|
onTriggerPointerUp = e => {
|
|
349
372
|
this.pointerPressed = false;
|
|
350
|
-
if (e.
|
|
351
|
-
|
|
373
|
+
if (e.target !== this.pointerDownTarget)
|
|
374
|
+
return;
|
|
375
|
+
// Hover already opened — don't toggle shut on the same pointer.
|
|
376
|
+
if (this.state.isOpen && this.openedByHover)
|
|
377
|
+
return;
|
|
378
|
+
this.toggle();
|
|
352
379
|
};
|
|
353
380
|
onFocus = e => {
|
|
354
381
|
this.focused = true;
|
|
@@ -393,8 +420,13 @@ class Popup extends Component {
|
|
|
393
420
|
};
|
|
394
421
|
close = () => {
|
|
395
422
|
this.isOpening = false;
|
|
423
|
+
this.openedByHover = false;
|
|
424
|
+
this.cancelHoverClose();
|
|
396
425
|
if (!this.state.isOpen)
|
|
397
426
|
return;
|
|
427
|
+
const { rootPopupId } = this.state;
|
|
428
|
+
if (rootPopupId)
|
|
429
|
+
unsetChild(rootPopupId, this.id);
|
|
398
430
|
this.unsubscribeSizeChange();
|
|
399
431
|
this.changeState(false, this.afterClose);
|
|
400
432
|
};
|
|
@@ -438,9 +470,17 @@ class Popup extends Component {
|
|
|
438
470
|
if (!disableTrigger) {
|
|
439
471
|
triggerProps.role = 'button';
|
|
440
472
|
if (hoverControl) {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
473
|
+
const userDown = triggerProps.onPointerDown;
|
|
474
|
+
const userUp = triggerProps.onPointerUp;
|
|
475
|
+
Object.assign(triggerProps, this.bindHoverHandlers(triggerProps), {
|
|
476
|
+
onPointerDown: e => {
|
|
477
|
+
this.onTriggerPointerDown(e);
|
|
478
|
+
userDown?.(e);
|
|
479
|
+
},
|
|
480
|
+
onPointerUp: e => {
|
|
481
|
+
this.onTriggerPointerUp(e);
|
|
482
|
+
userUp?.(e);
|
|
483
|
+
},
|
|
444
484
|
});
|
|
445
485
|
}
|
|
446
486
|
if (focusControl) {
|
|
@@ -453,7 +493,10 @@ class Popup extends Component {
|
|
|
453
493
|
return (jsx("div", { className: classesTrigger, ...triggerProps, suppressHydrationWarning: true, "data-popup-id": this.id, ref: this.triggerElem, children: trigger }));
|
|
454
494
|
}
|
|
455
495
|
renderContent() {
|
|
456
|
-
const { content,
|
|
496
|
+
const { content, wrapperProps = {}, size, disabled, inline, outlined, animated, paranja, blur, round, elevation, hoverControl, } = this.props;
|
|
497
|
+
const contentProps = hoverControl
|
|
498
|
+
? this.bindHoverHandlers(this.props.contentProps ?? {})
|
|
499
|
+
: (this.props.contentProps ?? {});
|
|
457
500
|
const { isOpen, isContentVisible, animating, direction, triggerBounds, rootPopupId, boundaryFit, } = this.state;
|
|
458
501
|
if (disabled)
|
|
459
502
|
return null;
|
|
@@ -471,6 +514,15 @@ class Popup extends Component {
|
|
|
471
514
|
...(shiftTf ? { transform: shiftTf } : {}),
|
|
472
515
|
};
|
|
473
516
|
}
|
|
517
|
+
// Nested popups portal as siblings of the parent wrapper. A transform on
|
|
518
|
+
// the parent creates a stacking context, so the child needs a higher
|
|
519
|
+
// z-index or it paints under the parent (looks like it never opened).
|
|
520
|
+
if (rootPopupId) {
|
|
521
|
+
wrapperProps.style = {
|
|
522
|
+
...wrapperProps.style,
|
|
523
|
+
zIndex: 12,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
474
526
|
const contentNode = (jsx("div", { ...wrapperProps, className: wrapperClasses, children: jsxs("div", { ...contentProps, ref: this.onContainerElemRef, className: classes, suppressHydrationWarning: true, "data-popup-id": this.id, "data-root-popup-id": rootPopupId, style: {
|
|
475
527
|
...(contentProps.style ?? {}),
|
|
476
528
|
...(boundaryFit.maxWidth !== null && boundaryFit.maxWidth > 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Popup_root__uQ-fP{display:inline-block;position:relative}.Popup_contentWrapper__2yi-2{opacity:0;pointer-events:none;position:absolute}.Popup_contentWrapper__2yi-2.Popup_animating__kR0qF{transition:opacity .1s ease-out}.Popup_contentWrapper__2yi-2.Popup_isOpen__BRIdP{opacity:1;
|
|
3
|
+
var css_248z = ".Popup_root__uQ-fP{display:inline-block;position:relative}.Popup_contentWrapper__2yi-2{opacity:0;pointer-events:none;position:absolute}.Popup_contentWrapper__2yi-2.Popup_animating__kR0qF{transition:opacity .1s ease-out}.Popup_contentWrapper__2yi-2.Popup_isOpen__BRIdP{opacity:1;z-index:11}.Popup_contentWrapper__2yi-2.Popup_inline__1-l1S.Popup_isOpen__BRIdP{position:relative}.Popup_contentWrapper__2yi-2:not(.Popup_inline__1-l1S),.Popup_contentWrapper__2yi-2:not(.Popup_inline__1-l1S)>.Popup_content__e8Qyu{position:absolute}.Popup_trigger__jQNaQ{cursor:pointer}.Popup_trigger__jQNaQ.Popup_isOpen__BRIdP{position:relative;z-index:11}.Popup_trigger__jQNaQ.Popup_disabled__DlE9y{opacity:.4;pointer-events:none}.Popup_content__e8Qyu{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--decent-color);box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50);box-sizing:border-box;max-width:min(min(560px,70vw),calc(100svw - 16px));min-width:100%;overflow:hidden;position:relative;transform-origin:top center;z-index:11}.Popup_content__e8Qyu:before{background-color:var(--accent-color-alpha-50);bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.Popup_content__e8Qyu.Popup_blur__1hfU8{-webkit-backdrop-filter:blur(50px);backdrop-filter:blur(50px);background-color:var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_size-xs__7QR-d{border-radius:4px}.Popup_content__e8Qyu.Popup_size-xs__7QR-d.Popup_round__7rD1m{border-radius:12px}.Popup_content__e8Qyu.Popup_size-s__UmixP{border-radius:4px}.Popup_content__e8Qyu.Popup_size-s__UmixP.Popup_round__7rD1m{border-radius:16px}.Popup_content__e8Qyu.Popup_size-m__FYpTL{border-radius:6px}.Popup_content__e8Qyu.Popup_size-m__FYpTL.Popup_round__7rD1m{border-radius:20px}.Popup_content__e8Qyu.Popup_size-l__BTS57{border-radius:8px}.Popup_content__e8Qyu.Popup_size-l__BTS57.Popup_round__7rD1m{border-radius:24px}.Popup_content__e8Qyu.Popup_size-xl__fSfCc{border-radius:10px}.Popup_content__e8Qyu.Popup_size-xl__fSfCc.Popup_round__7rD1m{border-radius:28px}.Popup_content__e8Qyu.Popup_elevation-1__vmP3e{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 0 var(--p-3) 2px var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_elevation-2__Ci4sI{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 0 var(--p-5) 2px var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_outlined__g3cJV:after{border-radius:inherit;bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.Popup_isOpen__BRIdP .Popup_content__e8Qyu{opacity:1;pointer-events:all;transform:scaleX(1)}.Popup_animating__kR0qF{transition:70ms ease-out;transition-property:transform,opacity,margin}.Popup_axis-top__BaLgG{bottom:100%}.Popup_axis-bottom__hZwwr{top:100%}.Popup_axis-right__LMYVy{left:100%}.Popup_axis-left__SFKm-{right:100%}.Popup_float-top__8SQAu{bottom:0}.Popup_float-right__mdm-3{left:0}.Popup_float-bottom__7flve{top:0}.Popup_float-left__tz7fX{right:0}.Popup_axis-bottom__hZwwr,.Popup_axis-top__BaLgG{transform:scaleY(.5)}.Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1,.Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{left:50%;transform:translateX(-50%) scaleY(.5)}.Popup_isOpen__BRIdP .Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1,.Popup_isOpen__BRIdP .Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{transform:translateX(-50%) scaleX(1)}.Popup_axis-left__SFKm-,.Popup_axis-right__LMYVy{transform:scaleX(.5)}.Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1,.Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{top:50%;transform:translateY(-50%) scaleX(.5)}.Popup_isOpen__BRIdP .Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1,.Popup_isOpen__BRIdP .Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{transform:translateY(-50%) scaleX(1)}.Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{transform-origin:bottom center}.Popup_axis-top__BaLgG.Popup_float-right__mdm-3{transform-origin:bottom left}.Popup_axis-top__BaLgG.Popup_float-left__tz7fX{transform-origin:bottom right}.Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1{transform-origin:top center}.Popup_axis-bottom__hZwwr.Popup_float-right__mdm-3{transform-origin:top left}.Popup_axis-bottom__hZwwr.Popup_float-left__tz7fX{transform-origin:top right}.Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{transform-origin:center left}.Popup_axis-right__LMYVy.Popup_float-top__8SQAu{transform-origin:bottom left}.Popup_axis-right__LMYVy.Popup_float-bottom__7flve{transform-origin:top left}.Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1{transform-origin:center right}.Popup_axis-left__SFKm-.Popup_float-top__8SQAu{transform-origin:bottom right}.Popup_axis-left__SFKm-.Popup_float-bottom__7flve{transform-origin:top right}";
|
|
4
4
|
var S = {"root":"Popup_root__uQ-fP","contentWrapper":"Popup_contentWrapper__2yi-2","animating":"Popup_animating__kR0qF","isOpen":"Popup_isOpen__BRIdP","inline":"Popup_inline__1-l1S","content":"Popup_content__e8Qyu","trigger":"Popup_trigger__jQNaQ","disabled":"Popup_disabled__DlE9y","blur":"Popup_blur__1hfU8","size-xs":"Popup_size-xs__7QR-d","round":"Popup_round__7rD1m","size-s":"Popup_size-s__UmixP","size-m":"Popup_size-m__FYpTL","size-l":"Popup_size-l__BTS57","size-xl":"Popup_size-xl__fSfCc","elevation-1":"Popup_elevation-1__vmP3e","elevation-2":"Popup_elevation-2__Ci4sI","outlined":"Popup_outlined__g3cJV","axis-top":"Popup_axis-top__BaLgG","axis-bottom":"Popup_axis-bottom__hZwwr","axis-right":"Popup_axis-right__LMYVy","axis-left":"Popup_axis-left__SFKm-","float-top":"Popup_float-top__8SQAu","float-right":"Popup_float-right__mdm-3","float-bottom":"Popup_float-bottom__7flve","float-left":"Popup_float-left__tz7fX","float-middle":"Popup_float-middle__Dmnn1"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".PromptComposer_root__gfdXN{width:100%}.PromptComposer_scroller__Sueif{flex:1;max-height:200px;min-height:40px;width:100%}.PromptComposer_editorMount__B9G-o{background:transparent;border:none;border-radius:0!important;box-shadow:none!important;display:flex;flex:1;flex-direction:column;min-height:40px;min-width:0;padding:0!important}.PromptComposer_editorMount__B9G-o:focus-within{box-shadow:none!important}.PromptComposer_editorMount__B9G-o .PromptComposer_promptComposerEditor__yQIpq{border:none!important;box-shadow:none!important;flex:1;margin:0;min-height:40px!important;outline:none!important;overflow:hidden!important;padding:var(--p-2) 0 0!important;resize:none!important;transition:opacity .1s ease-out;white-space:pre-wrap;word-break:break-word}.PromptComposer_editorMount__B9G-o .PromptComposer_promptComposerEditor__yQIpq a{color:var(--link-color)}.PromptComposer_editorMount__B9G-o .PromptComposer_promptComposerEditor__yQIpq a:hover{cursor:pointer;opacity:.8}.PromptComposer_editorMount__B9G-o .
|
|
4
|
-
var S = {"root":"PromptComposer_root__gfdXN","scroller":"PromptComposer_scroller__Sueif","editorMount":"PromptComposer_editorMount__B9G-o","promptComposerEditor":"PromptComposer_promptComposerEditor__yQIpq","
|
|
3
|
+
var css_248z = ".PromptComposer_root__gfdXN{width:100%}.PromptComposer_scroller__Sueif{flex:1;max-height:200px;min-height:40px;width:100%}.PromptComposer_editorMount__B9G-o{background:transparent;border:none;border-radius:0!important;box-shadow:none!important;display:flex;flex:1;flex-direction:column;min-height:40px;min-width:0;padding:0!important}.PromptComposer_editorMount__B9G-o:focus-within{box-shadow:none!important}.PromptComposer_editorMount__B9G-o .PromptComposer_promptComposerEditor__yQIpq{border:none!important;box-shadow:none!important;flex:1;margin:0;min-height:40px!important;outline:none!important;overflow:hidden!important;padding:var(--p-2) 0 0!important;resize:none!important;transition:opacity .1s ease-out;white-space:pre-wrap;word-break:break-word}.PromptComposer_editorMount__B9G-o .PromptComposer_promptComposerEditor__yQIpq a{color:var(--link-color)}.PromptComposer_editorMount__B9G-o .PromptComposer_promptComposerEditor__yQIpq a:hover{cursor:pointer;opacity:.8}.PromptComposer_editorMount__B9G-o .PromptComposer_promptComposerEmptyNode__62Ylm:before{color:var(--muted-foreground);content:attr(data-placeholder);float:left;height:0;pointer-events:none}";
|
|
4
|
+
var S = {"root":"PromptComposer_root__gfdXN","scroller":"PromptComposer_scroller__Sueif","editorMount":"PromptComposer_editorMount__B9G-o","promptComposerEditor":"PromptComposer_promptComposerEditor__yQIpq","promptComposerEmptyNode":"PromptComposer_promptComposerEmptyNode__62Ylm"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -245,7 +245,7 @@ function Select2(props) {
|
|
|
245
245
|
const inputValue = isSearching ? searchVal : isMultiple$1 ? '' : selectedLabel;
|
|
246
246
|
return (jsx(Input, { ...triggerProps, ...inputProps,
|
|
247
247
|
// TODO: autoComplete
|
|
248
|
-
addonRight: triggerArrow, error: isErrorVisible, value: inputValue, onChange: handleSearchChange, label: getFieldLabel(label), placeholder: hasChips && !inputValue ? '' : inputProps?.placeholder }));
|
|
248
|
+
addonRight: triggerArrow, error: isErrorVisible, value: inputValue, onChange: handleSearchChange, selectAllOnFocus: true, label: getFieldLabel(label), placeholder: hasChips && !inputValue ? '' : inputProps?.placeholder }));
|
|
249
249
|
};
|
|
250
250
|
const renderTriggerButton = () => {
|
|
251
251
|
const { label, className, ...rest } = triggerProps;
|
|
@@ -8,12 +8,11 @@ function TextShimmerComponent({ children, as: Component = 'p', className, durati
|
|
|
8
8
|
const raw = Math.min(48, 3.5 + Math.max(0, Math.min(1, spread / 10)) * 100.5);
|
|
9
9
|
// Wide blend stops “vertical knife” artefacts when the ramp only spans few pixels inside the glyph mask.
|
|
10
10
|
const ridgeHalf = Math.min(49, Math.max(36, raw + 17));
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
: 'var(--txt-sh-highlight)';
|
|
11
|
+
// Resolve on the gradient so ancestor --txt-sh-* inherit. --decent-color is the surface.
|
|
12
|
+
const fill = 'var(--txt-sh-fill, var(--text-shimmer-decent-tone, var(--accent-color)))';
|
|
13
|
+
const highlight = 'var(--txt-sh-highlight, var(--text-shimmer-accent-tone, var(--active-color)))';
|
|
14
|
+
const baseColor = inverted ? highlight : fill;
|
|
15
|
+
const bandColor = inverted ? fill : highlight;
|
|
17
16
|
const backgroundGradient = `linear-gradient(90deg, ${baseColor} calc(50% - ${ridgeHalf}%), ${bandColor} 50%, ${baseColor} calc(50% + ${ridgeHalf}%))`;
|
|
18
17
|
return { backgroundGradient };
|
|
19
18
|
}, [spread, inverted]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".TextShimmer_root__cnKtV{-webkit-text-fill-color:transparent;-webkit-font-smoothing:antialiased
|
|
3
|
+
var css_248z = ".TextShimmer_root__cnKtV{-webkit-text-fill-color:transparent;-webkit-font-smoothing:antialiased;animation:TextShimmer_textShimmer__w7rQj 1s linear infinite;animation:TextShimmer_textShimmer__w7rQj var(--text-shimmer-duration,1s) linear infinite;-webkit-background-clip:text;background-clip:text;background-repeat:repeat-x;background-size:200% 100%;color:transparent!important;display:inline-block;position:relative}@keyframes TextShimmer_textShimmer__w7rQj{0%{background-position:100%}to{background-position:-100%}}";
|
|
4
4
|
var S = {"root":"TextShimmer_root__cnKtV","textShimmer":"TextShimmer_textShimmer__w7rQj"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -3,6 +3,39 @@ import { useState, useRef } from 'react';
|
|
|
3
3
|
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
4
4
|
import S from './TextWithDeferTooltip.styl.js';
|
|
5
5
|
|
|
6
|
+
function clipsOverflow(style, axis) {
|
|
7
|
+
const overflow = axis === 'x' ? style.overflowX : style.overflowY;
|
|
8
|
+
if (overflow === 'hidden' || overflow === 'auto' || overflow === 'scroll') {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (axis === 'x' && style.textOverflow === 'ellipsis')
|
|
12
|
+
return true;
|
|
13
|
+
if (axis === 'y' &&
|
|
14
|
+
style.webkitLineClamp &&
|
|
15
|
+
style.webkitLineClamp !== 'none') {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
function isNodeOverflowing(node) {
|
|
21
|
+
const style = getComputedStyle(node);
|
|
22
|
+
if (clipsOverflow(style, 'x') && node.scrollWidth - node.clientWidth > 1) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if (clipsOverflow(style, 'y') && node.scrollHeight - node.clientHeight > 1) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
function isTextOverflowing(root) {
|
|
31
|
+
if (isNodeOverflowing(root))
|
|
32
|
+
return true;
|
|
33
|
+
for (const child of root.querySelectorAll('*')) {
|
|
34
|
+
if (isNodeOverflowing(child))
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
6
39
|
function TextWithDeferTooltip({ className, children, width, maxWidth, side = 'bottom', overTrigger = false, ...props }) {
|
|
7
40
|
const [withTooltip, setWithTooltip] = useState(false);
|
|
8
41
|
const [tooltipWidth, setTooltipWidth] = useState();
|
|
@@ -11,9 +44,7 @@ function TextWithDeferTooltip({ className, children, width, maxWidth, side = 'bo
|
|
|
11
44
|
const handleMouseEnter = () => {
|
|
12
45
|
if (!ref.current)
|
|
13
46
|
return;
|
|
14
|
-
|
|
15
|
-
const isOverflowingVertically = ref.current.scrollHeight - ref.current.clientHeight > 3;
|
|
16
|
-
if (isOverflowingHorizontally || isOverflowingVertically) {
|
|
47
|
+
if (isTextOverflowing(ref.current)) {
|
|
17
48
|
if (width != null) {
|
|
18
49
|
setTooltipWidth(width);
|
|
19
50
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -24,4 +24,5 @@ export declare const Input: import("react").ForwardRefExoticComponent<Omit<impor
|
|
|
24
24
|
checkAutofill?: boolean;
|
|
25
25
|
scrollProps?: Partial<import("../Scroll/Scroll.types").Props>;
|
|
26
26
|
fitContentWidth?: boolean;
|
|
27
|
+
selectAllOnFocus?: boolean;
|
|
27
28
|
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -28,4 +28,6 @@ export type Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> & Om
|
|
|
28
28
|
scrollProps?: Partial<ScrollProps>;
|
|
29
29
|
/** When true, width follows text via CSS `field-sizing: content` (non-textarea only). */
|
|
30
30
|
fitContentWidth?: boolean;
|
|
31
|
+
/** Select the current value when the field is focused. */
|
|
32
|
+
selectAllOnFocus?: boolean;
|
|
31
33
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as T from './NestedMenu.types';
|
|
2
2
|
export declare function NestedMenuLabel({ children, className, }: T.NestedMenuLabelProps): import("react").JSX.Element;
|
|
3
3
|
export declare function NestedMenuItemRow({ children, className, danger, disabled, href, target, rel, onClick, }: T.NestedMenuRowProps): import("react").JSX.Element;
|
|
4
|
-
declare function NestedMenuComponent({ trigger, items, open, onOpenChange, align, className, }: T.Props): import("react").JSX.Element;
|
|
4
|
+
declare function NestedMenuComponent({ trigger, items, open, onOpenChange, align, size, className, popupProps, }: T.Props): import("react").JSX.Element;
|
|
5
5
|
export declare const NestedMenu: typeof NestedMenuComponent & {
|
|
6
6
|
Item: typeof NestedMenuItemRow;
|
|
7
7
|
Label: typeof NestedMenuLabel;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import { Props as PopupProps } from 'uilib/components/Popup/Popup.types';
|
|
3
|
+
import { Size } from 'uilib/types';
|
|
2
4
|
export type NestedMenuItem = {
|
|
3
5
|
id: string;
|
|
4
6
|
label: ReactNode;
|
|
@@ -19,7 +21,9 @@ export type Props = {
|
|
|
19
21
|
open: boolean;
|
|
20
22
|
onOpenChange: (open: boolean) => void;
|
|
21
23
|
align?: 'start' | 'end';
|
|
24
|
+
size?: Size;
|
|
22
25
|
className?: string;
|
|
26
|
+
popupProps?: Partial<PopupProps>;
|
|
23
27
|
};
|
|
24
28
|
export type NestedMenuProps = Props;
|
|
25
29
|
export type NestedMenuRowProps = {
|
|
@@ -10,11 +10,12 @@ export declare class Popup extends Component<T.Props, T.State> {
|
|
|
10
10
|
onContainerElemRef: (elem: any) => void;
|
|
11
11
|
focused: boolean;
|
|
12
12
|
isOpening: boolean;
|
|
13
|
+
openedByHover: boolean;
|
|
13
14
|
pointerPressed: boolean;
|
|
14
|
-
subscribedHoverControl: boolean;
|
|
15
15
|
subscribedSizeChange: boolean;
|
|
16
16
|
pointerDownTarget: any;
|
|
17
17
|
isPointerPressedInside: boolean;
|
|
18
|
+
hoverCloseUnsub: (() => void) | null;
|
|
18
19
|
id: any;
|
|
19
20
|
parentPopupContent: any;
|
|
20
21
|
timers: any;
|
|
@@ -36,8 +37,6 @@ export declare class Popup extends Component<T.Props, T.State> {
|
|
|
36
37
|
subscribeScroll(): void;
|
|
37
38
|
unsubscribeScroll(): void;
|
|
38
39
|
unsubscribeSizeChange(): void;
|
|
39
|
-
subscribeHoverControl(): void;
|
|
40
|
-
unsubscribeHoverControl(): void;
|
|
41
40
|
updateBounds(): void;
|
|
42
41
|
updateBoundsThrottled: any;
|
|
43
42
|
scheduleComputeShift(): void;
|
|
@@ -47,12 +46,21 @@ export declare class Popup extends Component<T.Props, T.State> {
|
|
|
47
46
|
maxWidth: number | null;
|
|
48
47
|
};
|
|
49
48
|
setBoundaryFit(boundaryFit: H.BoundaryFit): void;
|
|
50
|
-
checkHover: any;
|
|
51
49
|
isControllable: () => boolean;
|
|
52
50
|
isLastClickInside: () => any;
|
|
53
51
|
onDocPointerDown: (e: PointerEvent) => void;
|
|
54
52
|
onDocPointerUp: (e: PointerEvent) => void;
|
|
55
|
-
isPointerOver(target: any, elem: any):
|
|
53
|
+
isPointerOver(target: any, elem: any): Element;
|
|
54
|
+
isHoverInside(target: any): Element;
|
|
55
|
+
isRelatedHover(target: any): boolean;
|
|
56
|
+
cancelHoverClose(): void;
|
|
57
|
+
scheduleHoverClose(): void;
|
|
58
|
+
onHoverEnter: () => void;
|
|
59
|
+
onHoverLeave: (e: PointerEvent) => void;
|
|
60
|
+
bindHoverHandlers(props?: Record<string, unknown>): {
|
|
61
|
+
onPointerEnter: (e: PointerEvent) => void;
|
|
62
|
+
onPointerLeave: (e: PointerEvent) => void;
|
|
63
|
+
};
|
|
56
64
|
onScroll: any;
|
|
57
65
|
onDocKeyDown: (e: KeyboardEvent) => void;
|
|
58
66
|
onDocKeyUp: (e: KeyboardEvent) => void;
|
|
@@ -28,6 +28,7 @@ export declare class Select extends Component<T.Props, T.State> {
|
|
|
28
28
|
checkAutofill?: boolean;
|
|
29
29
|
scrollProps?: Partial<import("../Scroll/Scroll.types").Props>;
|
|
30
30
|
fitContentWidth?: boolean;
|
|
31
|
+
selectAllOnFocus?: boolean;
|
|
31
32
|
} & import("react").RefAttributes<HTMLInputElement>>>;
|
|
32
33
|
triggerInputRef: import("react").RefObject<HTMLDivElement>;
|
|
33
34
|
contentRef: import("react").RefObject<HTMLDivElement>;
|