Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
cometchat avatar

Cometchat A11y

  • 336 installs
  • 70 repo stars
  • Updated June 23, 2026
  • cometchat/cometchat-skills

cometchat-a11y is a Claude Code skill that audits and fixes CometChat UI Kit chat, call, and theme integrations to meet WCAG 2.1 AA across React, React Native, Angular, Android, iOS, and Flutter.

About

cometchat-a11y is a Claude Code skill version 4.0.0 for accessibility in CometChat UI Kit integrations across React, React Native, Angular, Android V5/V6, iOS, and Flutter families compatible with v4.x, v5.x, and v6.x releases. It targets WCAG 2.1 AA with keyboard navigation in chat, screen reader announcements via live regions for new messages, color contrast checks, focus management on call screens, and motion-reduction support. The skill highlights cross-family checks that catch common production accessibility bugs in chat and calling UI. Frontend engineers reach for cometchat-a11y when shipping CometChat and need systematic a11y fixes instead of ad hoc component patches.

  • Cross-family coverage for CometChat UI Kit React, React Native, Angular, Android V5/V6, iOS, and Flutter
  • Targets WCAG 2.1 AA with five recurring integration failure modes called out explicitly
  • Screen reader live regions and announcements for inbound messages
  • Focus management on call screens plus prefers-reduced-motion handling

Cometchat A11y by the numbers

  • 336 all-time installs (skills.sh)
  • Ranked #745 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cometchat/cometchat-skills --skill cometchat-a11y

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs336
repo stars70
Last updatedJune 23, 2026
Repositorycometchat/cometchat-skills

How do you fix CometChat UI Kit accessibility bugs?

Audit and fix CometChat UI Kit chat, call, and theme wiring so integrations meet WCAG 2.1 AA across React, RN, Angular, Android, iOS, and Flutter.

Who is it for?

Frontend engineers shipping CometChat UI Kit chat or call features on React, React Native, Angular, Android, iOS, or Flutter who need WCAG 2.1 AA fixes.

Skip if: Projects without CometChat UI Kit or teams only building custom chat UIs unrelated to CometChat components.

When should I use this skill?

The user asks to audit or fix CometChat chat, call, or theme accessibility across supported UI Kit frameworks.

What you get

WCAG 2.1 AA remediation notes, keyboard and focus fixes, live-region announcement updates, and contrast corrections across CometChat UI Kit families.

  • a11y audit findings
  • WCAG remediation fixes
  • keyboard and live-region updates

By the numbers

  • Skill metadata version 4.0.0
  • Covers 6 UI Kit families: React, React Native, Angular, Android, iOS, Flutter
  • Supports CometChat UI Kit v4.x, v5.x, and v6.x compatibility

Files

SKILL.mdMarkdownGitHub ↗
Ground truth: per-platform UI Kit + docs/fundamentals. Official docs: https://www.cometchat.com/docs/fundamentals/overview · Docs MCP: claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.

Purpose

Accessibility for CometChat integrations. Out-of-the-box, the UI Kit components are mostly accessible — the kit's own buttons, inputs, and lists ship with semantic markup. Production gaps appear in the wiring around the kit: custom call surfaces, navigation, focus management on screen transitions, and contrast in custom themes.

Target: WCAG 2.1 AA. The skill writes code that meets this baseline.

---

The five gaps that trip integrations (any family)

1. Color contrast in custom themes. A brand color picked for "looks nice in the brand book" may be 3.2:1 against the text — fails AA's 4.5:1 minimum. 2. Focus management on chat screen entry. Tab/screen reader user lands on the chat screen but focus stays on the previous trigger button. They have to manually navigate into the message list every time. 3. No live region announcement for new messages. Screen reader users don't know a new message arrived unless they navigate the message list and hear the new item. 4. Keyboard-only users can't navigate the conversation list. Click handlers bound to <div> instead of <button> skip keyboard events. 5. Reduced-motion users see decorative animations. Typing-indicator dots, message bubble entrance animations, transition effects — should respect prefers-reduced-motion.

This skill addresses each one across families.

---

1. Color contrast — the theme audit

CometChat themes are CSS variables (web/RN) or color tokens (native/Flutter). Override a single color and you might fail AA.

Web / Angular — CSS variable contrast check

// scripts/check-contrast.ts (run in CI or as a one-shot)
function contrastRatio(hex1: string, hex2: string): number {
  const luminance = (hex: string) => {
    const rgb = hex.match(/\w\w/g)!.map(c => parseInt(c, 16) / 255).map(c =>
      c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4
    );
    return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
  };
  const l1 = luminance(hex1);
  const l2 = luminance(hex2);
  return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
}

// Pull the values from your CSS variables
const fg = getComputedStyle(document.documentElement).getPropertyValue("--cometchat-text-color").trim();
const bg = getComputedStyle(document.documentElement).getPropertyValue("--cometchat-background-color").trim();
const ratio = contrastRatio(fg, bg);
if (ratio < 4.5) {
  console.warn(`Text/background contrast ${ratio.toFixed(2)}:1 fails WCAG AA (need ≥4.5:1)`);
}

In CI, add this to your test suite. The skill writes a starter version into tests/a11y/contrast.test.ts.

React Native / native / Flutter — manual audit at theme-design time

Use a contrast-checker tool (browser extensions, https://webaim.org/resources/contrastchecker/) on the theme tokens before shipping. There's no runtime DOM to audit on native.

The kit's default theme tokens pass AA. Custom palettes need the audit.

Common fail: brand purple #6750A4 against white background = 6.6:1 (passes). Same purple against #F0F0F0 light gray = 5.7:1 (passes). Same purple against #999999 muted gray = 2.8:1 (FAILS). Watch for muted backgrounds in dark-mode toggles, secondary buttons, and "subtle" surfaces.

---

2. Focus management on chat screen entry

When the user navigates to a chat screen (clicked a conversation, opened the chat tab, accepted a deep link), focus should land on a meaningful control — usually the message composer or the latest message.

React (web)

import { useEffect, useRef } from "react";

export function ChatScreen() {
  const composerRef = useRef<HTMLElement>(null);

  useEffect(() => {
    // After mount + animations, focus the composer
    const timer = setTimeout(() => {
      composerRef.current?.focus();
    }, 100);
    return () => clearTimeout(timer);
  }, []);

  return (
    <div>
      <CometChatMessageHeader />
      <CometChatMessageList />
      <CometChatMessageComposer ref={composerRef} />
    </div>
  );
}

The kit's CometChatMessageComposer is a plain function component (no forwardRef in v6), so passing it a ref is a no-op. Wrap it in a focusable container and reach the input through the DOM: composerRef.current?.querySelector("input, [contenteditable]")?.focus().

React Native

import { useRef, useEffect } from "react";
import { findNodeHandle, AccessibilityInfo } from "react-native";

export function ChatScreen() {
  const composerRef = useRef(null);

  useEffect(() => {
    const handle = findNodeHandle(composerRef.current);
    if (handle) {
      AccessibilityInfo.setAccessibilityFocus(handle);
    }
  }, []);

  return (
    <View>
      <CometChatMessageHeader />
      <CometChatMessageList />
      <CometChatMessageComposer ref={composerRef} />
    </View>
  );
}

Angular

@Component({...})
export class ChatComponent implements AfterViewInit {
  @ViewChild("composer") composer!: ElementRef;

  ngAfterViewInit() {
    setTimeout(() => this.composer.nativeElement.focus(), 100);
  }
}

Native Android (Kotlin)

override fun onResume() {
  super.onResume()
  composerView.requestFocus()
  composerView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
}

Native iOS (Swift)

override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  UIAccessibility.post(notification: .screenChanged, argument: composerView)
}

Flutter

final FocusNode _composerFocus = FocusNode();

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) {
    _composerFocus.requestFocus();
  });
}

// Then on the composer widget: focusNode: _composerFocus

---

3. Live region for new messages

Screen reader users need an audible announcement when a new message arrives — otherwise they have to navigate to the message list and re-read it.

Web / Angular — ARIA live region

<!-- A visually-hidden region that screen readers announce -->
<div
  aria-live="polite"
  aria-atomic="true"
  style="position: absolute; left: -9999px; height: 1px; width: 1px; overflow: hidden;"
  id="message-announcer"></div>
// Listen for new messages and announce
import { CometChat } from "@cometchat/chat-sdk-javascript";

const listenerId = "a11y-message-announcer";
CometChat.addMessageListener(listenerId, new CometChat.MessageListener({
  onTextMessageReceived: (msg: CometChat.TextMessage) => {
    const senderName = msg.getSender().getName();
    const text = msg.getText();
    const region = document.getElementById("message-announcer");
    if (region) {
      // Clearing first ensures the same text re-announces
      region.textContent = "";
      setTimeout(() => {
        region.textContent = `New message from ${senderName}: ${text}`;
      }, 100);
    }
  },
}));

aria-live="polite" waits for the user to finish speaking before announcing. Use aria-live="assertive" only for urgent messages (like incoming calls) — too aggressive for chat.

React Native

import { AccessibilityInfo } from "react-native";

CometChat.addMessageListener(listenerId, new CometChat.MessageListener({
  onTextMessageReceived: (msg) => {
    const text = `New message from ${msg.getSender().getName()}: ${msg.getText()}`;
    AccessibilityInfo.announceForAccessibility(text);
  },
}));

Native Android / iOS / Flutter

Each platform has an equivalent — Android View.announceForAccessibility(text), iOS UIAccessibility.post(notification: .announcement, argument: text), Flutter SemanticsService.announce(text, TextDirection.ltr). Same shape; the SDK callback is the trigger.

---

4. Keyboard navigation

The kit's components are keyboard-accessible by default. Custom wrapping is what breaks it.

Anti-pattern — <div onClick> for clickable items

// ✗ WRONG — keyboard users can't activate
<div onClick={() => openConversation(c)}>{c.name}</div>

// ✓ RIGHT — `<button>` is keyboard + screen-reader native
<button onClick={() => openConversation(c)}>{c.name}</button>

// ✓ ALSO RIGHT — div with explicit ARIA + keyboard handlers
<div
  role="button"
  tabIndex={0}
  onClick={() => openConversation(c)}
  onKeyDown={(e) => {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      openConversation(c);
    }
  }}
>
  {c.name}
</div>

Skip links

For long conversation lists, add a skip-to-message-composer link:

<a href="#message-composer" class="skip-link">Skip to message composer</a>
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 999;
}
.skip-link:focus {
  left: 0;
  top: 0;
  background: white;
  padding: 8px;
}

The kit's components already include skip links where applicable; custom wrapping should preserve them.

Keyboard shortcuts

For productivity apps:

useEffect(() => {
  const handler = (e: KeyboardEvent) => {
    // Cmd/Ctrl + K → focus search
    if ((e.metaKey || e.ctrlKey) && e.key === "k") {
      e.preventDefault();
      searchRef.current?.focus();
    }
    // Escape → close any open thread / modal
    if (e.key === "Escape") {
      closeOpenThread();
    }
  };
  window.addEventListener("keydown", handler);
  return () => window.removeEventListener("keydown", handler);
}, []);

Document the shortcuts in your in-app help — discoverability matters.

---

5. Reduced motion

Animations help most users; they cause physical discomfort or distraction for users with vestibular disorders, ADHD, or who simply prefer less movement. WCAG 2.1 AA requires honoring the OS preference.

Web / Angular — CSS

@media (prefers-reduced-motion: reduce) {
  /* Disable kit animations + your custom ones */
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

React Native

import { AccessibilityInfo } from "react-native";

const [reduceMotion, setReduceMotion] = useState(false);

useEffect(() => {
  AccessibilityInfo.isReduceMotionEnabled().then(setReduceMotion);
  const sub = AccessibilityInfo.addEventListener("reduceMotionChanged", setReduceMotion);
  return () => sub.remove();
}, []);

// In animations
<Animated.View
  style={{
    transform: [{ scale: reduceMotion ? 1 : animatedValue }],
  }}
/>

Native iOS

let reduceMotion = UIAccessibility.isReduceMotionEnabled
if !reduceMotion {
  UIView.animate(withDuration: 0.3) { ... }
} else {
  // Apply final state without animation
}

Native Android

val reduceMotion = Settings.Global.getFloat(
  contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f
) == 0.0f

Flutter

final reduceMotion = MediaQuery.of(context).disableAnimations;

The skill defaults to wrapping the typing indicator + message-bubble entrance animations in reduce-motion guards. Other kit animations need similar treatment if you've customized them.

---

Calls a11y

Calls have specific a11y considerations beyond chat:

1. Focus on call screen entry → end-call button. Avoids accidental hangup but ensures the user can quickly exit. 2. Announce incoming calls. Live region (web/RN) or UIAccessibility.post(.announcement) (iOS) — "Incoming call from Alice." 3. Mute/end button labels. "Mute microphone" not just "Mute" — clarify what's being toggled. 4. No flashing — recording indicator uses dot, not strobe. WCAG 2.3 forbids more than 3 flashes/sec to prevent seizures. 5. Caption support if recording. Production calling apps with live captioning hook in via the platform's speech-recognition API and overlay text on the call screen.

---

Testing — automated + manual

Web automated

npm install --save-dev @axe-core/playwright
import { test, expect } from "@playwright/test";
import AxeBuilder from "@axe-core/playwright";

test("chat screen passes axe AA", async ({ page }) => {
  await page.goto("/messages");
  const results = await new AxeBuilder({ page }).withTags(["wcag2a", "wcag2aa"]).analyze();
  expect(results.violations).toEqual([]);
});

Native automated

iOS: Xcode → Accessibility Inspector → Audit. Android: Accessibility Scanner app on a real device.

Manual

  • Keyboard-only navigation — unplug your mouse, complete a full chat flow. Tab through every control.
  • VoiceOver (iOS) / TalkBack (Android) / NVDA (Windows) / VoiceOver (macOS) — listen to the kit; verify announcements make sense.
  • Browser zoom 200% — kit should remain usable at 200% zoom on a 1280×720 viewport (WCAG 1.4.10 reflow).

---

Anti-patterns

1. Custom themes without a contrast audit. Brand colors silently fail AA. 2. `<div onClick>` for clickable items. Keyboard users can't activate. 3. No live region for new messages. Screen reader users miss messages. 4. Auto-playing video on call screen. Some users browse with autoplay disabled — kit handles this; custom UI must too. 5. Focus stays on the trigger button after opening chat. User has to manually re-navigate. 6. Ignoring `prefers-reduced-motion`. Vestibular-disorder users get disoriented. 7. `aria-live="assertive"` for chat messages. Interrupts the user mid-sentence; reserve for genuinely urgent (incoming call). 8. Skipping label specificity. "Mute" alone is ambiguous; "Mute microphone" / "Unmute microphone" is clear. 9. Color-only signals. "Read" status as just a checkmark color — add a visible text label for color-blind users. 10. No test coverage for a11y. Regressions slip in. Automate the easy checks (axe-core); manual-test the rest per release.

---

Verification checklist

Cross-family:

  • [ ] Custom theme passes AA contrast (4.5:1 text, 3:1 large text + UI components)
  • [ ] Focus lands on a meaningful control on chat screen entry
  • [ ] Live region / accessibility announcement on new message receive
  • [ ] No <div onClick> patterns — buttons are buttons
  • [ ] prefers-reduced-motion / isReduceMotionEnabled honored for animations
  • [ ] Mute/end/camera labels are specific (not just "Mute")
  • [ ] Incoming-call announcement (assertive live region OR platform announcement API)
  • [ ] No flashing > 3 Hz (recording dot uses fade, not strobe)

Web/Angular:

  • [ ] axe-core / Playwright a11y test in CI; passes WCAG AA tags
  • [ ] <html lang="..."> set to current locale (consumes cometchat-i18n skill output)
  • [ ] Skip-to-composer link present
  • [ ] Browser zoom 200% smoke test

Native (Android/iOS/Flutter):

  • [ ] TalkBack / VoiceOver smoke test on a real device
  • [ ] Reduced motion preference observed (UIAccessibility.isReduceMotionEnabled, etc.)
  • [ ] Focus restored on screen pop (not just push)
  • [ ] Touch targets ≥ 44×44 pt (iOS) / 48×48 dp (Android) — kit defaults pass; custom UI must too

---

Pointers

  • cometchat-i18n — sister skill; <html lang> and screen-reader pronunciation of translated strings depend on locale set correctly
  • cometchat-{family}-customization — when customizing kit components, preserve their built-in a11y attributes
  • cometchat-{family}-troubleshooting — when a11y tools report issues that look kit-internal
  • WCAG 2.1 AA reference — https://www.w3.org/WAI/WCAG21/quickref/?levels=aa
  • Material Design accessibility — https://m3.material.io/foundations/accessible-design
  • Apple HIG accessibility — https://developer.apple.com/design/human-interface-guidelines/accessibility

Related skills

How it compares

Choose cometchat-a11y over generic a11y lint rules when debugging CometChat-specific chat, call, and theme integration patterns across multiple UI Kit families.

FAQ

Which frameworks does cometchat-a11y support?

cometchat-a11y supports CometChat UI Kit families for React, React Native, Angular, Android V5/V6, iOS, and Flutter. The skill applies cross-family WCAG 2.1 AA checks for chat, call, and theme integrations.

What WCAG level does cometchat-a11y target?

cometchat-a11y targets WCAG 2.1 AA compliance for CometChat UI Kit integrations. The skill covers keyboard navigation, live-region announcements, color contrast, call-screen focus management, and motion-reduction support.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.