'use client';
import * as React from 'react';
import { useFieldControlProps_unstable } from '@fluentui/react-field';
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';
/**
* Create the state required to render Switch.
*
* The returned state can be modified with hooks such as useSwitchStyles_unstable,
* before being passed to renderSwitch_unstable.
*
* @param props - props from this instance of Switch
* @param ref - reference to `` element of Switch
*/ export const useSwitch_unstable = (props, ref)=>{
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, ref)=>{
// Merge props from surrounding , if any
props = useFieldControlProps_unstable(props, {
supportsLabelFor: true,
supportsRequired: true
});
const { checked, defaultChecked, disabled, disabledFocusable = false, labelPosition = 'after', onChange, required } = props;
const nativeProps = getPartitionedNativeProps({
props,
primarySlotTagName: 'input',
excludedPropNames: [
'checked',
'defaultChecked',
'onChange',
'disabledFocusable'
]
});
const id = useId('switch-', nativeProps.primary.id);
const root = slot.always(props.root, {
defaultProps: {
ref: useFocusWithin(),
...nativeProps.root
},
elementType: 'div'
});
const indicator = slot.always(props.indicator, {
defaultProps: {
'aria-hidden': true,
children: /*#__PURE__*/ React.createElement(CircleFilled, null)
},
elementType: 'div'
});
const input = slot.always(props.input, {
defaultProps: {
checked,
defaultChecked,
id,
ref,
role: 'switch',
type: 'checkbox',
...nativeProps.primary,
disabled: disabled && !disabledFocusable,
...disabledFocusable && {
'aria-disabled': true
}
},
elementType: 'input'
});
input.onChange = mergeCallbacks(input.onChange, (ev)=>onChange === null || onChange === void 0 ? void 0 : onChange(ev, {
checked: ev.currentTarget.checked
}));
input.onClick = mergeCallbacks(input.onClick, (ev)=>{
if (disabledFocusable) {
ev.preventDefault();
}
});
input.onKeyDown = mergeCallbacks(input.onKeyDown, (ev)=>{
if (disabledFocusable && (ev.key === ' ' || ev.key === 'Enter')) {
ev.preventDefault();
}
});
const label = slot.optional(props.label, {
defaultProps: {
disabled: disabled || disabledFocusable,
htmlFor: id,
required,
size: 'medium'
},
elementType: Label
});
return {
disabledFocusable,
labelPosition,
components: {
root: 'div',
indicator: 'div',
input: 'input',
label: Label
},
root,
indicator,
input,
label
};
};