Skip to content

Commit a2108d9

Browse files
Merge branch 'neolution-ch:main' into main
2 parents 814c18e + 0e34721 commit a2108d9

7 files changed

Lines changed: 91 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [3.15.0] - 2025-12-19
11+
12+
### Added
13+
14+
- support to specify `innerRef` into `StaticTypeaheadInput` and `AsyncTypeaheadInput`.
15+
1016
## [3.14.0] - 2025-12-10
1117

1218
### Added
@@ -678,7 +684,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
678684

679685
- Created package :tada:
680686

681-
[unreleased]: https://github.com/neolution-ch/react-hook-form-components/compare/3.14.0...HEAD
687+
[unreleased]: https://github.com/neolution-ch/react-hook-form-components/compare/3.15.0...HEAD
682688
[0.1.2]: https://github.com/neolution-ch/react-hook-form-components/compare/0.1.1...0.1.2
683689
[0.1.1]: https://github.com/neolution-ch/react-hook-form-components/compare/0.1.0...0.1.1
684690
[0.1.0]: https://github.com/neolution-ch/react-hook-form-components/releases/tag/0.1.0
@@ -703,6 +709,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
703709
[0.4.0]: https://github.com/neolution-ch/react-hook-form-components/compare/0.3.0...0.4.0
704710
[0.3.0]: https://github.com/neolution-ch/react-hook-form-components/compare/0.2.0...0.3.0
705711
[0.2.0]: https://github.com/neolution-ch/react-hook-form-components/releases/tag/0.2.0
712+
[3.15.0]: https://github.com/neolution-ch/react-hook-form-components/compare/3.14.0...3.15.0
706713
[3.14.0]: https://github.com/neolution-ch/react-hook-form-components/compare/3.13.1...3.14.0
707714
[3.13.1]: https://github.com/neolution-ch/react-hook-form-components/compare/3.13.0...3.13.1
708715
[3.13.0]: https://github.com/neolution-ch/react-hook-form-components/compare/3.12.0...3.13.0

cypress/cypress/component/Typeahead/AsyncTypeaheadInput.cy.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,3 +929,38 @@ it("works with fixed options excluded", () => {
929929
cy.get("input[type=submit]").click({ force: true });
930930
cy.get("@onSubmitSpy").should("be.calledOnceWith", { [name]: [] });
931931
});
932+
933+
it("innerRef works correctly", () => {
934+
const { simpleOptions } = generateOptions();
935+
const name = faker.random.alpha(10);
936+
const options = generateOptions();
937+
938+
const InputWithRef = () => {
939+
const ref = useRef<HTMLInputElement>(null);
940+
941+
return (
942+
<div className="p-4">
943+
<Form
944+
onSubmit={() => {
945+
// Nothing to do
946+
}}
947+
>
948+
<AsyncTypeaheadInput
949+
queryFn={async (query: string) => await fetchMock(options.objectOptions, query, false)}
950+
autocompleteProps={{ openOnFocus: true }}
951+
innerRef={ref}
952+
name={name}
953+
label={name}
954+
/>
955+
<button title="focus" onClick={() => ref.current?.focus()}>
956+
Focus
957+
</button>
958+
</Form>
959+
</div>
960+
);
961+
};
962+
963+
cy.mount(<InputWithRef />);
964+
cy.get("button[title=focus]").click();
965+
cy.get(`#${name}`).should("be.focused");
966+
});

cypress/cypress/component/Typeahead/StaticTypeaheadInput.cy.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { faker, Sex } from "@faker-js/faker";
44
import * as yup from "yup";
55
import { yupResolver } from "@hookform/resolvers/yup";
66
import { generateOptions } from "../../helpers/typeahead";
7-
import { useState } from "react";
7+
import { useRef, useState } from "react";
88

99
const selectOption = (name: string, text: string) => {
1010
cy.get(`#${name}`).clear();
@@ -593,3 +593,31 @@ it("works with fixed options excluded", () => {
593593
cy.get("input[type=submit]").click({ force: true });
594594
cy.get("@onSubmitSpy").should("be.calledOnceWith", { [name]: [] });
595595
});
596+
597+
it("innerRef works correctly", () => {
598+
const { simpleOptions } = generateOptions();
599+
const name = faker.random.alpha(10);
600+
601+
const InputWithRef = () => {
602+
const ref = useRef<HTMLInputElement>(null);
603+
604+
return (
605+
<div className="p-4">
606+
<Form
607+
onSubmit={() => {
608+
// Nothing to do
609+
}}
610+
>
611+
<StaticTypeaheadInput autocompleteProps={{ openOnFocus: true }} innerRef={ref} name={name} label={name} options={simpleOptions} />
612+
<button title="focus" onClick={() => ref.current?.focus()}>
613+
Focus
614+
</button>
615+
</Form>
616+
</div>
617+
);
618+
};
619+
620+
cy.mount(<InputWithRef />);
621+
cy.get("button[title=focus]").click();
622+
cy.get(`#${name}`).should("be.focused");
623+
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@neolution-ch/react-hook-form-components",
3-
"version": "3.14.0",
3+
"version": "3.15.0",
44
"description": "a collection of react hook form components to reduce boilerplate and figuring out how to integrate react hook form with other libraries",
55
"homepage": "https://neolution-ch.github.io/react-hook-form-components",
66
"repository": {

src/lib/AsyncTypeaheadInput.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ interface AsyncTypeaheadInputProps<T extends FieldValues> extends CommonTypeahea
3939
const AsyncTypeaheadInput = <T extends FieldValues>(props: AsyncTypeaheadInputProps<T>) => {
4040
const {
4141
inputRef,
42+
innerRef,
4243
multiple,
4344
disabled,
4445
variant,
@@ -227,7 +228,12 @@ const AsyncTypeaheadInput = <T extends FieldValues>(props: AsyncTypeaheadInputPr
227228
loadMoreOptions={loadMoreOptions}
228229
setPage={setPage}
229230
{...params}
230-
inputRef={(elem) => ref(elem)}
231+
inputRef={(elem) => {
232+
if (innerRef) {
233+
innerRef.current = elem as HTMLInputElement;
234+
}
235+
ref(elem);
236+
}}
231237
/>
232238
)}
233239
renderTags={createTagRenderer(fixedOptions, autocompleteProps)}

src/lib/StaticTypeaheadInput.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const StaticTypeaheadInput = <T extends FieldValues>(props: StaticTypeaheadInput
6565
autocompleteProps,
6666
fixedOptions,
6767
withFixedOptionsInValue = true,
68+
innerRef,
6869
} = props;
6970

7071
const [page, setPage] = useState(1);
@@ -192,7 +193,12 @@ const StaticTypeaheadInput = <T extends FieldValues>(props: StaticTypeaheadInput
192193
loadMoreOptions={loadMoreOptions}
193194
setPage={setPage}
194195
{...params}
195-
inputRef={(elem) => ref(elem)}
196+
inputRef={(elem) => {
197+
if (innerRef) {
198+
innerRef.current = elem as HTMLInputElement;
199+
}
200+
ref(elem);
201+
}}
196202
/>
197203
)}
198204
renderTags={createTagRenderer(fixedOptions, autocompleteProps)}

src/lib/types/Typeahead.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ReactNode, SyntheticEvent } from "react";
1+
import { MutableRefObject, ReactNode, SyntheticEvent } from "react";
22
import { FieldValues } from "react-hook-form";
33
import { CommonInputProps } from "./CommonInputProps";
44
import { LabelValueOption } from "./LabelValueOption";
@@ -24,6 +24,7 @@ interface CommonTypeaheadProps<T extends FieldValues>
2424
useBootstrapStyle?: boolean;
2525
fixedOptions?: TypeaheadOptions;
2626
withFixedOptionsInValue?: boolean;
27+
innerRef?: MutableRefObject<HTMLInputElement | null>;
2728
getOptionDisabled?: (option: TypeaheadOption) => boolean;
2829
onChange?: (selected: string | string[]) => void;
2930
onInputChange?: (text: string, reason: AutocompleteInputChangeReason) => void;
@@ -53,6 +54,7 @@ type AsyncTypeaheadAutocompleteProps = Omit<
5354
| "getOptionDisabled"
5455
| "autoSelect"
5556
| "autoHighlight"
57+
| "ref"
5658
>;
5759

5860
type StaticTypeaheadAutocompleteProps = Omit<
@@ -76,6 +78,7 @@ type StaticTypeaheadAutocompleteProps = Omit<
7678
| "onChange"
7779
| "autoSelect"
7880
| "autoHighlight"
81+
| "ref"
7982
>;
8083

8184
export { CommonTypeaheadProps, AsyncTypeaheadAutocompleteProps, StaticTypeaheadAutocompleteProps };

0 commit comments

Comments
 (0)