Private
Public Access
1
0
Files
power-apps-codeapps-blog-part2/node_modules/@fluentui/react-tabs/lib/components/Tab/useTabAnimatedIndicator.styles.js

133 lines
5.5 KiB
JavaScript

'use client';
import * as React from 'react';
import { __styles, mergeClasses } from '@griffel/react';
import { useTabListContext_unstable } from '../TabList/TabListContext';
import { tokens } from '@fluentui/react-theme';
import { useAnimationFrame } from '@fluentui/react-utilities';
// eslint-disable-next-line @typescript-eslint/naming-convention
const tabIndicatorCssVars_unstable = {
offsetVar: '--fui-Tab__indicator--offset',
scaleVar: '--fui-Tab__indicator--scale'
};
const useActiveIndicatorStyles = /*#__PURE__*/__styles({
base: {
B68tc82: 0,
Bmxbyg5: 0,
Bpg54ce: "f1gl81tg"
},
animated: {
Ba2ppi3: "fhwpy7i",
F2fol1: "f6zz20j",
B1dyfl9: "f1ai4sc1",
Bu93a1u: "f1rnm8gg",
Bdasjez: "f1x3cmqg"
},
horizontal: {
sjv3b2: ["fug4aj8", "f1i5xzg7"],
b1kco5: "f1q7ujh"
},
vertical: {
sjv3b2: "f1hqboyk",
b1kco5: "f1dxupa6"
}
}, {
d: [[".f1gl81tg{overflow:visible;}", {
p: -1
}], ".fhwpy7i::after{transition-property:transform;}", ".f6zz20j::after{transition-duration:var(--durationSlow);}", ".f1ai4sc1::after{transition-timing-function:var(--curveDecelerateMax);}", ".fug4aj8::after{transform-origin:left;}", ".f1i5xzg7::after{transform-origin:right;}", ".f1q7ujh::after{transform:translateX(var(--fui-Tab__indicator--offset)) scaleX(var(--fui-Tab__indicator--scale));}", ".f1hqboyk::after{transform-origin:top;}", ".f1dxupa6::after{transform:translateY(var(--fui-Tab__indicator--offset)) scaleY(var(--fui-Tab__indicator--scale));}"],
m: [["@media (prefers-reduced-motion: reduce){.f1rnm8gg::after{transition-property:none;}}", {
m: "(prefers-reduced-motion: reduce)"
}], ["@media (prefers-reduced-motion: reduce){.f1x3cmqg::after{transition-duration:0.01ms;}}", {
m: "(prefers-reduced-motion: reduce)"
}]]
});
const calculateTabRect = element => {
if (element) {
var _element_parentElement;
const parentRect = ((_element_parentElement = element.parentElement) === null || _element_parentElement === void 0 ? void 0 : _element_parentElement.getBoundingClientRect()) || {
x: 0,
y: 0,
width: 0,
height: 0
};
const tabRect = element.getBoundingClientRect();
return {
x: tabRect.x - parentRect.x,
y: tabRect.y - parentRect.y,
width: tabRect.width,
height: tabRect.height
};
}
return undefined;
};
const getRegisteredTabRect = (registeredTabs, value) => {
var _registeredTabs_JSON_stringify;
const element = isValueDefined(value) ? (_registeredTabs_JSON_stringify = registeredTabs[JSON.stringify(value)]) === null || _registeredTabs_JSON_stringify === void 0 ? void 0 : _registeredTabs_JSON_stringify.ref.current : undefined;
return element ? calculateTabRect(element) : undefined;
};
// eslint-disable-next-line eqeqeq
const isValueDefined = value => value != null;
/**
* Adds additional styling to the active tab selection indicator to create a sliding animation.
*/
export const useTabAnimatedIndicatorStyles_unstable = state => {
const {
disabled,
selected,
vertical
} = state;
const activeIndicatorStyles = useActiveIndicatorStyles();
const [lastAnimatedFrom, setLastAnimatedFrom] = React.useState();
const [animationValues, setAnimationValues] = React.useState({
offset: 0,
scale: 1
});
const getRegisteredTabs = useTabListContext_unstable(ctx => ctx.getRegisteredTabs);
const [requestAnimationFrame] = useAnimationFrame();
if (selected) {
const {
previousSelectedValue,
selectedValue,
registeredTabs
} = getRegisteredTabs();
if (isValueDefined(previousSelectedValue) && lastAnimatedFrom !== previousSelectedValue) {
const previousSelectedTabRect = getRegisteredTabRect(registeredTabs, previousSelectedValue);
const selectedTabRect = getRegisteredTabRect(registeredTabs, selectedValue);
if (selectedTabRect && previousSelectedTabRect) {
const offset = vertical ? previousSelectedTabRect.y - selectedTabRect.y : previousSelectedTabRect.x - selectedTabRect.x;
const scale = vertical ? previousSelectedTabRect.height / selectedTabRect.height : previousSelectedTabRect.width / selectedTabRect.width;
setAnimationValues({
offset,
scale
});
setLastAnimatedFrom(previousSelectedValue);
// Reset the animation values after the animation is complete
requestAnimationFrame(() => setAnimationValues({
offset: 0,
scale: 1
}));
}
}
} else if (isValueDefined(lastAnimatedFrom)) {
// need to clear the last animated from so that if this tab is selected again
// from the same previous tab as last time, that animation still happens.
setLastAnimatedFrom(undefined);
}
// do not apply any animation if the tab is disabled
if (disabled) {
return state;
}
// the animation should only happen as the selection indicator returns to its
// original position and not when set at the previous tabs position.
const animating = animationValues.offset === 0 && animationValues.scale === 1;
state.root.className = mergeClasses(state.root.className, selected && activeIndicatorStyles.base, selected && animating && activeIndicatorStyles.animated, selected && (vertical ? activeIndicatorStyles.vertical : activeIndicatorStyles.horizontal));
const rootCssVars = {
[tabIndicatorCssVars_unstable.offsetVar]: `${animationValues.offset}px`,
[tabIndicatorCssVars_unstable.scaleVar]: `${animationValues.scale}`
};
state.root.style = {
...rootCssVars,
...state.root.style
};
return state;
};