From 022f2a041d0514db190624803a1ea535c7a061d8 Mon Sep 17 00:00:00 2001 From: Dmytro Kirpa Date: Tue, 3 Mar 2026 08:15:39 +0100 Subject: [PATCH 1/3] feat(react-input): add useInputBase_unstable hook Adds InputBaseProps, InputBaseState types and useInputBase_unstable hook to the react-input package. The base hook handles controlled/uncontrolled value state, onChange handling, and slot structure (root span, input, contentBefore, contentAfter) without design-specific props (appearance, size). The styled useInput_unstable hook is refactored to call the base hook and spread its results. Co-Authored-By: Claude Sonnet 4.6 --- .../src/components/Input/Input.types.ts | 13 ++++++++- .../library/src/components/Input/index.ts | 4 +-- .../library/src/components/Input/useInput.ts | 29 +++++++++++++++---- .../react-input/library/src/index.ts | 12 +++++++- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/packages/react-components/react-input/library/src/components/Input/Input.types.ts b/packages/react-components/react-input/library/src/components/Input/Input.types.ts index 2afe13a355f8c4..3b91de4697c812 100644 --- a/packages/react-components/react-input/library/src/components/Input/Input.types.ts +++ b/packages/react-components/react-input/library/src/components/Input/Input.types.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; +import type { ComponentProps, ComponentState, DistributiveOmit, Slot } from '@fluentui/react-utilities'; export type InputSlots = { /** @@ -106,11 +106,22 @@ export type InputProps = Omit< | 'week'; }; +/** + * Input props without design-specific props (appearance, size). + * Use this when building a base input that is unstyled or uses a custom design system. + */ +export type InputBaseProps = DistributiveOmit; + /** * State used in rendering Input. */ export type InputState = Required> & ComponentState; +/** + * Input state without design-specific state (appearance, size). + */ +export type InputBaseState = DistributiveOmit; + /** * Data passed to the `onChange` callback when a user changes the input's value. */ diff --git a/packages/react-components/react-input/library/src/components/Input/index.ts b/packages/react-components/react-input/library/src/components/Input/index.ts index d4ee29a7f63653..843a8d1d4060bf 100644 --- a/packages/react-components/react-input/library/src/components/Input/index.ts +++ b/packages/react-components/react-input/library/src/components/Input/index.ts @@ -1,5 +1,5 @@ export { Input } from './Input'; -export type { InputOnChangeData, InputProps, InputSlots, InputState } from './Input.types'; +export type { InputBaseProps, InputBaseState, InputOnChangeData, InputProps, InputSlots, InputState } from './Input.types'; export { renderInput_unstable } from './renderInput'; -export { useInput_unstable } from './useInput'; +export { useInput_unstable, useInputBase_unstable } from './useInput'; export { inputClassNames, useInputStyles_unstable } from './useInputStyles.styles'; diff --git a/packages/react-components/react-input/library/src/components/Input/useInput.ts b/packages/react-components/react-input/library/src/components/Input/useInput.ts index 3436ec5f1333d4..d93522375ee81a 100644 --- a/packages/react-components/react-input/library/src/components/Input/useInput.ts +++ b/packages/react-components/react-input/library/src/components/Input/useInput.ts @@ -3,7 +3,7 @@ import * as React from 'react'; import { useFieldControlProps_unstable } from '@fluentui/react-field'; import { getPartitionedNativeProps, useControllableState, useEventCallback, slot } from '@fluentui/react-utilities'; -import type { InputProps, InputState } from './Input.types'; +import type { InputBaseProps, InputBaseState, InputProps, InputState } from './Input.types'; import { useOverrides_unstable as useOverrides } from '@fluentui/react-shared-contexts'; /** @@ -20,7 +20,7 @@ export const useInput_unstable = (props: InputProps, ref: React.Ref): InputBaseState => { + const { onChange } = props; + const [value, setValue] = useControllableState({ state: props.value, defaultState: props.defaultValue, @@ -42,12 +61,10 @@ export const useInput_unstable = (props: InputProps, ref: React.Ref Date: Tue, 3 Mar 2026 12:01:50 +0100 Subject: [PATCH 2/3] change file --- ...i-react-input-e2a5a63e-40cf-40e8-a33f-b83b14c0058b.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-input-e2a5a63e-40cf-40e8-a33f-b83b14c0058b.json diff --git a/change/@fluentui-react-input-e2a5a63e-40cf-40e8-a33f-b83b14c0058b.json b/change/@fluentui-react-input-e2a5a63e-40cf-40e8-a33f-b83b14c0058b.json new file mode 100644 index 00000000000000..24c73c90f153fe --- /dev/null +++ b/change/@fluentui-react-input-e2a5a63e-40cf-40e8-a33f-b83b14c0058b.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: add base hooks for Input", + "packageName": "@fluentui/react-input", + "email": "dmytrokirpa@microsoft.com", + "dependentChangeType": "patch" +} From fe74c41b639512064ccee10c641140912636e742 Mon Sep 17 00:00:00 2001 From: Dmytro Kirpa Date: Thu, 5 Mar 2026 13:38:48 +0100 Subject: [PATCH 3/3] chore: fix formatting and lint in react-input Co-Authored-By: Claude Sonnet 4.6 --- .../react-input/library/src/components/Input/index.ts | 9 ++++++++- .../react-components/react-input/library/src/index.ts | 8 +------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/react-components/react-input/library/src/components/Input/index.ts b/packages/react-components/react-input/library/src/components/Input/index.ts index 843a8d1d4060bf..f1d4e289e499ab 100644 --- a/packages/react-components/react-input/library/src/components/Input/index.ts +++ b/packages/react-components/react-input/library/src/components/Input/index.ts @@ -1,5 +1,12 @@ export { Input } from './Input'; -export type { InputBaseProps, InputBaseState, InputOnChangeData, InputProps, InputSlots, InputState } from './Input.types'; +export type { + InputBaseProps, + InputBaseState, + InputOnChangeData, + InputProps, + InputSlots, + InputState, +} from './Input.types'; export { renderInput_unstable } from './renderInput'; export { useInput_unstable, useInputBase_unstable } from './useInput'; export { inputClassNames, useInputStyles_unstable } from './useInputStyles.styles'; diff --git a/packages/react-components/react-input/library/src/index.ts b/packages/react-components/react-input/library/src/index.ts index 29d34a8e948727..7aecaf095b228a 100644 --- a/packages/react-components/react-input/library/src/index.ts +++ b/packages/react-components/react-input/library/src/index.ts @@ -1,10 +1,4 @@ -export { - Input, - inputClassNames, - renderInput_unstable, - useInputStyles_unstable, - useInput_unstable, -} from './Input'; +export { Input, inputClassNames, renderInput_unstable, useInputStyles_unstable, useInput_unstable } from './Input'; export type { InputOnChangeData, InputProps, InputSlots, InputState } from './Input'; // Experimental APIs - will be uncommented in the experimental release branch