Private
Public Access
1
0
Files
power-apps-codeapps-blog-part2/node_modules/@fluentui/react-card/lib/components/Card/useCard.js

133 lines
4.2 KiB
JavaScript

'use client';
import * as React from 'react';
import { getIntrinsicElementProps, useMergedRefs, slot } from '@fluentui/react-utilities';
import { useFocusableGroup, useFocusWithin } from '@fluentui/react-tabster';
import { useCardSelectable } from './useCardSelectable';
import { cardContextDefaultValue } from './CardContext';
const focusMap = {
off: undefined,
'no-tab': 'limited-trap-focus',
'tab-exit': 'limited',
'tab-only': 'unlimited'
};
/**
* Create the state for interactive cards.
*
* This internal hook defines if the card is interactive
* and control focus properties based on that.
*
* @param props - props from this instance of Card
*/ const useCardInteractive = ({ focusMode: initialFocusMode, disabled = false, ...props })=>{
const interactive = [
'onClick',
'onDoubleClick',
'onMouseUp',
'onMouseDown',
'onPointerUp',
'onPointerDown',
'onTouchStart',
'onTouchEnd',
'onDragStart',
'onDragEnd'
].some((prop)=>props[prop]);
// default focusMode to tab-only when interactive, and off when not
const focusMode = initialFocusMode !== null && initialFocusMode !== void 0 ? initialFocusMode : interactive ? 'no-tab' : 'off';
const groupperAttrs = useFocusableGroup({
tabBehavior: focusMap[focusMode]
});
if (disabled) {
return {
interactive: false,
focusAttributes: null
};
}
if (focusMode === 'off') {
return {
interactive,
focusAttributes: null
};
}
return {
interactive,
focusAttributes: {
...groupperAttrs,
tabIndex: 0
}
};
};
/**
* Create the state required to render Card.
*
* The returned state can be modified with hooks such as useCardStyles_unstable,
* before being passed to renderCard_unstable.
*
* @param props - props from this instance of Card
* @param ref - reference to the root element of Card
*/ export const useCard_unstable = (props, ref)=>{
const { appearance = 'filled', orientation = 'vertical', size = 'medium', ...cardProps } = props;
const state = useCardBase_unstable(cardProps, ref);
return {
...state,
appearance,
orientation,
size
};
};
/**
* Base hook for Card component, which manages state related to interactivity, selection,
* focus management, ARIA attributes, and slot structure without design props.
*
* @param props - props from this instance of Card
* @param ref - reference to the root element of Card
*/ export const useCardBase_unstable = (props, ref)=>{
const { disabled = false, ...restProps } = props;
const [referenceId, setReferenceId] = React.useState(cardContextDefaultValue.selectableA11yProps.referenceId);
const [referenceLabel, setReferenceLabel] = React.useState(cardContextDefaultValue.selectableA11yProps.referenceId);
const cardBaseRef = useFocusWithin();
const { selectable, selected, selectableCardProps, selectFocused, checkboxSlot, floatingActionSlot } = useCardSelectable(props, {
referenceId,
referenceLabel
}, cardBaseRef);
const cardRef = useMergedRefs(cardBaseRef, ref);
const { interactive, focusAttributes } = useCardInteractive(props);
let cardRootProps = {
...!selectable ? focusAttributes : null,
...restProps,
...selectableCardProps
};
if (disabled) {
cardRootProps = {
...restProps,
'aria-disabled': true,
onClick: undefined
};
}
return {
interactive,
selectable,
selectFocused,
selected,
disabled,
selectableA11yProps: {
setReferenceId,
referenceId,
referenceLabel,
setReferenceLabel
},
components: {
root: 'div',
floatingAction: 'div',
checkbox: 'input'
},
root: slot.always(getIntrinsicElementProps('div', {
ref: cardRef,
role: 'group',
...cardRootProps
}), {
elementType: 'div'
}),
floatingAction: floatingActionSlot,
checkbox: checkboxSlot
};
};