'use client'; import * as React from 'react'; import { useEventCallback, useControllableState, getIntrinsicElementProps, slot } from '@fluentui/react-utilities'; import { useArrowNavigationGroup } from '@fluentui/react-tabster'; /** * Create the state required to render Toolbar. * * The returned state can be modified with hooks such as useToolbarStyles_unstable, * before being passed to renderToolbar_unstable. * * @param props - props from this instance of Toolbar * @param ref - reference to root HTMLElement of Toolbar */ export const useToolbar_unstable = (props, ref)=>{ const { size = 'medium' } = props; const state = useToolbarBase_unstable(props, ref); const arrowNavigationProps = useToolbarArrowNavigationProps_unstable(); return { size, ...state, root: { ...state.root, ...arrowNavigationProps } }; }; /** * Base hook that builds Toolbar state for behavior and structure only. * It does not add arrow key navigation, which is handled by `useToolbar_unstable`. * * @internal * @param props - Props for this Toolbar instance. * @param ref - Ref to the root HTMLElement. */ export const useToolbarBase_unstable = (props, ref)=>{ const { vertical = false } = props; const initialState = { vertical, // TODO add appropriate props/defaults components: { // TODO add each slot's element type or component root: 'div' }, // TODO add appropriate slots, for example: // mySlot: resolveShorthand(props.mySlot), root: slot.always(getIntrinsicElementProps('div', { role: 'toolbar', ref: ref, ...vertical && { 'aria-orientation': 'vertical' }, ...props }), { elementType: 'div' }) }; const [checkedValues, onCheckedValueChange] = useToolbarSelectableState({ checkedValues: props.checkedValues, defaultCheckedValues: props.defaultCheckedValues, onCheckedValueChange: props.onCheckedValueChange }); const handleToggleButton = useEventCallback((e, name, value, checked)=>{ if (name && value) { const checkedItems = (checkedValues === null || checkedValues === void 0 ? void 0 : checkedValues[name]) || []; const newCheckedItems = [ ...checkedItems ]; if (checked) { newCheckedItems.splice(newCheckedItems.indexOf(value), 1); } else { newCheckedItems.push(value); } onCheckedValueChange === null || onCheckedValueChange === void 0 ? void 0 : onCheckedValueChange(e, { name, checkedItems: newCheckedItems }); } }); const handleRadio = useEventCallback((e, name, value, checked)=>{ if (name && value) { onCheckedValueChange === null || onCheckedValueChange === void 0 ? void 0 : onCheckedValueChange(e, { name, checkedItems: [ value ] }); } }); return { ...initialState, handleToggleButton, handleRadio, checkedValues: checkedValues !== null && checkedValues !== void 0 ? checkedValues : {} }; }; /** * Adds appropriate state values and handlers for selectable items * i.e checkboxes and radios */ const useToolbarSelectableState = (state)=>{ const [checkedValues, setCheckedValues] = useControllableState({ state: state.checkedValues, defaultState: state.defaultCheckedValues, initialState: {} }); const { onCheckedValueChange: onCheckedValueChangeOriginal } = state; const onCheckedValueChange = useEventCallback((e, { name, checkedItems })=>{ if (onCheckedValueChangeOriginal) { onCheckedValueChangeOriginal(e, { name, checkedItems }); } setCheckedValues((s)=>{ return s ? { ...s, [name]: checkedItems } : { [name]: checkedItems }; }); }); return [ checkedValues, onCheckedValueChange ]; }; /** * Hook to add arrow navigation props to the Toolbar. * * @internal * @returns - Tabster DOM attributes for arrow navigation */ export const useToolbarArrowNavigationProps_unstable = ()=>{ return useArrowNavigationGroup({ circular: true, axis: 'both' }); };