Skip to content

EPMRPP-117731 || 'Caps Lock' icon is displayed in the password fields even when the Caps Lock is off#313

Merged
VaheSamsonyan merged 2 commits into
developfrom
bugfix/EPMRPP-117731-Caps-Lock-icon-is-displayed-in-the-password-fields-even-when-the-Caps-Lock-is-off
Jul 15, 2026
Merged

EPMRPP-117731 || 'Caps Lock' icon is displayed in the password fields even when the Caps Lock is off#313
VaheSamsonyan merged 2 commits into
developfrom
bugfix/EPMRPP-117731-Caps-Lock-icon-is-displayed-in-the-password-fields-even-when-the-Caps-Lock-is-off

Conversation

@VaheSamsonyan

@VaheSamsonyan VaheSamsonyan commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Description

checking the visibility and resetting the caps lock state to off, after returning from another tab

Visibility

visibilitycheck.mp4

Summary by CodeRabbit

  • Bug Fixes
    • Caps Lock indicators now stay in sync with the operating system state, including after switching away from and back to a browser tab.
    • Caps Lock messages and icons are shown only when the corresponding text field is focused (while still respecting the existing Caps Lock message and state conditions).

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The Caps Lock hook now synchronizes with the OS modifier state, rechecks after CapsLock key release, and resets when the tab becomes visible. FieldText displays the indicator only when the input is focused.

Changes

Caps Lock behavior

Layer / File(s) Summary
Synchronize Caps Lock state
src/common/hooks/useCapsLock.ts
The hook reads modifier state, handles key release and visibility changes, and registers and removes the corresponding listeners.
Require focus for the indicator
src/components/fieldText/fieldText.tsx
The Caps Lock indicator now also requires the field to be focused.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: allaprischepa, siarheirazuvalau

Poem

A rabbit checks the caps-lock light,
Syncing day and tab each night.
When focus hops into the field,
The little warning is revealed.
Clean listeners bounce away.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main fix: preventing the Caps Lock icon from showing when Caps Lock is off.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/EPMRPP-117731-Caps-Lock-icon-is-displayed-in-the-password-fields-even-when-the-Caps-Lock-is-off

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/common/hooks/useCapsLock.ts (1)

24-60: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consolidate event listeners for scalability and add mousedown sync.

The current implementation effectively addresses the synchronization requirements. However, since FieldText is a base component that utilizes this hook, rendering multiple inputs on a single page will attach duplicate sets of window and document event listeners, causing them all to fire on every keystroke.

Consider extracting the listener logic to the module level using React 18's useSyncExternalStore. This maintains a single global subscription regardless of how many inputs are rendered. Additionally, listening to mousedown events allows the state to sync immediately when a user clicks the page or input, without waiting for their first keypress.

♻️ Proposed refactor using `useSyncExternalStore`

Replace the hook implementation with a module-level store:

import { useSyncExternalStore } from 'react';

let globalCapsLockOn = false;
let isListening = false;
const listeners = new Set<() => void>();

const emitChange = () => listeners.forEach((listener) => listener());

const syncCapsLock = (event: Event) => {
  const modifierEvent = event as KeyboardEvent | MouseEvent;
  const newState = modifierEvent.getModifierState?.('CapsLock') ?? false;
  if (newState !== globalCapsLockOn) {
    globalCapsLockOn = newState;
    emitChange();
  }
};

const handleKeyUp = (event: KeyboardEvent) => {
  // CapsLock keydown fires before the OS toggles the modifier; keyup reads the real state.
  if (event.key === 'CapsLock') {
    syncCapsLock(event);
  }
};

// Caps Lock may be toggled in another browser tab where this page receives no
// keyboard events. Reset on tab return; the real state is re-detected on the
// next keydown or mousedown while a password field is focused.
const handleVisibilityChange = () => {
  if (document.visibilityState === 'visible' && globalCapsLockOn) {
    globalCapsLockOn = false;
    emitChange();
  }
};

const subscribe = (listener: () => void) => {
  if (!isListening && typeof window !== 'undefined') {
    window.addEventListener('keydown', syncCapsLock);
    window.addEventListener('keyup', handleKeyUp);
    window.addEventListener('mousedown', syncCapsLock);
    document.addEventListener('visibilitychange', handleVisibilityChange);
    isListening = true;
  }
  
  listeners.add(listener);
  return () => {
    listeners.delete(listener);
  };
};

const getSnapshot = () => globalCapsLockOn;
const getServerSnapshot = () => false;

export const useCapsLock = () => {
  const capsLockOn = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
  return { capsLockOn };
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/common/hooks/useCapsLock.ts` around lines 24 - 60, Refactor useCapsLock
to use a module-level external store with useSyncExternalStore, keeping one
shared set of window/document listeners regardless of how many hook instances
render. Preserve the existing keydown, CapsLock keyup, and visibility-reset
behavior, add mousedown synchronization, and ensure subscriptions are cleaned up
and SSR uses a false server snapshot.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/common/hooks/useCapsLock.ts`:
- Around line 24-60: Refactor useCapsLock to use a module-level external store
with useSyncExternalStore, keeping one shared set of window/document listeners
regardless of how many hook instances render. Preserve the existing keydown,
CapsLock keyup, and visibility-reset behavior, add mousedown synchronization,
and ensure subscriptions are cleaned up and SSR uses a false server snapshot.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d562957-437b-42f5-83ba-2629b823d51f

📥 Commits

Reviewing files that changed from the base of the PR and between 2c73e6f and 7ee31da.

📒 Files selected for processing (1)
  • src/common/hooks/useCapsLock.ts

@VaheSamsonyan
VaheSamsonyan merged commit 34588d7 into develop Jul 15, 2026
2 checks passed
@VaheSamsonyan
VaheSamsonyan deleted the bugfix/EPMRPP-117731-Caps-Lock-icon-is-displayed-in-the-password-fields-even-when-the-Caps-Lock-is-off branch July 15, 2026 12:14
github-actions Bot pushed a commit that referenced this pull request Jul 15, 2026
… even when the Caps Lock is off (#313)

* checking visibility and resetting the caps lock to off, showing the icon only when the field is focused

* matching the os state and the caps lock state

---------

Co-authored-by: vahesamsonyan <vahe_samsonyan@epam.com> 34588d7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants