Outlook_Addin_LLM/node_modules/@fluentui/react-positioning/lib/createArrowStyles.js

82 lines
3.4 KiB
JavaScript

import { tokens } from '@fluentui/react-theme';
/**
* @internal
* Helper that creates a makeStyles rule for an arrow element.
* For runtime arrow size toggling simply create extra classnames to apply to the arrow element
*
* ```ts
* makeStyles({
* arrowWithSize: createArrowStyles({ arrowHeight: 6 }),
*
* arrowWithoutSize: createArrowStyles({ arrowHeight: undefined }),
* mediumArrow: createArrowHeightStyles(4),
* smallArrow: createArrowHeightStyles(2),
* })
* ...
*
* state.arrowWithSize.className = styles.arrowWithSize;
* state.arrowWithoutSize.className = mergeClasses(
* styles.arrowWithoutSize,
* state.smallArrow && styles.smallArrow,
* state.mediumArrow && styles.mediumArrow,
* )
* ```
*/ export function createArrowStyles(options) {
const { arrowHeight, borderWidth = '1px', borderStyle = 'solid', borderColor = tokens.colorTransparentStroke } = options;
return {
boxSizing: 'border-box',
position: 'absolute',
zIndex: -1,
...arrowHeight && createArrowHeightStyles(arrowHeight),
backgroundColor: 'inherit',
backgroundClip: 'content-box',
borderBottomLeftRadius: `${tokens.borderRadiusSmall} /* @noflip */`,
transform: 'rotate(var(--fui-positioning-arrow-angle)) /* @noflip */',
height: 'var(--fui-positioning-arrow-height)',
width: 'var(--fui-positioning-arrow-height)',
'::before': {
content: '""',
display: 'block',
backgroundColor: 'inherit',
margin: `-${borderWidth}`,
width: '100%',
height: '100%',
border: `${borderWidth} ${borderStyle} ${borderColor}`,
borderBottomLeftRadius: `${tokens.borderRadiusSmall} /* @noflip */`,
clipPath: 'polygon(0% 0%, 100% 100%, 0% 100%)'
},
// Popper sets data-popper-placement on the root element, which is used to align the arrow
':global([data-popper-placement^="top"])': {
bottom: 'var(--fui-positioning-arrow-offset)',
'--fui-positioning-arrow-angle': '-45deg'
},
':global([data-popper-placement^="right"])': {
left: `var(--fui-positioning-arrow-offset) /* @noflip */`,
'--fui-positioning-arrow-angle': '45deg'
},
':global([data-popper-placement^="bottom"])': {
top: 'var(--fui-positioning-arrow-offset)',
'--fui-positioning-arrow-angle': '135deg'
},
':global([data-popper-placement^="left"])': {
right: `var(--fui-positioning-arrow-offset) /* @noflip */`,
'--fui-positioning-arrow-angle': '225deg'
}
};
}
/**
* @internal
* Creates CSS styles to size the arrow created by createArrowStyles to the given height.
*
* Use this when you need to create classes for several different arrow sizes. If you only need a
* constant arrow size, you can pass the `arrowHeight` param to createArrowStyles instead.
*/ export function createArrowHeightStyles(arrowHeight) {
// The arrow is a square rotated 45 degrees to have its bottom and right edges form a right triangle.
// Multiply the triangle's height by sqrt(2) to get length of its edges.
const edgeLength = 1.414 * arrowHeight;
return {
'--fui-positioning-arrow-height': `${edgeLength}px`,
'--fui-positioning-arrow-offset': `${edgeLength / 2 * -1}px`
};
}