@purpurds/autocomplete 5.14.0 → 5.15.1
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/LICENSE.txt +10 -10
- package/dist/autocomplete.cjs.js +21 -13
- package/dist/autocomplete.cjs.js.map +1 -1
- package/dist/autocomplete.d.ts +6 -6
- package/dist/autocomplete.d.ts.map +1 -1
- package/dist/autocomplete.es.js +566 -446
- package/dist/autocomplete.es.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/useAutocomplete.d.ts +1 -1
- package/dist/useAutocomplete.d.ts.map +1 -1
- package/package.json +10 -9
- package/src/autocomplete.stories.tsx +1 -0
- package/src/autocomplete.test.tsx +9 -5
- package/src/autocomplete.tsx +6 -6
- package/src/useAutocomplete.ts +11 -2
- package/dist/listbox.d.ts +0 -22
- package/dist/listbox.d.ts.map +0 -1
- package/src/listbox.module.scss +0 -60
- package/src/listbox.tsx +0 -94
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
._purpur-autocomplete_1u8x6_1{position:relative}._purpur-autocomplete__listbox_1u8x6_4{position:absolute;z-index:1;top:calc(100% + var(--purpur-spacing-100))}._purpur-autocomplete__chevron-button_1u8x6_9{padding:0;border:0;background:none;cursor:pointer}._purpur-autocomplete_1u8x6_1 ._purpur-autocomplete__chevron-icon_1u8x6_15{display:block;transition:transform var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}._purpur-autocomplete_1u8x6_1 ._purpur-autocomplete__chevron-icon--up_1u8x6_19{transform:rotate(180deg)}
|
|
1
|
+
._purpur-autocomplete_1u8x6_1{position:relative}._purpur-autocomplete__listbox_1u8x6_4{position:absolute;z-index:1;top:calc(100% + var(--purpur-spacing-100))}._purpur-autocomplete__chevron-button_1u8x6_9{padding:0;border:0;background:none;cursor:pointer}._purpur-autocomplete_1u8x6_1 ._purpur-autocomplete__chevron-icon_1u8x6_15{display:block;transition:transform var(--purpur-motion-duration-200) var(--purpur-motion-easing-ease-in-out)}._purpur-autocomplete_1u8x6_1 ._purpur-autocomplete__chevron-icon--up_1u8x6_19{transform:rotate(180deg)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../src/useAutocomplete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../src/useAutocomplete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIxE,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC,GAAG;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,MAAM,IAAI;IAIrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAInB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAI/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAI3B,UAAU,CAAC,EAAE,MAAM,CAAC;IAIpB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;IAItE,EAAE,EAAE,MAAM,CAAC;IAIX,YAAY,EAAE,MAAM,CAAC;IAIrB,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAInC,aAAa,CAAC,EAAE,SAAS,CAAC;IAI1B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAIxC,WAAW,CAAC,EAAE,OAAO,CAAC;IAItB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;IAI3C,OAAO,EAAE,CAAC,EAAE,CAAC;IAIb,cAAc,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,mOAgB7C,sBAAsB,CAAC,CAAC,CAAC;;;;;;;;kCAqLW,CAAC,SAAS,MAAM,KAAG,gBAAgB;;CAqDzE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@purpurds/autocomplete",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.15.1",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"main": "./dist/autocomplete.cjs.js",
|
|
6
6
|
"types": "./dist/autocomplete.d.ts",
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
"source": "src/autocomplete.tsx",
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"classnames": "~2.5.0",
|
|
18
|
-
"@purpurds/
|
|
19
|
-
"@purpurds/
|
|
20
|
-
"@purpurds/
|
|
21
|
-
"@purpurds/
|
|
18
|
+
"@purpurds/listbox": "5.15.1",
|
|
19
|
+
"@purpurds/icon": "5.15.1",
|
|
20
|
+
"@purpurds/paragraph": "5.15.1",
|
|
21
|
+
"@purpurds/tokens": "5.15.1",
|
|
22
|
+
"@purpurds/text-field": "5.15.1"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@rushstack/eslint-patch": "~1.10.0",
|
|
@@ -44,10 +45,10 @@
|
|
|
44
45
|
"typescript": "^5.5.4",
|
|
45
46
|
"vite": "5.3.4",
|
|
46
47
|
"vitest": "~1.5.0",
|
|
47
|
-
"@purpurds/button": "5.
|
|
48
|
-
"@purpurds/
|
|
49
|
-
"@purpurds/search-field": "5.
|
|
50
|
-
"@purpurds/
|
|
48
|
+
"@purpurds/button": "5.15.1",
|
|
49
|
+
"@purpurds/component-rig": "1.0.0",
|
|
50
|
+
"@purpurds/search-field": "5.15.1",
|
|
51
|
+
"@purpurds/icon": "5.15.1"
|
|
51
52
|
},
|
|
52
53
|
"scripts": {
|
|
53
54
|
"build:dev": "vite",
|
|
@@ -7,6 +7,7 @@ import type { Meta, StoryObj } from "@storybook/react";
|
|
|
7
7
|
|
|
8
8
|
import "@purpurds/icon/styles";
|
|
9
9
|
import "@purpurds/button/styles";
|
|
10
|
+
import "@purpurds/listbox/styles";
|
|
10
11
|
import "@purpurds/search-field/styles";
|
|
11
12
|
import "@purpurds/text-field/styles";
|
|
12
13
|
import { Autocomplete } from "./autocomplete";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { TextField } from "@purpurds/text-field";
|
|
3
3
|
import * as matchers from "@testing-library/jest-dom/matchers";
|
|
4
|
-
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
+
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
5
5
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
6
6
|
|
|
7
7
|
import { Autocomplete } from "./autocomplete";
|
|
@@ -593,7 +593,7 @@ describe("B2xAutocomplete", () => {
|
|
|
593
593
|
expect(input.value).toEqual("random text");
|
|
594
594
|
});
|
|
595
595
|
|
|
596
|
-
it("should reset input value on blur for combobox with no selected option", () => {
|
|
596
|
+
it("should reset input value on blur for combobox with no selected option", async () => {
|
|
597
597
|
const onSelectMock = vi.fn();
|
|
598
598
|
render(
|
|
599
599
|
<Autocomplete
|
|
@@ -613,10 +613,12 @@ describe("B2xAutocomplete", () => {
|
|
|
613
613
|
fireEvent.change(input, { target: { value: "random text" } });
|
|
614
614
|
expect(input.value).toEqual("random text");
|
|
615
615
|
fireEvent.blur(input);
|
|
616
|
-
|
|
616
|
+
await waitFor(() => {
|
|
617
|
+
expect(input.value).toEqual("");
|
|
618
|
+
});
|
|
617
619
|
});
|
|
618
620
|
|
|
619
|
-
it("should reset input value on blur for combobox with selected option", () => {
|
|
621
|
+
it("should reset input value on blur for combobox with selected option", async () => {
|
|
620
622
|
const onSelectMock = vi.fn();
|
|
621
623
|
render(
|
|
622
624
|
<Autocomplete
|
|
@@ -637,6 +639,8 @@ describe("B2xAutocomplete", () => {
|
|
|
637
639
|
fireEvent.change(input, { target: { value: "random text" } });
|
|
638
640
|
expect(input.value).toEqual("random text");
|
|
639
641
|
fireEvent.blur(input);
|
|
640
|
-
|
|
642
|
+
await waitFor(() => {
|
|
643
|
+
expect(input.value).toEqual(options[0].label);
|
|
644
|
+
});
|
|
641
645
|
});
|
|
642
646
|
});
|
package/src/autocomplete.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ComponentPropsWithRef, ForwardedRef, ReactNode } from "react";
|
|
2
2
|
import React, { cloneElement, forwardRef } from "react";
|
|
3
3
|
import { IconChevronDown } from "@purpurds/icon";
|
|
4
|
+
import { Listbox } from "@purpurds/listbox";
|
|
4
5
|
import { isTextField } from "@purpurds/text-field";
|
|
5
6
|
import c from "classnames/bind";
|
|
6
7
|
|
|
7
8
|
import styles from "./autocomplete.module.scss";
|
|
8
|
-
import * as ListBox from "./listbox";
|
|
9
9
|
import type { Option, UseAutocompleteOptions } from "./useAutocomplete";
|
|
10
10
|
import { useAutocomplete } from "./useAutocomplete";
|
|
11
11
|
import type { Prettify } from "./utils";
|
|
@@ -48,9 +48,9 @@ const AutocompleteComponent = <T extends Option>(
|
|
|
48
48
|
const { key, ...listboxItemProps } = getListBoxItemProps(option, index);
|
|
49
49
|
|
|
50
50
|
return (
|
|
51
|
-
<
|
|
51
|
+
<Listbox.Item key={key} {...listboxItemProps}>
|
|
52
52
|
{renderOption ? renderOption?.(option) : option.label}
|
|
53
|
-
</
|
|
53
|
+
</Listbox.Item>
|
|
54
54
|
);
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -101,13 +101,13 @@ const AutocompleteComponent = <T extends Option>(
|
|
|
101
101
|
<div id={id} ref={setRootRef} className={cx([className, rootClassName])}>
|
|
102
102
|
{getInputComponent()}
|
|
103
103
|
{showListbox && (
|
|
104
|
-
<
|
|
104
|
+
<Listbox {...listboxProps} className={cx(`${rootClassName}__listbox`)}>
|
|
105
105
|
{!optionsToShow.length ? (
|
|
106
|
-
<
|
|
106
|
+
<Listbox.Item noninteractive>{noOptionsText}</Listbox.Item>
|
|
107
107
|
) : (
|
|
108
108
|
optionsToShow.filter((option): option is T => !!option).map(renderListboxItem)
|
|
109
109
|
)}
|
|
110
|
-
</
|
|
110
|
+
</Listbox>
|
|
111
111
|
)}
|
|
112
112
|
</div>
|
|
113
113
|
);
|
package/src/useAutocomplete.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentPropsWithRef, CSSProperties, ReactNode } from "react";
|
|
2
2
|
import { useRef, useState } from "react";
|
|
3
|
+
import type { ListboxItemProps, ListboxProps } from "@purpurds/listbox";
|
|
3
4
|
|
|
4
|
-
import type { ListboxItemProps, ListboxProps } from "./listbox";
|
|
5
5
|
import { useMutableRefObject, useOnClickOutside } from "./utils";
|
|
6
6
|
|
|
7
7
|
export type Option = {
|
|
@@ -245,7 +245,16 @@ export const useAutocomplete = <T extends Option>({
|
|
|
245
245
|
|
|
246
246
|
const handleOnBlur = () => {
|
|
247
247
|
if (combobox) {
|
|
248
|
-
|
|
248
|
+
// Use a timeout to allow click events on the listbox to fire before this check
|
|
249
|
+
setTimeout(() => {
|
|
250
|
+
// If the blur happened due to a click inside the listbox, don't reset the value
|
|
251
|
+
if (
|
|
252
|
+
!inputRef.current?.contains(document.activeElement) &&
|
|
253
|
+
!listboxRef.current?.contains(document.activeElement)
|
|
254
|
+
) {
|
|
255
|
+
populateInputField(selectedOption ? selectedOption.label : "");
|
|
256
|
+
}
|
|
257
|
+
});
|
|
249
258
|
}
|
|
250
259
|
};
|
|
251
260
|
|
package/dist/listbox.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ComponentPropsWithRef, default as React } from 'react';
|
|
2
|
-
|
|
3
|
-
export * from './useAutocomplete';
|
|
4
|
-
type ListboxProps = Omit<ComponentPropsWithRef<"ul">, "role"> & {
|
|
5
|
-
"data-testid"?: string;
|
|
6
|
-
"aria-label": NonNullable<ComponentPropsWithRef<"ul">["aria-label"]>;
|
|
7
|
-
"aria-expanded": NonNullable<ComponentPropsWithRef<"ul">["aria-expanded"]>;
|
|
8
|
-
};
|
|
9
|
-
type ListboxItemProps = Omit<ComponentPropsWithRef<"li">, "role"> & {
|
|
10
|
-
"data-testid"?: string;
|
|
11
|
-
highlighted?: boolean;
|
|
12
|
-
hovered?: boolean;
|
|
13
|
-
key?: string;
|
|
14
|
-
selected?: boolean;
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
noninteractive?: boolean;
|
|
17
|
-
};
|
|
18
|
-
declare const Root: React.ForwardRefExoticComponent<Omit<ListboxProps, "ref"> & React.RefAttributes<HTMLUListElement>>;
|
|
19
|
-
declare const Item: React.ForwardRefExoticComponent<Omit<ListboxItemProps, "ref"> & React.RefAttributes<HTMLLIElement>>;
|
|
20
|
-
export { Item, Root };
|
|
21
|
-
export type { ListboxItemProps, ListboxProps };
|
|
22
|
-
//# sourceMappingURL=listbox.d.ts.map
|
package/dist/listbox.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"listbox.d.ts","sourceRoot":"","sources":["../src/listbox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EAKtB,MAAM,OAAO,CAAC;AACf,OAAO,KAA+C,MAAM,OAAO,CAAC;AAOpE,cAAc,mBAAmB,CAAC;AAKlC,KAAK,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,GAAG;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,WAAW,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACrE,eAAe,EAAE,WAAW,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;CAC5E,CAAC;AAgBF,KAAK,gBAAgB,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,GAAG;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AA0CF,QAAA,MAAM,IAAI,oGAAU,CAAC;AACrB,QAAA,MAAM,IAAI,qGAAc,CAAC;AAEzB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACtB,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,CAAC"}
|
package/src/listbox.module.scss
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
.purpur-listbox {
|
|
2
|
-
padding: 0;
|
|
3
|
-
margin: 0;
|
|
4
|
-
width: 100%;
|
|
5
|
-
list-style-type: none;
|
|
6
|
-
border: var(--purpur-border-width-xs) solid var(--purpur-color-border-interactive-subtle);
|
|
7
|
-
border-radius: var(--purpur-border-radius-sm);
|
|
8
|
-
color: var(--purpur-color-brand-off-black);
|
|
9
|
-
width: 100%;
|
|
10
|
-
background-color: var(--purpur-color-brand-white);
|
|
11
|
-
max-height: calc(2 * var(--purpur-spacing-1200));
|
|
12
|
-
overflow-y: scroll;
|
|
13
|
-
box-sizing: border-box;
|
|
14
|
-
|
|
15
|
-
&-item {
|
|
16
|
-
$listboxItemRoot: &;
|
|
17
|
-
|
|
18
|
-
cursor: pointer;
|
|
19
|
-
list-style: none;
|
|
20
|
-
padding: var(--purpur-spacing-150);
|
|
21
|
-
border: var(--purpur-border-width-xs) solid transparent;
|
|
22
|
-
cursor: pointer;
|
|
23
|
-
max-width: 100%;
|
|
24
|
-
word-break: break-word;
|
|
25
|
-
transition: background var(--purpur-motion-duration-150) ease;
|
|
26
|
-
display: flex;
|
|
27
|
-
justify-content: space-between;
|
|
28
|
-
align-items: center;
|
|
29
|
-
gap: var(--purpur-spacing-100);
|
|
30
|
-
|
|
31
|
-
&--hovered {
|
|
32
|
-
/* Enable only on non-touch devices */
|
|
33
|
-
@media (hover: hover) and (pointer: fine) {
|
|
34
|
-
background: var(--purpur-color-background-interactive-transparent-hover);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
&--highlighted {
|
|
39
|
-
outline: var(--purpur-border-width-sm) solid var(--purpur-color-border-interactive-focus);
|
|
40
|
-
outline-offset: calc(-1 * var(--purpur-border-width-sm));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
&:active:not(#{$listboxItemRoot}--noninteractive) {
|
|
44
|
-
background: var(--purpur-color-background-interactive-transparent-active);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
&--disabled {
|
|
48
|
-
color: var(--purpur-color-text-weak);
|
|
49
|
-
cursor: default;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
&--noninteractive {
|
|
53
|
-
cursor: default;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
&__icon {
|
|
57
|
-
color: var(--purpur-color-text-interactive-selected);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
package/src/listbox.tsx
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ComponentPropsWithRef,
|
|
3
|
-
ForwardedRef,
|
|
4
|
-
ReactElement,
|
|
5
|
-
ReactNode,
|
|
6
|
-
ReactPortal,
|
|
7
|
-
} from "react";
|
|
8
|
-
import React, { Children, forwardRef, isValidElement } from "react";
|
|
9
|
-
import { checkmark, Icon } from "@purpurds/icon";
|
|
10
|
-
import { Paragraph } from "@purpurds/paragraph";
|
|
11
|
-
import c from "classnames/bind";
|
|
12
|
-
|
|
13
|
-
import styles from "./listbox.module.scss";
|
|
14
|
-
|
|
15
|
-
export * from "./useAutocomplete";
|
|
16
|
-
const cx = c.bind(styles);
|
|
17
|
-
|
|
18
|
-
const rootClassName = "purpur-listbox";
|
|
19
|
-
|
|
20
|
-
type ListboxProps = Omit<ComponentPropsWithRef<"ul">, "role"> & {
|
|
21
|
-
"data-testid"?: string;
|
|
22
|
-
"aria-label": NonNullable<ComponentPropsWithRef<"ul">["aria-label"]>;
|
|
23
|
-
"aria-expanded": NonNullable<ComponentPropsWithRef<"ul">["aria-expanded"]>;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const Listbox = forwardRef(
|
|
27
|
-
({ children, ...listboxProps }: ListboxProps, ref: ForwardedRef<HTMLUListElement>) => (
|
|
28
|
-
<ul
|
|
29
|
-
{...listboxProps}
|
|
30
|
-
ref={ref}
|
|
31
|
-
className={cx(rootClassName, listboxProps.className)}
|
|
32
|
-
role="listbox"
|
|
33
|
-
>
|
|
34
|
-
{Children.toArray(children).filter(isListboxItem)}
|
|
35
|
-
</ul>
|
|
36
|
-
)
|
|
37
|
-
);
|
|
38
|
-
Listbox.displayName = "ListBox";
|
|
39
|
-
|
|
40
|
-
type ListboxItemProps = Omit<ComponentPropsWithRef<"li">, "role"> & {
|
|
41
|
-
"data-testid"?: string;
|
|
42
|
-
highlighted?: boolean;
|
|
43
|
-
hovered?: boolean;
|
|
44
|
-
key?: string;
|
|
45
|
-
selected?: boolean;
|
|
46
|
-
disabled?: boolean;
|
|
47
|
-
noninteractive?: boolean;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const ListboxItem = forwardRef((props: ListboxItemProps, ref: ForwardedRef<HTMLLIElement>) => {
|
|
51
|
-
const { disabled, highlighted, hovered, selected, children, noninteractive, ...liProps } = props;
|
|
52
|
-
const className = cx(`${rootClassName}-item`, liProps.className, {
|
|
53
|
-
[`${rootClassName}-item--highlighted`]: highlighted,
|
|
54
|
-
[`${rootClassName}-item--selected`]: selected,
|
|
55
|
-
[`${rootClassName}-item--hovered`]: hovered,
|
|
56
|
-
[`${rootClassName}-item--disabled`]: disabled,
|
|
57
|
-
[`${rootClassName}-item--noninteractive`]: noninteractive,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<li
|
|
62
|
-
{...liProps}
|
|
63
|
-
ref={ref}
|
|
64
|
-
className={className}
|
|
65
|
-
aria-selected={!!selected}
|
|
66
|
-
role="option"
|
|
67
|
-
aria-disabled={!!disabled}
|
|
68
|
-
>
|
|
69
|
-
{typeof children === "string" ? <Paragraph>{children}</Paragraph> : children}
|
|
70
|
-
{selected && <Icon svg={checkmark} size="xs" className={cx(`${rootClassName}-item__icon`)} />}
|
|
71
|
-
</li>
|
|
72
|
-
);
|
|
73
|
-
});
|
|
74
|
-
ListboxItem.displayName = "ListBoxItem";
|
|
75
|
-
|
|
76
|
-
function isListboxItem(
|
|
77
|
-
child:
|
|
78
|
-
| ReactElement
|
|
79
|
-
| Iterable<ReactNode>
|
|
80
|
-
| ReactPortal
|
|
81
|
-
| string
|
|
82
|
-
| number
|
|
83
|
-
| boolean
|
|
84
|
-
| null
|
|
85
|
-
| undefined
|
|
86
|
-
): child is ReactElement<ListboxItemProps> {
|
|
87
|
-
return isValidElement<ListboxItemProps>(child) && child?.type === ListboxItem;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const Root = Listbox;
|
|
91
|
-
const Item = ListboxItem;
|
|
92
|
-
|
|
93
|
-
export { Item, Root };
|
|
94
|
-
export type { ListboxItemProps, ListboxProps };
|