## Description **Targets main.** This is the first of four cleanup PRs (#16240, #16241, #16242, #16243) that fix the design-system violations that #16234 (merged) put in the warn-only baseline. This PR replaces `lucide-react` and `react-icons` with `@opal/icons`. ### Before and after 10 files imported `lucide-react` (3) or `react-icons` (7). This PR migrates them all, except for 3 icons that have no Opal match. Three files are now clean of the design-system rules, so they are removed from the baseline in `web/.oxlintrc.json`: - `src/app/admin/agents/CollapsibleSection.tsx` - `src/app/app/message/messageComponents/interfaces.ts` - `src/views/admin/connectors/FederatedDetailPage/index.tsx` ### Changes (all under `web/src/`) | File | Old | New | | --- | --- | --- | | `app/admin/agents/CollapsibleSection.tsx` | `FiSettings` | `SvgSettings` (size 16 kept) | | `app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx` | lucide `AlertCircle` | `SvgAlertCircle` (classes kept) | | `app/admin/documents/feedback/DocumentFeedbackTable.tsx` | `FiEye`, `FiEyeOff` | `SvgEye`, `SvgEyeOff` | | `app/admin/documents/sets/page.tsx` | `FiCheckCircle`, `FiClock`, `FiAlertTriangle`, `FiLock`, `FiEdit2` | The matching `Svg*` icons; `FiEdit2` becomes `SvgEdit` | | `app/app/message/errorHelpers.tsx` | lucide `AlertCircle`, `Clock`, `Lock`, `Server` | The matching `Svg*` icons | | `app/app/message/messageComponents/interfaces.ts` | `IconType` from `react-icons` | `IconFunctionComponent \| null`. No caller passes a react-icons icon any more | | `app/app/message/messageComponents/toolDisplayHelpers.tsx` | `FiTool`, `FiCircle` | `SvgWrench`, `SvgCircle` | | `app/ee/admin/performance/query-history/[id]/page.tsx` | `FiBook` | `SvgBook` | | `app/ee/admin/standard-answer/page.tsx` | `FiTag` | `SvgTag` (size 16) | | `views/admin/connectors/FederatedDetailPage/index.tsx` | lucide `Loader2` | `SvgLoader` (classes kept) | ### Kept on purpose (no matching Opal icon) These sites still trip the rule and stay in the baseline. Each needs an icon added to `web/lib/opal/src/icons/` from Figma first: - `Wifi` in `errorHelpers.tsx`: Opal has no wifi or signal icon. - `FiUnlock` in `documents/sets/page.tsx`: Opal has `lock` but no unlock icon. The lock and unlock icons in that table now come from different sets. - `FiList` in `toolDisplayHelpers.tsx`: no Opal icon has the same bullet-list shape (`list-tree`, `list-check` and `text-lines` all differ). ### Visual differences reviewers should check - **Size:** react-icons default to `1em`, but Opal icons have no default size, so I set an explicit size from the text size around each icon: - `SvgEye`/`SvgEyeOff` are 12 (they sit in `text-xs`). - `SvgBook` is 14 (it sits in `text-sm`). - `SvgEdit` is 16. Its button sets no text size, so this one is a guess. - **Stroke:** lucide icons use stroke width 2, and Opal icons use 1.5, so lines look slightly thinner. - **`FiEdit2` to `SvgEdit`:** Opal's pencil has an underline. - **`FiCircle` to `SvgCircle`:** the Opal circle is smaller (r=4 in a 16 box, where the old one was r=10 in a 24 box). It is only the fallback when there are no packets, and `ReasoningRenderer` already uses `SvgCircle`. ## How Has This Been Tested? - oxlint: in the changed files, only the 3 icons listed above still report. The full run has 0 errors. - `bun run types:check`: no type errors, and type coverage stays at 99.04%. - pre-commit (oxfmt, oxlint) passes on the changed files. ## Additional Options - [ ] [Optional] Please cherry-pick this PR to the latest release version. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Style** * Updated icons across admin pages, document controls, chat tools, and message error states for a more consistent appearance. * Loading indicators, visibility controls, and error-state behavior remain unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Onyx Mobile (Expo)
A standalone React Native app for Onyx, under mobile/ — independent of web/ (its own
dependencies, lockfile, and tooling). Scaffolded with create-expo-app (Expo Router template).
Stack
- Expo SDK 56 (managed, New Architecture) · Expo Router · React 19.2 / RN 0.85 · Bun.
- NativeWind v4 for styling.
No design system wired yet — tokens/theme will be imported from the
@onyx-ai/sharedpackage later (see theSubash-Mohan/shared-package-mobile-webbranch). - TanStack Query (MMKV-persisted) · Zustand · react-native-mmkv · @shopify/flash-list.
Prerequisites
First-time machine setup (Xcode, Android Studio, JDK 17, NDK, simulator/emulator) is in
GETTING_STARTED.md. The list below is the short version.
- Node LTS on PATH, Bun, Xcode 26.4+ (older versions fail to build — see
GETTING_STARTED.md) + an iOS simulator, CocoaPods. - Recommended:
brew install watchman(faster, more reliable Metro file watching). - The project path must contain no spaces (RN/Xcode build scripts break otherwise).
- Runs as a development build (not Expo Go) —
react-native-mmkvv4 and FlashList are native modules absent from Expo Go.
Setup (from inside mobile/)
bun install
bunx expo install --fix # reconcile any deps to SDK 56
Run (iOS simulator)
bun run prebuild -- -p ios # or: bunx expo prebuild --clean -p ios (generates ios/)
bun run run:ios # or: bunx expo run:ios --port 8082
The first iOS build compiles React Native from source (~15 min) — RN 0.85 has no prebuilt CocoaPods artifact; this is expected, not a hang. Subsequent builds are incremental. Metro runs on port 8082 (8081 is commonly taken by Docker).
Android (
bun run run:android): the build must compile with JDK 17 — pointJAVA_HOMEat one first:export JAVA_HOME=$(/usr/libexec/java_home -v 17)(Android Studio's bundled JDK 21 won't work). The first Android build compiles native C++ via the NDK (~10–15 min).
Scripts
| Command | What it does |
|---|---|
bun run start / ios / android / web |
Metro / dev menu (port 8082). |
bun run run:ios / run:android |
Build + launch the native dev build. |
bun run prebuild |
Regenerate the native ios/ + android/ projects (CNG). |
bun run typecheck |
tsc --noEmit. |
bun run lint |
expo lint (ESLint flat config + eslint-config-expo). |
bun run format / format:check |
Prettier write / check (sorts NativeWind classes). |
Project layout
src/app/ Expo Router routes (_layout.tsx provider stack, index.tsx placeholder home)
src/query/ TanStack Query client + MMKV persister
src/state/ MMKV instances + storage adapter (shared by Query + zustand persist)
src/global.css Tailwind entry stylesheet (NativeWind)
Design system
Not wired yet. Tokens, theme, and shared utilities will be imported from the @onyx-ai/shared
package once it lands (see the Subash-Mohan/shared-package-mobile-web branch). Nothing is
vendored locally — the package owns the Style Dictionary build and the design tokens.
The splash logo (
assets/images/splash-icon.png) is a placeholder on the Onyx-blue background (#208AEF) — replace it with the real Onyx logo art.