Skip to content

Commit

Permalink
fix: honor disabled prop in InputSearch list item
Browse files Browse the repository at this point in the history
  • Loading branch information
wp-aberg committed Dec 11, 2024
1 parent f4697d5 commit 62f88ec
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
22 changes: 19 additions & 3 deletions packages/kit/src/input-search/InputSearchListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { Item } from "react-stately";
import { useOption } from "react-aria";
import { styled, theme } from "../theme";
import { InputSearchContext } from "./InputSearchRoot";

import type { Node, ListState, ComboBoxState } from "react-stately";

Expand Down Expand Up @@ -75,6 +76,24 @@ interface ListItemProps {
}

export const ListItem = ({ item, state }: ListItemProps) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { children, textValue, disabled, ...itemProps } = item.props;

const { setDisabledKeys } = React.useContext(InputSearchContext);
React.useEffect(() => {
if (disabled && !state.disabledKeys.has(item.key)) {
setDisabledKeys((prev) => {
if (prev) {
const next = new Set(prev);
next.add(item.key);
return next;
} else {
return new Set([item.key]);
}
});
}
}, [disabled, setDisabledKeys, state.disabledKeys]);

const ref = React.useRef<HTMLLIElement>(null);
const { optionProps, isDisabled, isSelected, isFocused } = useOption(
{
Expand All @@ -97,9 +116,6 @@ export const ListItem = ({ item, state }: ListItemProps) => {
);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { children, textValue, ...itemProps } = item.props;

return (
<StyledListItem
{...itemProps}
Expand Down
8 changes: 7 additions & 1 deletion packages/kit/src/input-search/InputSearchRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useComboBox } from "react-aria";
import { styled, theme } from "../theme";

import type * as WPDS from "../theme";
import type { ComboBoxState } from "react-stately";
import type { ComboBoxState, Key } from "react-stately";
import type { AriaListBoxOptions } from "react-aria";
import type { CollectionChildren } from "@react-types/shared";

Expand All @@ -20,6 +20,9 @@ type InputSearchContextProps = {
setCollectionChildren: React.Dispatch<
React.SetStateAction<CollectionChildren<object> | undefined>
>;
setDisabledKeys: React.Dispatch<
React.SetStateAction<Iterable<Key> | undefined>
>;
isDisabled?: boolean;
setUsePortal: React.Dispatch<React.SetStateAction<boolean | undefined>>;
setPortalDomNode: React.Dispatch<React.SetStateAction<HTMLElement | null>>;
Expand Down Expand Up @@ -76,9 +79,11 @@ export const InputSearchRoot = ({
}: InputSearchRootProps) => {
const [collectionChildren, setCollectionChildren] =
React.useState<CollectionChildren<object>>();
const [disabledKeys, setDisabledKeys] = React.useState<Iterable<Key>>();

const state = useComboBoxState({
children: collectionChildren,
disabledKeys,
allowsCustomValue: true,
allowsEmptyCollection: true,
menuTrigger: openOnFocus ? "focus" : "input",
Expand Down Expand Up @@ -132,6 +137,7 @@ export const InputSearchRoot = ({
inputProps,
listBoxProps,
setCollectionChildren,
setDisabledKeys,
setUsePortal,
setPortalDomNode,
isDisabled: disabled,
Expand Down
28 changes: 28 additions & 0 deletions packages/kit/src/input-search/play.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,34 @@ export const Grouping = {
},
};

const DisabledTemplate: StoryFn<typeof InputSearch.Root> = (args) => {
return (
<Box css={{ width: "275px", height: "340px" }}>
<InputSearch.Root {...args} aria-label="Example-Search" openOnFocus>
<InputSearch.Input name="fruit" id="fruit" />
<InputSearch.Popover>
<InputSearch.List>
<InputSearch.ListItem value="Apple" />
<InputSearch.ListItem value="Banana" disabled />
<InputSearch.ListItem value="Orange" />
<InputSearch.ListItem value="Kiwi" />
<InputSearch.ListItem value="Pineapple" />
</InputSearch.List>
</InputSearch.Popover>
</InputSearch.Root>
</Box>
);
};

export const Disabled = {
render: DisabledTemplate,
args: {},

parameters: {
chromatic: { disableSnapshot: true },
},
};

const ScrollTemplate: StoryFn<typeof InputSearch.Root> = (args) => {
return (
<Box css={{ width: "275px", height: "340px", marginBlockStart: "700px" }}>
Expand Down

0 comments on commit 62f88ec

Please sign in to comment.