LibreChat/packages/client
Danny Avila 0db511fee8
fix: Restore WCAG AA Contrast for Text Tokens & Hide Edit Action While Streaming (#14677)
*  fix: Restore WCAG AA Contrast for Text Tokens & Hide Edit Action While Streaming

Fixes the unreadable composer placeholder and the edit pencil that appears on
hover mid-generation, plus the sibling token failures found while tracing the
root cause.

Placeholder: #13879 moved the composer from `dark:placeholder-white/60` to the
semantic `placeholder:text-text-tertiary`, but `--text-tertiary` was
`var(--gray-500)` in *both* themes, and #595959 is a dark gray. Dark mode fell
from 5.90:1 to 1.91:1. Fixed at the token (dark -> gray-400, 4.56:1) rather than
the call site: the token has 99 usages and was failing at 1.91-2.77:1 on every
dark surface. The .gizmo dark theme already uses a light gray (#999999) for the
same token, so only the default dark theme carried the inverted value.

Two more instances of the same "token never tuned per theme" bug:
- `--text-warning` was amber-500 in both themes: 2.15:1 in light across 13
  real warning strings. Now amber-700 (5.02:1).
- Light `status-{success,warning,error}` on their own `-subtle` fill measured
  3.58 / 3.07 / 4.41 -- the exact pairing Alert, Badge, Tag and Chip use for
  every status variant. Bumped to the 700 ramp (5.21 / 4.84 / 5.91). Solid
  `bg-status-*` is only used for dots, so nothing renders text on it.

Edit action: `hideEditButton` already covers `isSubmitting` and the button got
`isVisible={false}` -> `opacity-0`, but `group-hover:opacity-100` (0,2,0)
outranks bare `opacity-0` (0,1,0), so hovering the row revealed a disabled
pencil. The reveal classes are now gated on `isVisible`, with
`pointer-events-none` so the hidden button is inert.

Both token sources of truth (style.css and themes/*.ts) were updated and verified
in sync across all 67 tokens.

Tests: new HoverButtons spec covers both hover states; semanticTokens.spec.ts
gains a contrast guardrail over text tokens x surfaces and each status hue
against its subtle fill, verified to fail on the original values.
applyTheme.spec.ts now derives its expectation from the theme object instead of
pinning a hex, so retuning a hue no longer breaks an unrelated plumbing test.

* 🔤 style: Sort imports in HoverButtons spec

CI's changed-files import-order check flagged the new spec; the previous
commit bypassed the lint-staged hook that would have caught it.
2026-08-07 00:52:07 -04:00
..
src fix: Restore WCAG AA Contrast for Text Tokens & Hide Edit Action While Streaming (#14677) 2026-08-07 00:52:07 -04:00
babel.config.js 🪟 feat: DataTable update + Various UI enhancements (#9698) 2025-12-11 16:39:06 -05:00
jest.config.js ⬆️ chore: Migrate off deprecated @ariakit/react-core to @ariakit/react-components (#13940) 2026-06-24 23:13:57 -04:00
jest.resolver.cjs ⬆️ chore: Migrate off deprecated @ariakit/react-core to @ariakit/react-components (#13940) 2026-06-24 23:13:57 -04:00
jest.setup.ts 🪟 feat: DataTable update + Various UI enhancements (#9698) 2025-12-11 16:39:06 -05:00
package.json 🌯 chore: Retire Rollup-Era devDependencies After tsdown Migration (#14496) 2026-07-28 22:08:52 -04:00
tailwind.config.js
tsconfig.json refactor: Migrate @librechat/client build to tsdown (#13596) 2026-06-08 11:20:03 -04:00
tsconfig.test.json 🪟 feat: DataTable update + Various UI enhancements (#9698) 2025-12-11 16:39:06 -05:00
tsdown.config.mjs 🌀 ci: Deterministic Circular Dependency Checks (#14579) 2026-08-01 14:43:26 -04:00