Skip to content

add colorblind-aware UI settings#789

Open
Tiltann wants to merge 2 commits into
overextended:mainfrom
Tiltann:main
Open

add colorblind-aware UI settings#789
Tiltann wants to merge 2 commits into
overextended:mainfrom
Tiltann:main

Conversation

@Tiltann

@Tiltann Tiltann commented Jun 3, 2026

Copy link
Copy Markdown

Configurable Colorblind Mode for ox_lib

Adds accessibility-focused colorblind mode support to ox_lib, ensuring color-dependent UI elements (e.g. skillcheck indicators) adapt to players with color vision deficiencies.

Motivated by this community post.


What Changed

Settings & Localization

  • Added colorblind mode options to the /ox_lib settings menu (resource/settings.lua)
  • Added localization strings for new settings and labels (locales/en.json)

State & Sync

  • Persisted selected mode client-side and synchronized it to the web UI config path (resource/client.lua)
  • Wired colorblind mode handling into the config provider (web/src/providers/ConfigProvider.tsx)
  • Ensured safe app initialization and mode sync (web/src/App.tsx)

Hardening

  • Improved fetchNui to gracefully handle empty or non-JSON callback bodies, preventing crashes (web/src/utils/fetchNui.ts)
  • Added a resource name mismatch guard in resource/init.lua misnamed resources now fail fast with a clear error message instead of telling the person to build the UI.

Why

  • Improves accessibility for players with color vision deficiencies
  • Ensures skillcheck colors are mode-aware rather than hardcoded
  • Prevents NUI failures from malformed or empty callback responses
  • Makes resource misconfiguration easier to diagnose at startup

Testing

  • Web UI builds successfully (npm run build)
  • No file-level errors in modified Lua / JSON / TypeScript files
  • Manually validated settings flow and color mode application path
  • Confirmed startup error message for resource name mismatch

Notes

  • No breaking API changes
  • Existing behavior is fully preserved when colorblind mode is set to Off

Copilot AI review requested due to automatic review settings June 3, 2026 12:55

Copilot AI 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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a colorblind mode system that syncs between Lua settings and the React UI, and updates UI theming (including SkillCheck) accordingly.

Changes:

  • Introduces colorblind presets/theme mapping (web) and a colorblind setting + sync path (resource/Lua).
  • Updates ConfigProvider and SkillCheck to apply colorblind-aware colors.
  • Adjusts NUI fetch handling and moves init to a React effect.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
web/src/utils/fetchNui.ts Changes NUI response handling to parse from text with JSON fallback behavior
web/src/providers/ConfigProvider.tsx Adds colorblindMode to config, applies preset theme, and syncs changes via NUI
web/src/features/skillcheck/index.tsx Uses config-driven colorblind colors for SkillCheck strokes
web/src/config/colorblind.ts Adds colorblind presets and helper to get the theme for a mode
web/src/App.tsx Runs NUI init from useEffect instead of during render
resource/settings.lua Adds persisted colorblind mode setting, UI selection, sync callback, and test action
resource/init.lua Adds a resource-name mismatch check intended to hard-fail when renamed incorrectly
resource/client.lua Extends getConfig to include colorblindMode for the UI
locales/en.json Adds localization strings for colorblind mode and UI test action

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread resource/init.lua
Comment on lines +45 to +51
if not GetCurrentResourceName() == "ox_lib" then
local err =
'^1Resource name mismatch. Please ensure the resource is named "ox_lib".\n ^3https://github.com/overextended/ox_lib/releases/latest/download/ox_lib.zip^0'
function lib.hasLoaded() return err end

error(err)
end
Comment thread web/src/utils/fetchNui.ts
Comment on lines +32 to +42
const rawResponse = await resp.text();

return respFormatted;
if (!rawResponse) {
return null as T;
}

try {
return JSON.parse(rawResponse) as T;
} catch {
return null as T;
}
Comment on lines +28 to +33
fetchNui<Config>('getConfig').then((data) => {
setConfig({
...data,
...getColorblindTheme(data.colorblindMode),
});
});
Comment on lines +40 to +46
useNuiEvent<ColorblindMode>('setColorblindMode', (mode) => {
setConfig((previous) => ({
...previous,
...getColorblindTheme(mode),
colorblindMode: mode,
}));
});

const useStyles = createStyles((theme, params: { difficultyOffset: number }) => ({
const useStyles = createStyles(
(theme, params: { difficultyOffset: number; skillAreaColor: string; indicatorColor: string }) => ({
skillArea: {
fill: 'transparent',
stroke: theme.fn.primaryColor(),
stroke: params.skillAreaColor,
},
indicator: {
stroke: 'red',
stroke: params.indicatorColor,

export type ColorblindMode = 'off' | 'protanopia' | 'deuteranopia' | 'tritanopia' | 'achromatopsia';

const colorblindModes: Record<ColorblindMode, { primaryColor: MantineColor; primaryShade: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; skillAreaColor: MantineColor; skillAreaShade: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; indicatorColor: MantineColor; indicatorShade: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 }> = {
},
};

export const getColorblindTheme = (mode: ColorblindMode) => colorblindModes[mode];
Comment thread resource/settings.lua
Comment on lines 278 to 281
RegisterCommand('ox_lib', function()


local inputSettings = {
@Skryptific

Copy link
Copy Markdown
Contributor

I have seen some variables using snake case, this repo does not use that for variables.

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.

3 participants