Skip to content

Commit

Permalink
fix(Tappable): force activated/hovered state (#7906)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackySoul committed Nov 7, 2024
1 parent a8f0e1a commit 91bf3e9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 36 deletions.
57 changes: 30 additions & 27 deletions packages/vkui/src/components/Clickable/useState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ function useHover({ hovered, hasHover = true, lockState, setParentStateLock }: U
(isHover: boolean) => {
setHoveredStateLocal(isHover);

const isHovered = calculateStateValue({
hasState: hasHover,
isLocked: lockState,
stateValueControlled: Boolean(hovered),
stateValueLocal: isHover,
});
const isHovered =
hovered ??
calculateStateValue({
hasState: hasHover,
isLocked: lockState,
stateValueLocal: isHover,
});

// проверка сделана чтобы реже вызывать обновление состояния
// контекста родителя
Expand All @@ -122,12 +123,13 @@ function useHover({ hovered, hasHover = true, lockState, setParentStateLock }: U
handleHover(false);
};

const isHovered = calculateStateValue({
hasState: hasHover,
isLocked: lockState,
stateValueControlled: Boolean(hovered),
stateValueLocal: hoveredStateLocal,
});
const isHovered =
hovered ??
calculateStateValue({
hasState: hasHover,
isLocked: lockState,
stateValueLocal: hoveredStateLocal,
});

return {
isHovered,
Expand Down Expand Up @@ -194,12 +196,13 @@ function useActive({
setActivated(false, activeEffectDelay);
};

const isActivated = calculateStateValue({
hasState: hasActive,
isLocked: lockStateRef.current,
stateValueControlled: Boolean(activated),
stateValueLocal: activatedState,
});
const isActivated =
activated ??
calculateStateValue({
hasState: hasActive,
isLocked: lockStateRef.current,
stateValueLocal: activatedState,
});

return {
isActivated,
Expand Down Expand Up @@ -262,9 +265,12 @@ function useLockRef(
export function useState({
hovered,
hasHover,
activated,
hasActive,
activeEffectDelay,
unlockParentHover,
...restProps
hoverClassName,
activeClassName,
}: StateProps): {
stateClassName: string;
setLockHoverBubblingImmediate: (...args: any[]) => void;
Expand All @@ -286,15 +292,14 @@ export function useState({
});

const { isActivated, ...activeEvent } = useActive({
...restProps,
activated,
hasActive,
activeEffectDelay,
lockStateRef: lockActiveStateRef,
setParentStateLock: setParentStateLockActiveBubbling,
});

const stateClassName = classNames(
isHovered && restProps.hoverClassName,
isActivated && restProps.activeClassName,
);
const stateClassName = classNames(isHovered && hoverClassName, isActivated && activeClassName);
const handlers = mergeCalls(hoverEvent, activeEvent);

return {
Expand All @@ -309,13 +314,11 @@ export function useState({
function calculateStateValue({
hasState,
isLocked,
stateValueControlled,
stateValueLocal,
}: {
hasState: boolean;
isLocked: boolean;
stateValueControlled: boolean;
stateValueLocal: boolean;
}): boolean {
return hasState && !isLocked && (stateValueControlled || stateValueLocal);
return hasState && !isLocked && stateValueLocal;
}
23 changes: 14 additions & 9 deletions packages/vkui/src/components/Tappable/Tappable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,12 @@ describe(Tappable, () => {
it('activates during longtap', async () => {
render(<TappableTest onClick={noop} />);
fireEvent.pointerDown(tappable());
expect(tappable()).not.toHaveClass(styles['Tappable--activated-background']);
await waitFor(() => expect(tappable()).toHaveClass(styles['Tappable--activated-background']));
act(jest.runOnlyPendingTimers);
expect(tappable()).toHaveClass(styles['Tappable--activated-background']);

fireEvent.pointerUp(tappable());
expect(tappable()).toHaveClass(styles['Tappable--activated-background']);
act(jest.runOnlyPendingTimers);
expect(tappable()).not.toHaveClass(styles['Tappable--activated-background']);
});

it('does not activate on child Tappable click', async () => {
Expand Down Expand Up @@ -264,12 +265,16 @@ describe(Tappable, () => {
expect(tappable()).not.toHaveClass(styles['Tappable--activated-background']);
});

it('on hasActive=false', () => {
const h = render(<TappableTest />);
fireEvent.mouseDown(tappable());
act(jest.runAllTimers);
h.rerender(<TappableTest hasActive={false} />);
expect(tappable()).not.toHaveClass(styles['Tappable--activated-background']);
it('on hasActive=false', async () => {
render(<TappableTest hasActive={false} onClick={noop} />);
await userEvent.click(tappable());
let errored = false;
await waitFor(() =>
expect(tappable()).toHaveClass(styles['Tappable--activated-background']),
).catch(() => {
errored = true;
});
expect(errored).toBeTruthy();
});

it('on child hover', async () => {
Expand Down

0 comments on commit 91bf3e9

Please sign in to comment.