diff --git a/change/@fluentui-react-switch-e81c15fc-676d-4d0a-9912-731bec20916c.json b/change/@fluentui-react-switch-e81c15fc-676d-4d0a-9912-731bec20916c.json new file mode 100644 index 00000000000000..9917be8d20b44d --- /dev/null +++ b/change/@fluentui-react-switch-e81c15fc-676d-4d0a-9912-731bec20916c.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "refactor: add base state hooks for Switch component", + "packageName": "@fluentui/react-switch", + "email": "copilot@github.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-switch/library/src/Switch.ts b/packages/react-components/react-switch/library/src/Switch.ts index bbdd746cfad93b..4e1341d85147bd 100644 --- a/packages/react-components/react-switch/library/src/Switch.ts +++ b/packages/react-components/react-switch/library/src/Switch.ts @@ -1,4 +1,11 @@ -export type { SwitchOnChangeData, SwitchProps, SwitchSlots, SwitchState } from './components/Switch/index'; +export type { + SwitchBaseProps, + SwitchBaseState, + SwitchOnChangeData, + SwitchProps, + SwitchSlots, + SwitchState, +} from './components/Switch/index'; export { Switch, renderSwitch_unstable, @@ -7,4 +14,5 @@ export { switchClassNames, useSwitchStyles_unstable, useSwitch_unstable, + useSwitchBase_unstable, } from './components/Switch/index'; diff --git a/packages/react-components/react-switch/library/src/components/Switch/Switch.types.ts b/packages/react-components/react-switch/library/src/components/Switch/Switch.types.ts index 152358cbcb7438..f36ec83c1806f6 100644 --- a/packages/react-components/react-switch/library/src/components/Switch/Switch.types.ts +++ b/packages/react-components/react-switch/library/src/components/Switch/Switch.types.ts @@ -79,7 +79,17 @@ export type SwitchProps = Omit< onChange?: (ev: React.ChangeEvent, data: SwitchOnChangeData) => void; }; +/** + * Switch base props, excluding design-related props like size + */ +export type SwitchBaseProps = Omit; + /** * State used in rendering Switch */ export type SwitchState = ComponentState & Required>; + +/** + * Switch base state, excluding design-related state like size + */ +export type SwitchBaseState = Omit; diff --git a/packages/react-components/react-switch/library/src/components/Switch/index.ts b/packages/react-components/react-switch/library/src/components/Switch/index.ts index 4853a54d26424c..00cbd61b9f6991 100644 --- a/packages/react-components/react-switch/library/src/components/Switch/index.ts +++ b/packages/react-components/react-switch/library/src/components/Switch/index.ts @@ -1,7 +1,14 @@ export { Switch } from './Switch'; -export type { SwitchOnChangeData, SwitchProps, SwitchSlots, SwitchState } from './Switch.types'; +export type { + SwitchBaseProps, + SwitchBaseState, + SwitchOnChangeData, + SwitchProps, + SwitchSlots, + SwitchState, +} from './Switch.types'; export { renderSwitch_unstable } from './renderSwitch'; -export { useSwitch_unstable } from './useSwitch'; +export { useSwitch_unstable, useSwitchBase_unstable } from './useSwitch'; export { // eslint-disable-next-line @typescript-eslint/no-deprecated switchClassName, diff --git a/packages/react-components/react-switch/library/src/components/Switch/useSwitch.tsx b/packages/react-components/react-switch/library/src/components/Switch/useSwitch.tsx index 36dbe57fe6227a..e3ad1dfa4b5b85 100644 --- a/packages/react-components/react-switch/library/src/components/Switch/useSwitch.tsx +++ b/packages/react-components/react-switch/library/src/components/Switch/useSwitch.tsx @@ -6,7 +6,7 @@ import { CircleFilled } from '@fluentui/react-icons'; import { Label } from '@fluentui/react-label'; import { useFocusWithin } from '@fluentui/react-tabster'; import { getPartitionedNativeProps, mergeCallbacks, useId, slot } from '@fluentui/react-utilities'; -import type { SwitchProps, SwitchState } from './Switch.types'; +import type { SwitchProps, SwitchState, SwitchBaseProps, SwitchBaseState } from './Switch.types'; /** * Create the state required to render Switch. @@ -18,15 +18,32 @@ import type { SwitchProps, SwitchState } from './Switch.types'; * @param ref - reference to `` element of Switch */ export const useSwitch_unstable = (props: SwitchProps, ref: React.Ref): SwitchState => { + const { size = 'medium', ...baseProps } = props; + + const baseState = useSwitchBase_unstable(baseProps, ref); + + return { + ...baseState, + size, + }; +}; + +/** + * Base hook for Switch component, manages state and structure common to all variants of Switch + * + * @param props - base props from this instance of Switch + * @param ref - reference to `` element of Switch + */ +export const useSwitchBase_unstable = (props: SwitchBaseProps, ref?: React.Ref): SwitchBaseState => { // Merge props from surrounding , if any props = useFieldControlProps_unstable(props, { supportsLabelFor: true, supportsRequired: true }); - const { checked, defaultChecked, disabled, labelPosition = 'after', size = 'medium', onChange, required } = props; + const { checked, defaultChecked, disabled, labelPosition = 'after', onChange, required } = props; const nativeProps = getPartitionedNativeProps({ props, primarySlotTagName: 'input', - excludedPropNames: ['checked', 'defaultChecked', 'onChange', 'size'], + excludedPropNames: ['checked', 'defaultChecked', 'onChange'], }); const id = useId('switch-', nativeProps.primary.id); @@ -49,13 +66,12 @@ export const useSwitch_unstable = (props: SwitchProps, ref: React.Ref