@gooddata/sdk-ui-kit 11.42.0-alpha.0 → 11.42.0-alpha.2
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/esm/@ui/UiCombobox/UiComboboxInput.d.ts +22 -4
- package/esm/@ui/UiCombobox/UiComboboxInput.d.ts.map +1 -1
- package/esm/@ui/UiCombobox/UiComboboxInput.js +38 -31
- package/esm/@ui/UiCombobox/UiComboboxList.js +2 -2
- package/esm/@ui/UiCombobox/UiComboboxListItem.d.ts +3 -13
- package/esm/@ui/UiCombobox/UiComboboxListItem.d.ts.map +1 -1
- package/esm/@ui/UiCombobox/UiComboboxListItem.js +13 -23
- package/esm/@ui/UiCombobox/UiComboboxPopup.d.ts +6 -3
- package/esm/@ui/UiCombobox/UiComboboxPopup.d.ts.map +1 -1
- package/esm/@ui/UiCombobox/UiComboboxPopup.js +5 -7
- package/esm/@ui/UiCombobox/types.d.ts +17 -9
- package/esm/@ui/UiCombobox/types.d.ts.map +1 -1
- package/esm/@ui/UiCombobox/useCombobox.d.ts.map +1 -1
- package/esm/@ui/UiCombobox/useCombobox.js +73 -161
- package/esm/@ui/UiCombobox/useComboboxChrome.d.ts +9 -0
- package/esm/@ui/UiCombobox/useComboboxChrome.d.ts.map +1 -0
- package/esm/@ui/UiCombobox/useComboboxChrome.js +61 -0
- package/esm/@ui/UiCombobox/useComboboxSelection.d.ts +24 -0
- package/esm/@ui/UiCombobox/useComboboxSelection.d.ts.map +1 -0
- package/esm/@ui/UiCombobox/useComboboxSelection.js +82 -0
- package/esm/@ui/UiDropdown/UiDropdown.js +3 -3
- package/esm/@ui/UiFloatingElement/UiFloatingElement.d.ts.map +1 -1
- package/esm/@ui/UiFloatingElement/UiFloatingElement.js +3 -2
- package/esm/@ui/UiFloatingPanel/UiFloatingPanel.d.ts +28 -0
- package/esm/@ui/UiFloatingPanel/UiFloatingPanel.d.ts.map +1 -0
- package/esm/@ui/UiFloatingPanel/UiFloatingPanel.js +14 -0
- package/esm/@ui/UiTags/UiTags.d.ts.map +1 -1
- package/esm/@ui/UiTags/UiTags.js +2 -2
- package/esm/@ui/UiTextInput/UiTextInput.d.ts +13 -2
- package/esm/@ui/UiTextInput/UiTextInput.d.ts.map +1 -1
- package/esm/@ui/UiTextInput/UiTextInput.js +2 -2
- package/esm/@ui/UiTooltip/UiTooltip.d.ts.map +1 -1
- package/esm/@ui/UiTooltip/UiTooltip.js +10 -4
- package/esm/@ui/hooks/useCloseOnOutsideClick.d.ts +31 -0
- package/esm/@ui/hooks/useCloseOnOutsideClick.d.ts.map +1 -1
- package/esm/@ui/hooks/useCloseOnOutsideClick.js +73 -6
- package/esm/Dialog/ShareDialog/ShareDialog.d.ts +1 -1
- package/esm/Dialog/ShareDialog/ShareDialog.d.ts.map +1 -1
- package/esm/Dialog/ShareDialog/ShareDialog.js +2 -2
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareDialogBase.d.ts.map +1 -1
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareDialogBase.js +2 -2
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareGranteeBase.d.ts +1 -1
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareGranteeBase.d.ts.map +1 -1
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareGranteeBase.js +2 -2
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareLink.d.ts +1 -1
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareLink.d.ts.map +1 -1
- package/esm/Dialog/ShareDialog/ShareDialogBase/ShareLink.js +3 -3
- package/esm/Dialog/ShareDialog/ShareDialogBase/types.d.ts +3 -0
- package/esm/Dialog/ShareDialog/ShareDialogBase/types.d.ts.map +1 -1
- package/esm/Dialog/ShareDialog/types.d.ts +5 -0
- package/esm/Dialog/ShareDialog/types.d.ts.map +1 -1
- package/esm/Header/generateHeaderMenuItemsGroups.js +3 -3
- package/esm/Tabs/Tabs.d.ts +2 -1
- package/esm/Tabs/Tabs.d.ts.map +1 -1
- package/esm/Tabs/Tabs.js +1 -1
- package/esm/index.d.ts +3 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -0
- package/esm/sdk-ui-kit.d.ts +99 -33
- package/package.json +11 -11
- package/src/@ui/UiCombobox/UiCombobox.scss +0 -16
- package/src/@ui/UiDropdown/UiDropdown.scss +1 -20
- package/src/@ui/UiFloatingPanel/UiFloatingPanel.scss +27 -0
- package/src/@ui/UiMenu/UiMenu.scss +0 -1
- package/src/@ui/UiPopover/UiPopover.scss +8 -0
- package/src/@ui/UiTags/UiTags.scss +0 -4
- package/src/@ui/UiTextInput/UiTextInput.scss +6 -2
- package/src/@ui/index.scss +1 -0
- package/styles/css/list.css +6 -1
- package/styles/css/list.css.map +1 -1
- package/styles/css/main.css +24 -30
- package/styles/css/main.css.map +1 -1
- package/styles/css/menu.css +6 -1
- package/styles/css/menu.css.map +1 -1
- package/styles/icons/dashboard.svg +5 -0
- package/styles/scss/list.scss +6 -1
|
@@ -1,6 +1,24 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type FocusEvent, type KeyboardEvent, type MouseEvent } from "react";
|
|
2
2
|
/** @internal */
|
|
3
|
-
export
|
|
4
|
-
/**
|
|
5
|
-
|
|
3
|
+
export interface IUiComboboxInputProps {
|
|
4
|
+
/** Accessible name for the input. */
|
|
5
|
+
"aria-label"?: string;
|
|
6
|
+
/** Visible placeholder. */
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
/** Form field name forwarded to the underlying input. */
|
|
9
|
+
name?: string;
|
|
10
|
+
autoFocus?: boolean;
|
|
11
|
+
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
|
|
12
|
+
onFocus?: (event: FocusEvent<HTMLInputElement>) => void;
|
|
13
|
+
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
|
|
14
|
+
onClick?: (event: MouseEvent<HTMLInputElement>) => void;
|
|
15
|
+
dataTestId?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Binds `UiTextInput` to the surrounding `UiCombobox` state: value, keyboard
|
|
19
|
+
* handler, open/close, ARIA combobox+listbox attributes.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export declare const UiComboboxInput: import("react").ForwardRefExoticComponent<IUiComboboxInputProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
6
24
|
//# sourceMappingURL=UiComboboxInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UiComboboxInput.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/UiComboboxInput.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"UiComboboxInput.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/UiComboboxInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,UAAU,EAIlB,MAAM,OAAO,CAAC;AAMf,gBAAgB;AAChB,MAAM,WAAW,qBAAqB;IAClC,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC7D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACvD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oHAsF3B,CAAC"}
|
|
@@ -1,37 +1,44 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// (C) 2025 GoodData Corporation
|
|
3
|
-
import { forwardRef, } from "react";
|
|
4
|
-
import {
|
|
5
|
-
import cx from "classnames";
|
|
6
|
-
import { e } from "./comboboxBem.js";
|
|
2
|
+
// (C) 2025-2026 GoodData Corporation
|
|
3
|
+
import { forwardRef, useCallback, } from "react";
|
|
4
|
+
import { UiTextInput } from "../UiTextInput/UiTextInput.js";
|
|
7
5
|
import { useComboboxState } from "./UiComboboxContext.js";
|
|
8
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Binds `UiTextInput` to the surrounding `UiCombobox` state: value, keyboard
|
|
8
|
+
* handler, open/close, ARIA combobox+listbox attributes.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
9
12
|
export const UiComboboxInput = forwardRef(function UiComboboxInput(props, forwardedRef) {
|
|
10
|
-
const {
|
|
11
|
-
const { inputValue, onInputChange, onInputKeyDown, onInputBlur,
|
|
12
|
-
const
|
|
13
|
-
const referenceProps = getReferenceProps({
|
|
14
|
-
...htmlInputProps,
|
|
15
|
-
autoComplete: "off",
|
|
16
|
-
autoCapitalize: "none",
|
|
17
|
-
autoCorrect: "off",
|
|
18
|
-
// Most of the aria attributes already come from `getReferenceProps`
|
|
19
|
-
"aria-activedescendant": activeOption?.id,
|
|
20
|
-
"aria-autocomplete": "list",
|
|
21
|
-
onKeyDown: handleKeyDown,
|
|
22
|
-
onBlur: handleBlur,
|
|
23
|
-
});
|
|
24
|
-
function handleChange(event) {
|
|
25
|
-
onInputChange(event.target.value);
|
|
26
|
-
htmlInputProps.onChange?.(event);
|
|
27
|
-
}
|
|
28
|
-
function handleKeyDown(event) {
|
|
13
|
+
const { "aria-label": ariaLabel, placeholder, name, autoFocus, onKeyDown: callerOnKeyDown, onFocus: callerOnFocus, onBlur: callerOnBlur, onClick: callerOnClick, dataTestId, } = props;
|
|
14
|
+
const { inputValue, onInputChange, onInputKeyDown, onInputBlur, isOpen, setIsOpen, anchorRef, activeOption, listboxId, } = useComboboxState();
|
|
15
|
+
const handleKeyDown = useCallback((event) => {
|
|
29
16
|
onInputKeyDown(event);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
if (!event.isDefaultPrevented()) {
|
|
18
|
+
callerOnKeyDown?.(event);
|
|
19
|
+
}
|
|
20
|
+
}, [onInputKeyDown, callerOnKeyDown]);
|
|
21
|
+
const handleBlur = useCallback((event) => {
|
|
33
22
|
onInputBlur();
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
23
|
+
callerOnBlur?.(event);
|
|
24
|
+
}, [onInputBlur, callerOnBlur]);
|
|
25
|
+
// Click toggles open state (matches floating-ui's default `useClick`),
|
|
26
|
+
// so the user can also click to close. Focus alone doesn't open —
|
|
27
|
+
// Tab / programmatic focus shouldn't expand the listbox.
|
|
28
|
+
const handleClick = useCallback((event) => {
|
|
29
|
+
setIsOpen(!isOpen);
|
|
30
|
+
callerOnClick?.(event);
|
|
31
|
+
}, [isOpen, setIsOpen, callerOnClick]);
|
|
32
|
+
return (_jsx(UiTextInput, { inputRef: forwardedRef, wrapperRef: anchorRef, value: inputValue, onChange: onInputChange, name: name, placeholder: placeholder, autoFocus: autoFocus,
|
|
33
|
+
// Browser autofill would overlap the listbox; the combobox
|
|
34
|
+
// owns its own typeahead so we suppress all native suggestions.
|
|
35
|
+
autoComplete: "off", autoCapitalize: "none", autoCorrect: "off", dataTestId: dataTestId, onKeyDown: handleKeyDown, onFocus: callerOnFocus, onBlur: handleBlur, onClick: handleClick, accessibilityConfig: {
|
|
36
|
+
role: "combobox",
|
|
37
|
+
ariaAutocomplete: "list",
|
|
38
|
+
ariaExpanded: isOpen,
|
|
39
|
+
ariaActiveDescendant: activeOption?.id,
|
|
40
|
+
ariaHaspopup: "listbox",
|
|
41
|
+
ariaControls: listboxId,
|
|
42
|
+
ariaLabel,
|
|
43
|
+
} }));
|
|
37
44
|
});
|
|
@@ -7,6 +7,6 @@ import { useComboboxState } from "./UiComboboxContext.js";
|
|
|
7
7
|
import { UiComboboxListItem } from "./UiComboboxListItem.js";
|
|
8
8
|
/** @internal */
|
|
9
9
|
export function UiComboboxList({ children, className, ...htmlProps }) {
|
|
10
|
-
const { availableOptions } = useComboboxState();
|
|
11
|
-
return (_jsx("ul", { role: "listbox", ...htmlProps, className: cx(e("list"), className), tabIndex: -1, children: availableOptions.map((option, index) => children ? (_jsx(Fragment, { children: children(option, index) }, option.id)) : (_jsx(UiComboboxListItem, { option: option, index: index }, option.id))) }));
|
|
10
|
+
const { availableOptions, listboxId } = useComboboxState();
|
|
11
|
+
return (_jsx("ul", { role: "listbox", ...htmlProps, id: listboxId, className: cx(e("list"), className), tabIndex: -1, children: availableOptions.map((option, index) => children ? (_jsx(Fragment, { children: children(option, index) }, option.id)) : (_jsx(UiComboboxListItem, { option: option, index: index }, option.id))) }));
|
|
12
12
|
}
|
|
@@ -11,28 +11,18 @@ type UiComboboxListItemImplProps = IUiComboboxListItemProps & {
|
|
|
11
11
|
isActive: boolean;
|
|
12
12
|
isSelected: boolean;
|
|
13
13
|
isDisabled: boolean;
|
|
14
|
-
getItemProps: IUiComboboxState["getItemProps"];
|
|
15
14
|
registerItemRef: IUiComboboxState["registerItemRef"];
|
|
15
|
+
setActiveIndex: IUiComboboxState["setActiveIndex"];
|
|
16
16
|
selectOption: IUiComboboxState["selectOption"];
|
|
17
17
|
};
|
|
18
18
|
export declare const UiComboboxListItemImpl: import("react").NamedExoticComponent<UiComboboxListItemImplProps>;
|
|
19
19
|
/** @internal */
|
|
20
20
|
export type UiComboboxListItemLabelProps = HTMLAttributes<HTMLSpanElement>;
|
|
21
|
-
/**
|
|
22
|
-
* Renders the primary label content within a combobox list item.
|
|
23
|
-
* Use this component for composable customization of list item content.
|
|
24
|
-
*
|
|
25
|
-
* @internal
|
|
26
|
-
*/
|
|
21
|
+
/** @internal */
|
|
27
22
|
export declare function UiComboboxListItemLabel(props: UiComboboxListItemLabelProps): import("react/jsx-runtime").JSX.Element;
|
|
28
23
|
/** @internal */
|
|
29
24
|
export type UiComboboxListItemCreatableLabelProps = HTMLAttributes<HTMLSpanElement>;
|
|
30
|
-
/**
|
|
31
|
-
* Renders the "creatable" label suffix within a combobox list item.
|
|
32
|
-
* Use this component for composable customization of list item content.
|
|
33
|
-
*
|
|
34
|
-
* @internal
|
|
35
|
-
*/
|
|
25
|
+
/** @internal */
|
|
36
26
|
export declare function UiComboboxListItemCreatableLabel(props: UiComboboxListItemCreatableLabelProps): import("react/jsx-runtime").JSX.Element;
|
|
37
27
|
export {};
|
|
38
28
|
//# sourceMappingURL=UiComboboxListItem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UiComboboxListItem.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/UiComboboxListItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAyB,MAAM,OAAO,CAAC;AAKnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGtE,gBAAgB;AAChB,MAAM,WAAW,wBAAyB,SAAQ,cAAc,CAAC,aAAa,CAAC;IAC3E,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,gBAAgB;AAChB,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"UiComboboxListItem.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/UiComboboxListItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAyB,MAAM,OAAO,CAAC;AAKnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGtE,gBAAgB;AAChB,MAAM,WAAW,wBAAyB,SAAQ,cAAc,CAAC,aAAa,CAAC;IAC3E,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,gBAAgB;AAChB,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,wBAAwB,2CAoBjE;AAED,KAAK,2BAA2B,GAAG,wBAAwB,GAAG;IAC1D,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;IACrD,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACnD,YAAY,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;CAClD,CAAC;AAEF,eAAO,MAAM,sBAAsB,mEAyDjC,CAAC;AAEH,gBAAgB;AAChB,MAAM,MAAM,4BAA4B,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;AAE3E,gBAAgB;AAChB,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,2CAO1E;AAED,gBAAgB;AAChB,MAAM,MAAM,qCAAqC,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;AAEpF,gBAAgB;AAChB,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,qCAAqC,2CAO5F"}
|
|
@@ -7,20 +7,14 @@ import { useComboboxState } from "./UiComboboxContext.js";
|
|
|
7
7
|
/** @internal */
|
|
8
8
|
export function UiComboboxListItem(props) {
|
|
9
9
|
const { option } = props;
|
|
10
|
-
const { registerItemRef,
|
|
10
|
+
const { registerItemRef, setActiveIndex, selectOption, activeOption, selectedOption } = useComboboxState();
|
|
11
11
|
const isDisabled = Boolean(option.disabled);
|
|
12
12
|
const isActive = activeOption?.id === option.id;
|
|
13
13
|
const isSelected = selectedOption?.id === option.id;
|
|
14
|
-
return (_jsx(UiComboboxListItemImpl, { ...props, isActive: isActive, isSelected: isSelected, isDisabled: isDisabled,
|
|
14
|
+
return (_jsx(UiComboboxListItemImpl, { ...props, isActive: isActive, isSelected: isSelected, isDisabled: isDisabled, registerItemRef: registerItemRef, setActiveIndex: setActiveIndex, selectOption: selectOption }));
|
|
15
15
|
}
|
|
16
16
|
export const UiComboboxListItemImpl = memo(function UiComboboxListItemImpl(props) {
|
|
17
|
-
const { option, index, className, children, onClick, isActive, isSelected, isDisabled,
|
|
18
|
-
// https://floating-ui.com/docs/useRole#component-roles
|
|
19
|
-
const itemProps = getItemProps({
|
|
20
|
-
...htmlProps,
|
|
21
|
-
active: isActive,
|
|
22
|
-
selected: isSelected,
|
|
23
|
-
});
|
|
17
|
+
const { option, index, className, children, onClick, onMouseMove, isActive, isSelected, isDisabled, registerItemRef, setActiveIndex, selectOption, ...htmlProps } = props;
|
|
24
18
|
function handleClick(event) {
|
|
25
19
|
if (isDisabled) {
|
|
26
20
|
event.preventDefault();
|
|
@@ -29,27 +23,23 @@ export const UiComboboxListItemImpl = memo(function UiComboboxListItemImpl(props
|
|
|
29
23
|
selectOption(option, index);
|
|
30
24
|
onClick?.(event);
|
|
31
25
|
}
|
|
32
|
-
|
|
26
|
+
function handleMouseMove(event) {
|
|
27
|
+
if (!isActive) {
|
|
28
|
+
setActiveIndex(index);
|
|
29
|
+
}
|
|
30
|
+
onMouseMove?.(event);
|
|
31
|
+
}
|
|
32
|
+
return (_jsx("li", { ...htmlProps, ref: (node) => {
|
|
33
33
|
registerItemRef(node, index);
|
|
34
|
-
}, id: option.id, role: "option", "aria-selected": isSelected, "aria-disabled": isDisabled, className: cx(e("item", { isActive, isSelected, isDisabled }), className), onClick: handleClick, children: children ?? (_jsxs(_Fragment, { children: [
|
|
34
|
+
}, id: option.id, role: "option", "aria-selected": isSelected, "aria-disabled": isDisabled, className: cx(e("item", { isActive, isSelected, isDisabled }), className), onClick: handleClick, onMouseMove: handleMouseMove, children: children ?? (_jsxs(_Fragment, { children: [
|
|
35
35
|
_jsx(UiComboboxListItemLabel, { children: option.label }), option.creatable ? _jsx(UiComboboxListItemCreatableLabel, {}) : null] })) }));
|
|
36
36
|
});
|
|
37
|
-
/**
|
|
38
|
-
* Renders the primary label content within a combobox list item.
|
|
39
|
-
* Use this component for composable customization of list item content.
|
|
40
|
-
*
|
|
41
|
-
* @internal
|
|
42
|
-
*/
|
|
37
|
+
/** @internal */
|
|
43
38
|
export function UiComboboxListItemLabel(props) {
|
|
44
39
|
const { children, className, ...htmlProps } = props;
|
|
45
40
|
return (_jsx("span", { ...htmlProps, className: cx(e("item-label"), className), children: children }));
|
|
46
41
|
}
|
|
47
|
-
/**
|
|
48
|
-
* Renders the "creatable" label suffix within a combobox list item.
|
|
49
|
-
* Use this component for composable customization of list item content.
|
|
50
|
-
*
|
|
51
|
-
* @internal
|
|
52
|
-
*/
|
|
42
|
+
/** @internal */
|
|
53
43
|
export function UiComboboxListItemCreatableLabel(props) {
|
|
54
44
|
const { children = "(create new)", className, ...htmlProps } = props;
|
|
55
45
|
return (_jsx("span", { ...htmlProps, className: cx(e("item-creatable"), className), children: children }));
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CSSProperties, type ReactNode } from "react";
|
|
2
2
|
/** @internal */
|
|
3
|
-
export
|
|
3
|
+
export interface IUiComboboxPopupProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
style?: CSSProperties;
|
|
6
|
+
}
|
|
4
7
|
/** @internal */
|
|
5
|
-
export declare function UiComboboxPopup({
|
|
8
|
+
export declare function UiComboboxPopup({ children, style }: IUiComboboxPopupProps): import("react/jsx-runtime").JSX.Element | null;
|
|
6
9
|
//# sourceMappingURL=UiComboboxPopup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UiComboboxPopup.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/UiComboboxPopup.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UiComboboxPopup.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/UiComboboxPopup.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAM3D,gBAAgB;AAChB,MAAM,WAAW,qBAAqB;IAClC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,gBAAgB;AAChB,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,qBAAqB,kDAwBzE"}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
import cx from "classnames";
|
|
4
|
-
import { e } from "./comboboxBem.js";
|
|
2
|
+
import { UiFloatingPanel } from "../UiFloatingPanel/UiFloatingPanel.js";
|
|
5
3
|
import { useComboboxState } from "./UiComboboxContext.js";
|
|
6
4
|
/** @internal */
|
|
7
|
-
export function UiComboboxPopup({
|
|
8
|
-
const { isOpen,
|
|
9
|
-
if (!
|
|
5
|
+
export function UiComboboxPopup({ children, style }) {
|
|
6
|
+
const { isOpen, setIsOpen, anchorRef, shouldRenderPopup } = useComboboxState();
|
|
7
|
+
if (!shouldRenderPopup) {
|
|
10
8
|
return null;
|
|
11
9
|
}
|
|
12
|
-
return (_jsx(
|
|
10
|
+
return (_jsx(UiFloatingPanel, { anchor: anchorRef, isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-start", width: "same-as-anchor", padding: "listbox", closeOnOutsideClick: true, accessibilityConfig: { role: undefined }, style: style, children: _jsx("div", { onMouseDown: (event) => event.preventDefault(), children: children }) }));
|
|
13
11
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { CSSProperties, KeyboardEvent } from "react";
|
|
1
|
+
import type { KeyboardEvent, RefObject } from "react";
|
|
3
2
|
/** @internal */
|
|
4
3
|
export interface IUiComboboxOption {
|
|
5
4
|
id: string;
|
|
@@ -22,7 +21,10 @@ export interface IUiComboboxParams {
|
|
|
22
21
|
*/
|
|
23
22
|
defaultValue?: string;
|
|
24
23
|
/**
|
|
25
|
-
*
|
|
24
|
+
* Called whenever the input value changes — on typing, on Escape reset,
|
|
25
|
+
* and when an option is selected. The combobox is fully controlled when
|
|
26
|
+
* paired with `value`; consumers that need to distinguish selection from
|
|
27
|
+
* typing should inspect the current `selectedOption` state.
|
|
26
28
|
*/
|
|
27
29
|
onValueChange?: (value: string) => void;
|
|
28
30
|
/**
|
|
@@ -45,13 +47,19 @@ export interface IUiComboboxState {
|
|
|
45
47
|
selectOption: (option: IUiComboboxOption, index?: number) => void;
|
|
46
48
|
isOpen: boolean;
|
|
47
49
|
setIsOpen: (isOpen: boolean) => void;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Drives popup visibility. Sync combobox sets it to `availableOptions.length > 0`;
|
|
52
|
+
* async sources keep it `true` so status rows (loading / error / no-match) can show.
|
|
53
|
+
*/
|
|
54
|
+
shouldRenderPopup: boolean;
|
|
55
|
+
/** Anchor for the popup — typically the input's outer wrapper, so the popup matches the visible field width. */
|
|
56
|
+
anchorRef: RefObject<HTMLElement | null>;
|
|
50
57
|
registerItemRef: (node: HTMLElement | null, index: number) => void;
|
|
51
|
-
getReferenceProps: UseInteractionsReturn["getReferenceProps"];
|
|
52
|
-
getFloatingProps: UseInteractionsReturn["getFloatingProps"];
|
|
53
|
-
getItemProps: UseInteractionsReturn["getItemProps"];
|
|
54
|
-
floatingStyles: CSSProperties;
|
|
55
58
|
creatable: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Stable id of the `<ul role="listbox">`. The input advertises it via
|
|
61
|
+
* `aria-controls`; the listbox sets it as its `id`.
|
|
62
|
+
*/
|
|
63
|
+
listboxId: string;
|
|
56
64
|
}
|
|
57
65
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,gBAAgB;AAChB,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,gBAAgB;AAChB,MAAM,WAAW,iBAAiB;IAC9B;;OAEG;IACH,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,gBAAgB;AAChB,MAAM,WAAW,gBAAgB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACjE,WAAW,EAAE,MAAM,IAAI,CAAC;IAExB,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,YAAY,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC5C,cAAc,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC9C,YAAY,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAElE,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC;;;OAGG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kHAAgH;IAChH,SAAS,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACzC,eAAe,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnE,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCombobox.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/useCombobox.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useCombobox.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/useCombobox.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkBtE,gBAAgB;AAChB,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB,CA+EvE"}
|
|
@@ -1,169 +1,81 @@
|
|
|
1
1
|
// (C) 2025-2026 GoodData Corporation
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { useId, useMemo } from "react";
|
|
3
|
+
import { makeKeyboardNavigation } from "../@utils/keyboardNavigation.js";
|
|
4
|
+
import { useComboboxChrome } from "./useComboboxChrome.js";
|
|
5
|
+
import { useComboboxSelection } from "./useComboboxSelection.js";
|
|
6
|
+
// Omit handlers where we want default behavior to fall through —
|
|
7
|
+
// `makeKeyboardNavigation` preventDefaults every registered action.
|
|
8
|
+
const comboboxKeys = makeKeyboardNavigation({
|
|
9
|
+
onArrowDown: [{ code: "ArrowDown" }],
|
|
10
|
+
onArrowUp: [{ code: "ArrowUp" }],
|
|
11
|
+
onEnter: [{ code: ["Enter", "NumpadEnter"] }],
|
|
12
|
+
onEscape: [{ code: "Escape" }],
|
|
13
|
+
});
|
|
5
14
|
/** @internal */
|
|
6
15
|
export function useCombobox(params) {
|
|
7
16
|
const { value, defaultValue = "", onValueChange, options, creatable = false } = params;
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
setActiveIndex(null);
|
|
16
|
-
setSelectedOption(undefined);
|
|
17
|
-
}, [defaultValue, setInputValue]);
|
|
18
|
-
const availableOptions = useMemo(() => {
|
|
19
|
-
const value = normalizeValue(inputValue);
|
|
20
|
-
const selectedValue = selectedOption ? normalizeValue(selectedOption.label) : undefined;
|
|
21
|
-
// Show all options when there is no value or the value is the same as the selected value
|
|
22
|
-
if (!value || value === selectedValue) {
|
|
23
|
-
return options;
|
|
24
|
-
}
|
|
25
|
-
const matchedOptions = options.filter((option) => normalizeValue(option.label).includes(value));
|
|
26
|
-
const hasExactMatch = matchedOptions.some((option) => normalizeValue(option.label) === value);
|
|
27
|
-
// Add a creatable option if there are multiple matches and none matches the input exactly
|
|
28
|
-
if (creatable && !hasExactMatch) {
|
|
29
|
-
matchedOptions.push({
|
|
30
|
-
id: `creatable/${inputValue}`,
|
|
31
|
-
label: inputValue,
|
|
32
|
-
creatable: true,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
return matchedOptions;
|
|
36
|
-
}, [options, inputValue, selectedOption, creatable]);
|
|
37
|
-
const activeOption = activeIndex == null ? undefined : availableOptions[activeIndex];
|
|
38
|
-
const { setReferenceRef, setFloatingRef, floatingStyles, getReferenceProps, getFloatingProps, getItemProps, registerItemRef, } = useComboboxFloating({ isOpen, setIsOpen, activeIndex, setActiveIndex });
|
|
39
|
-
const handleSelectOption = useCallback((option, index) => {
|
|
40
|
-
if (index !== undefined) {
|
|
41
|
-
setActiveIndex(index);
|
|
42
|
-
}
|
|
43
|
-
setSelectedOption(option);
|
|
44
|
-
setIsOpen(false);
|
|
45
|
-
setInputValue(option.label);
|
|
46
|
-
}, [setInputValue]);
|
|
47
|
-
const handleInputChange = useCallback((inputValue) => {
|
|
48
|
-
setInputValue(inputValue);
|
|
49
|
-
setIsOpen(true);
|
|
50
|
-
}, [setInputValue]);
|
|
51
|
-
const handleInputKeyDown = useCallback((event) => {
|
|
52
|
-
if (event.key === "Escape" && !isOpen && !isInputValueEmpty) {
|
|
53
|
-
event.stopPropagation();
|
|
54
|
-
resetState();
|
|
55
|
-
}
|
|
56
|
-
if (event.key === "Enter" && activeOption) {
|
|
57
|
-
event.preventDefault();
|
|
58
|
-
handleSelectOption(activeOption);
|
|
59
|
-
}
|
|
60
|
-
}, [activeOption, isInputValueEmpty, isOpen, handleSelectOption, resetState]);
|
|
61
|
-
const handleInputBlur = useCallback(() => {
|
|
62
|
-
if (inputValue && selectedOption && inputValue !== selectedOption.label && !creatable) {
|
|
63
|
-
setInputValue(selectedOption.label);
|
|
64
|
-
}
|
|
65
|
-
setIsOpen(false);
|
|
66
|
-
}, [inputValue, selectedOption, setInputValue, creatable]);
|
|
67
|
-
return useMemo(() => ({
|
|
68
|
-
availableOptions,
|
|
69
|
-
inputValue,
|
|
70
|
-
isOpen,
|
|
71
|
-
setIsOpen,
|
|
72
|
-
onInputChange: handleInputChange,
|
|
73
|
-
onInputKeyDown: handleInputKeyDown,
|
|
74
|
-
onInputBlur: handleInputBlur,
|
|
75
|
-
activeIndex,
|
|
76
|
-
setActiveIndex,
|
|
77
|
-
activeOption,
|
|
78
|
-
selectedOption,
|
|
79
|
-
selectOption: handleSelectOption,
|
|
80
|
-
setReferenceRef,
|
|
81
|
-
setFloatingRef,
|
|
82
|
-
registerItemRef,
|
|
83
|
-
getReferenceProps,
|
|
84
|
-
getFloatingProps,
|
|
85
|
-
getItemProps,
|
|
86
|
-
floatingStyles,
|
|
17
|
+
const listboxId = useId();
|
|
18
|
+
const chrome = useComboboxChrome();
|
|
19
|
+
const selection = useComboboxSelection({
|
|
20
|
+
options,
|
|
21
|
+
value,
|
|
22
|
+
defaultValue,
|
|
23
|
+
onValueChange,
|
|
87
24
|
creatable,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
25
|
+
setIsOpen: chrome.setIsOpen,
|
|
26
|
+
setActiveIndex: chrome.setActiveIndex,
|
|
27
|
+
});
|
|
28
|
+
// Clamp on read so a filter that shrinks the list doesn't leave us
|
|
29
|
+
// pointing past the end (Enter would otherwise be a silent no-op).
|
|
30
|
+
const optionCount = selection.availableOptions.length;
|
|
31
|
+
const safeActiveIndex = chrome.activeIndex == null ? null : Math.min(chrome.activeIndex, optionCount - 1);
|
|
32
|
+
const activeOption = safeActiveIndex == null || optionCount === 0
|
|
33
|
+
? undefined
|
|
34
|
+
: selection.availableOptions[safeActiveIndex];
|
|
35
|
+
const onInputKeyDown = useMemo(() => {
|
|
36
|
+
// Leave Enter unhandled when there's no selectable target so creatable
|
|
37
|
+
// flows like UiTags (add tag on unhandled Enter) can react to it.
|
|
38
|
+
const onEnter = chrome.isOpen && activeOption
|
|
39
|
+
? activeOption.disabled
|
|
40
|
+
? () => undefined
|
|
41
|
+
: () => selection.selectOption(activeOption)
|
|
42
|
+
: undefined;
|
|
43
|
+
// Leave Escape unhandled when idle so the enclosing modal can dismiss.
|
|
44
|
+
const hasSomethingToClose = chrome.isOpen || selection.inputValue.length > 0;
|
|
45
|
+
const onEscape = hasSomethingToClose
|
|
46
|
+
? (event) => {
|
|
47
|
+
event.nativeEvent.stopPropagation();
|
|
48
|
+
if (chrome.isOpen) {
|
|
49
|
+
chrome.setIsOpen(false);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
selection.resetState();
|
|
53
|
+
}
|
|
54
|
+
: undefined;
|
|
55
|
+
return comboboxKeys({
|
|
56
|
+
onArrowDown: () => chrome.focusByDelta(1, optionCount),
|
|
57
|
+
onArrowUp: () => chrome.focusByDelta(-1, optionCount),
|
|
58
|
+
onEnter,
|
|
59
|
+
onEscape,
|
|
60
|
+
});
|
|
61
|
+
}, [chrome, selection, activeOption, optionCount]);
|
|
62
|
+
return useMemo(() => ({
|
|
63
|
+
availableOptions: selection.availableOptions,
|
|
64
|
+
inputValue: selection.inputValue,
|
|
65
|
+
isOpen: chrome.isOpen,
|
|
66
|
+
setIsOpen: chrome.setIsOpen,
|
|
67
|
+
onInputChange: selection.onInputChange,
|
|
68
|
+
onInputKeyDown,
|
|
69
|
+
onInputBlur: selection.onInputBlur,
|
|
70
|
+
activeIndex: chrome.activeIndex,
|
|
71
|
+
setActiveIndex: chrome.setActiveIndex,
|
|
96
72
|
activeOption,
|
|
97
|
-
selectedOption,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
getReferenceProps,
|
|
103
|
-
getFloatingProps,
|
|
104
|
-
getItemProps,
|
|
105
|
-
floatingStyles,
|
|
73
|
+
selectedOption: selection.selectedOption,
|
|
74
|
+
selectOption: selection.selectOption,
|
|
75
|
+
anchorRef: chrome.anchorRef,
|
|
76
|
+
registerItemRef: chrome.registerItemRef,
|
|
77
|
+
shouldRenderPopup: optionCount > 0,
|
|
106
78
|
creatable,
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
function useControlledValue(params) {
|
|
110
|
-
const { value, defaultValue, onValueChange } = params;
|
|
111
|
-
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
112
|
-
const isControlled = value !== undefined;
|
|
113
|
-
const controlledValue = isControlled ? value : uncontrolledValue;
|
|
114
|
-
const setControlledValue = useCallback((newValue) => {
|
|
115
|
-
if (isControlled) {
|
|
116
|
-
onValueChange?.(newValue);
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
setUncontrolledValue(newValue);
|
|
120
|
-
}
|
|
121
|
-
}, [isControlled, onValueChange]);
|
|
122
|
-
return [controlledValue, setControlledValue];
|
|
123
|
-
}
|
|
124
|
-
function useComboboxFloating(params) {
|
|
125
|
-
const { isOpen, setIsOpen, activeIndex, setActiveIndex } = params;
|
|
126
|
-
const listRef = useRef([]);
|
|
127
|
-
const { refs, floatingStyles, context } = useFloating({
|
|
128
|
-
placement: "bottom-start",
|
|
129
|
-
open: isOpen,
|
|
130
|
-
onOpenChange: setIsOpen,
|
|
131
|
-
whileElementsMounted: autoUpdate,
|
|
132
|
-
middleware: [
|
|
133
|
-
flip(),
|
|
134
|
-
size({
|
|
135
|
-
apply({ rects, elements }) {
|
|
136
|
-
elements.floating.style.width = `${rects.reference.width}px`;
|
|
137
|
-
},
|
|
138
|
-
}),
|
|
139
|
-
],
|
|
140
|
-
});
|
|
141
|
-
const listNav = useListNavigation(context, {
|
|
142
|
-
listRef,
|
|
143
|
-
activeIndex,
|
|
144
|
-
onNavigate: setActiveIndex,
|
|
145
|
-
virtual: true,
|
|
146
|
-
loop: true,
|
|
147
|
-
});
|
|
148
|
-
const click = useClick(context);
|
|
149
|
-
const dismiss = useDismiss(context);
|
|
150
|
-
const role = useRole(context, { role: "combobox" });
|
|
151
|
-
const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
|
|
152
|
-
listNav,
|
|
153
|
-
click,
|
|
154
|
-
dismiss,
|
|
155
|
-
role,
|
|
156
|
-
]);
|
|
157
|
-
const registerItemRef = useCallback((node, index) => {
|
|
158
|
-
listRef.current[index] = node;
|
|
159
|
-
}, []);
|
|
160
|
-
return {
|
|
161
|
-
setReferenceRef: refs.setReference,
|
|
162
|
-
setFloatingRef: refs.setFloating,
|
|
163
|
-
floatingStyles,
|
|
164
|
-
getReferenceProps,
|
|
165
|
-
getFloatingProps,
|
|
166
|
-
getItemProps,
|
|
167
|
-
registerItemRef,
|
|
168
|
-
};
|
|
79
|
+
listboxId,
|
|
80
|
+
}), [chrome, selection, onInputKeyDown, activeOption, creatable, listboxId, optionCount]);
|
|
169
81
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IUiComboboxState } from "./types.js";
|
|
2
|
+
type IUseComboboxChromeReturn = Pick<IUiComboboxState, "isOpen" | "setIsOpen" | "activeIndex" | "setActiveIndex" | "anchorRef" | "registerItemRef"> & {
|
|
3
|
+
/** Open the popup if needed and move highlight by `delta`, wrapping at `total`. */
|
|
4
|
+
focusByDelta: (delta: 1 | -1, total: number) => void;
|
|
5
|
+
};
|
|
6
|
+
/** @internal */
|
|
7
|
+
export declare function useComboboxChrome(): IUseComboboxChromeReturn;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=useComboboxChrome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useComboboxChrome.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiCombobox/useComboboxChrome.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,KAAK,wBAAwB,GAAG,IAAI,CAChC,gBAAgB,EAChB,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,gBAAgB,GAAG,WAAW,GAAG,iBAAiB,CAC9F,GAAG;IACA,mFAAmF;IACnF,YAAY,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD,CAAC;AAEF,gBAAgB;AAChB,wBAAgB,iBAAiB,IAAI,wBAAwB,CAmE5D"}
|