Private
Public Access
1
0
Files
power-apps-codeapps-blog-part2/node_modules/@fluentui/react-spinner/lib/components/Spinner/useSpinner.js

94 lines
3.1 KiB
JavaScript

'use client';
import * as React from 'react';
import { getIntrinsicElementProps, useId, useTimeout, slot } from '@fluentui/react-utilities';
import { Label } from '@fluentui/react-label';
import { useSpinnerContext } from '../../contexts/SpinnerContext';
/**
* Create the state required to render Spinner.
*
* The returned state can be modified with hooks such as useSpinnerStyles_unstable,
* before being passed to renderSpinner_unstable.
*
* @param props - props from this instance of Spinner
* @param ref - reference to root HTMLElement of Spinner
*/ export const useSpinner_unstable = (props, ref)=>{
const { size: contextSize } = useSpinnerContext();
const { appearance = 'primary', size = contextSize !== null && contextSize !== void 0 ? contextSize : 'medium', ...baseProps } = props;
const baseState = useSpinnerBase_unstable(baseProps, ref);
return {
...baseState,
appearance,
size
};
};
/**
* Base hook for Spinner component, which manages state related to slots structure, ARIA attributes,
* and delay-based visibility logic.
*
* @param props - User provided props to the Spinner component.
* @param ref - User provided ref to be passed to the Spinner component.
*/ export const useSpinnerBase_unstable = (props, ref)=>{
const { delay = 0, labelPosition = 'after' } = props;
const baseId = useId('spinner');
const { role = 'progressbar', ...rest } = props;
const nativeRoot = slot.always(getIntrinsicElementProps('div', {
// FIXME:
// `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`
// but since it would be a breaking change to fix it, we are casting ref to it's proper type
ref: ref,
role,
...rest
}), {
elementType: 'div'
});
const [isShownAfterDelay, setIsShownAfterDelay] = React.useState(false);
const [setDelayTimeout, clearDelayTimeout] = useTimeout();
React.useEffect(()=>{
if (delay <= 0) {
return;
}
setDelayTimeout(()=>{
setIsShownAfterDelay(true);
}, delay);
return ()=>{
clearDelayTimeout();
};
}, [
setDelayTimeout,
clearDelayTimeout,
delay
]);
const labelShorthand = slot.optional(props.label, {
defaultProps: {
id: baseId
},
renderByDefault: false,
elementType: Label
});
const spinnerShortHand = slot.optional(props.spinner, {
renderByDefault: true,
elementType: 'span'
});
if (labelShorthand && nativeRoot && !nativeRoot['aria-labelledby']) {
nativeRoot['aria-labelledby'] = labelShorthand.id;
}
const state = {
delay,
labelPosition,
shouldRenderSpinner: !delay || isShownAfterDelay,
components: {
root: 'div',
spinner: 'span',
spinnerTail: 'span',
label: Label
},
root: nativeRoot,
spinner: spinnerShortHand,
spinnerTail: slot.always(props.spinnerTail, {
elementType: 'span'
}),
label: labelShorthand
};
return state;
};