Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/input-group/input-group-list-addon.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { OpenChangeReason } from "@floating-ui/react";
import findIndex from "lodash/findIndex";
import isEqual from "lodash/isEqual";
import React, { useEffect, useRef, useState } from "react";
import { VisuallyHidden, concatIds } from "../shared/accessibility";
import {
DropdownList,
DropdownListState,
ExpandableElement,
useDropdownListState,
} from "../shared/dropdown-list-v2";
import { ElementWithDropdown } from "../shared/dropdown-wrapper";
import {
Expand Down Expand Up @@ -76,6 +79,12 @@ export const Component = <T, V>(
const [selected, setSelected] = useState<T | undefined>(selectedOption);
const [showOptions, setShowOptions] = useState<boolean>(false);
const [focused, setFocused] = useState<boolean>(false);
const { context, setSelectedIndex, onKeyDown } = useDropdownListState({
options,
disabled,
readOnly,
onOpenChange: setShowOptions,
});
const [internalId] = useState<string>(() => SimpleIdGenerator.generate());
const listboxId = `${internalId}-listbox`;
const instructionId = `${internalId}-instruction`;
Expand All @@ -90,6 +99,13 @@ export const Component = <T, V>(
// =============================================================================
useEffect(() => {
setSelected(selectedOption);
setSelectedIndex(
selectedOption
? findIndex(options, (option) => {
return isEqual(option, selectedOption);
})
: -1
);
}, [selectedOption]);

// =============================================================================
Expand Down Expand Up @@ -123,6 +139,7 @@ export const Component = <T, V>(
const handleListItemClick = (item: T, extractedValue: V) => {
selectorRef.current?.focus();
setSelected(item);
setSelectedIndex(findIndex(options, (option) => isEqual(option, item)));
setShowOptions(false);
triggerOptionDisplayCallback(false);

Expand Down Expand Up @@ -209,11 +226,12 @@ export const Component = <T, V>(
aria-labelledby={concatIds(ariaLabelledBy, comboboxLabelId)}
aria-describedby={concatIds(ariaDescribedBy, instructionId)}
aria-invalid={ariaInvalid}
onKeyDown={onKeyDown}
>
{renderSelectorContent()}
</ExpandableElement>
<VisuallyHidden id={instructionId}>
Press space to open options
Press Space or Enter to open options
</VisuallyHidden>
</div>
);
Expand Down Expand Up @@ -283,7 +301,7 @@ export const Component = <T, V>(
};

return (
<DropdownListState>
<DropdownListState context={context}>
<FieldWrapper
$focused={focused}
$disabled={disabled}
Expand Down
23 changes: 21 additions & 2 deletions src/input-multi-select/input-multi-select.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { OpenChangeReason } from "@floating-ui/react";
import findIndex from "lodash/findIndex";
import isEqual from "lodash/isEqual";
import React, { useEffect, useRef, useState } from "react";
import {
DropdownList,
DropdownListState,
ExpandableElement,
useDropdownListState,
} from "../shared/dropdown-list-v2";
import { ElementWithDropdown } from "../shared/dropdown-wrapper";
import {
Expand Down Expand Up @@ -51,7 +53,7 @@ export const InputMultiSelect = <T, V>({
dropdownZIndex,
maxSelectable,
dropdownRootNode,
dropdownWidth
dropdownWidth,
}: InputMultiSelectProps<T, V>): JSX.Element => {
// =============================================================================
// CONST, STATE
Expand All @@ -60,6 +62,12 @@ export const InputMultiSelect = <T, V>({
const [selected, setSelected] = useState<T[]>(selectedOptions || []);
const [showOptions, setShowOptions] = useState<boolean>(false);
const [focused, setFocused] = useState<boolean>(false);
const { context, onKeyDown, setSelectedIndex } = useDropdownListState({
options,
disabled,
readOnly,
onOpenChange: setShowOptions,
});
const [internalId] = useState<string>(() => SimpleIdGenerator.generate());

const nodeRef = useRef<HTMLDivElement>(null);
Expand All @@ -70,6 +78,13 @@ export const InputMultiSelect = <T, V>({
// =============================================================================
useEffect(() => {
setSelected(selectedOptions || []);
setSelectedIndex(
selectedOptions?.[0]
? findIndex(options, (option) =>
isEqual(option, selectedOptions[0])
)
: -1
);
}, [selectedOptions]);

// =============================================================================
Expand All @@ -78,9 +93,11 @@ export const InputMultiSelect = <T, V>({
const handleSelectAllClick = () => {
if ((selected && selected.length > 0) || maxSelectable) {
setSelected([]);
setSelectedIndex(-1);
performOnSelectOptions([]);
} else {
setSelected(options);
setSelectedIndex(0);
performOnSelectOptions(options);
}
};
Expand All @@ -103,6 +120,7 @@ export const InputMultiSelect = <T, V>({
}

setSelected(selectedCopy);
setSelectedIndex(findIndex(options, (option) => isEqual(option, item)));
performOnSelectOptions(selectedCopy);
};

Expand Down Expand Up @@ -231,6 +249,7 @@ export const InputMultiSelect = <T, V>({
aria-labelledby={ariaLabelledBy}
aria-describedby={ariaDescribedBy}
aria-invalid={ariaInvalid}
onKeyDown={onKeyDown}
>
{renderSelectorContent()}
</ExpandableElement>
Expand Down Expand Up @@ -270,7 +289,7 @@ export const InputMultiSelect = <T, V>({
};

return (
<DropdownListState>
<DropdownListState context={context}>
<ElementWithDropdown
enabled={!readOnly && !disabled}
isOpen={showOptions}
Expand Down
22 changes: 20 additions & 2 deletions src/input-select/input-select.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { OpenChangeReason } from "@floating-ui/react";
import findIndex from "lodash/findIndex";
import isEqual from "lodash/isEqual";
import React, { useEffect, useRef, useState } from "react";
import {
DropdownList,
DropdownListState,
ExpandableElement,
useDropdownListState,
} from "../shared/dropdown-list-v2";
import { ElementWithDropdown } from "../shared/dropdown-wrapper";
import {
Expand Down Expand Up @@ -53,14 +56,20 @@ export const InputSelect = <T, V>({
alignment,
dropdownZIndex,
dropdownRootNode,
dropdownWidth
dropdownWidth,
}: InputSelectProps<T, V>): JSX.Element => {
// =============================================================================
// CONST, STATE
// =============================================================================
const [selected, setSelected] = useState<T | undefined>(selectedOption);
const [showOptions, setShowOptions] = useState<boolean>(false);
const [focused, setFocused] = useState<boolean>(false);
const { context, setSelectedIndex, onKeyDown } = useDropdownListState({
options,
disabled,
readOnly,
onOpenChange: setShowOptions,
});
const [internalId] = useState<string>(() => SimpleIdGenerator.generate());

const nodeRef = useRef<HTMLDivElement>(null);
Expand All @@ -72,6 +81,13 @@ export const InputSelect = <T, V>({
// =============================================================================
useEffect(() => {
setSelected(selectedOption);
setSelectedIndex(
selectedOption
? findIndex(options, (option) =>
isEqual(option, selectedOption)
)
: -1
);
}, [selectedOption]);

// =============================================================================
Expand All @@ -80,6 +96,7 @@ export const InputSelect = <T, V>({
const handleListItemClick = (item: T, extractedValue: V) => {
selectorRef.current?.focus();
setSelected(item);
setSelectedIndex(findIndex(options, (option) => isEqual(option, item)));
setShowOptions(false);
triggerOptionDisplayCallback(false);

Expand Down Expand Up @@ -234,6 +251,7 @@ export const InputSelect = <T, V>({
aria-labelledby={ariaLabelledBy}
aria-describedby={ariaDescribedBy}
aria-invalid={ariaInvalid}
onKeyDown={onKeyDown}
>
{renderSelectorContent()}
</ExpandableElement>
Expand Down Expand Up @@ -270,7 +288,7 @@ export const InputSelect = <T, V>({
};

return (
<DropdownListState>
<DropdownListState context={context}>
<ElementWithDropdown
enabled={!readOnly && !disabled}
isOpen={showOptions}
Expand Down
19 changes: 14 additions & 5 deletions src/predictive-text-input/predictive-text-input.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import debounce from "lodash/debounce";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { DropdownList, DropdownListState } from "../shared/dropdown-list-v2";
import { VisuallyHidden, concatIds } from "src/shared/accessibility";
import { Input } from "../input";
import {
DropdownList,
DropdownListState,
useDropdownListState,
} from "../shared/dropdown-list-v2";
import { ItemsLoadStateType } from "../shared/dropdown-list/types";
import { ElementWithDropdown } from "../shared/dropdown-wrapper";
import { InputWrapper } from "../shared/input-wrapper/input-wrapper";
import { Input } from "../input";
import { SimpleIdGenerator } from "../util";
import { PredictiveTextInputProps } from "./types";
import { ItemsLoadStateType } from "../shared/dropdown-list/types";
import { VisuallyHidden, concatIds } from "src/shared/accessibility";

export const PredictiveTextInput = <T, V>({
className,
Expand Down Expand Up @@ -57,6 +61,11 @@ export const PredictiveTextInput = <T, V>({
);
const [isOpen, setIsOpen] = useState(false);
const [isFocused, setIsFocused] = useState(false);
const { context } = useDropdownListState({
options,
disabled,
readOnly,
});

const [internalId] = useState<string>(() => SimpleIdGenerator.generate());
const [resultAnnouncement, setResultAnnouncement] = useState<string | null>(
Expand Down Expand Up @@ -346,7 +355,7 @@ export const PredictiveTextInput = <T, V>({
};

return (
<DropdownListState>
<DropdownListState context={context}>
<ElementWithDropdown
enabled={!readOnly && !disabled}
isOpen={isOpen}
Expand Down
37 changes: 16 additions & 21 deletions src/select-histogram/select-histogram.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { useEffect, useRef, useState } from "react";
import { HistogramSlider } from "../histogram-slider";
import {
DropdownListState,
ExpandableElement,
} from "../shared/dropdown-list-v2";
import { ExpandableElement } from "../shared/dropdown-list-v2";
import {
DropdownRenderProps,
ElementWithDropdown,
Expand Down Expand Up @@ -225,22 +222,20 @@ export const SelectHistogram = ({
);

return (
<DropdownListState>
<ElementWithDropdown
enabled={!readOnly && !disabled}
isOpen={showOptions}
renderElement={renderElement}
renderDropdown={renderDropdown}
onOpen={handleOpen}
onClose={handleClose}
onDismiss={handleDismiss}
clickToToggle
offset={8}
alignment={alignment}
fitAvailableHeight
customZIndex={dropdownZIndex}
rootNode={dropdownRootNode}
/>
</DropdownListState>
<ElementWithDropdown
enabled={!readOnly && !disabled}
isOpen={showOptions}
renderElement={renderElement}
renderDropdown={renderDropdown}
onOpen={handleOpen}
onClose={handleClose}
onDismiss={handleDismiss}
clickToToggle
offset={8}
alignment={alignment}
fitAvailableHeight
customZIndex={dropdownZIndex}
rootNode={dropdownRootNode}
/>
);
};
Loading
Loading