Skip to content

docs(theme): improve icon search visibility in dark mode - #4823

Closed
mensonones wants to merge 94 commits into
callstack:5.0from
mensonones:main
Closed

mensonones wants to merge 94 commits into
callstack:5.0from
mensonones:main

Conversation

@mensonones

Copy link
Copy Markdown
Contributor

Motivation

The icon search input field in the documentation site was completely invisible in dark theme due to white text being rendered on a white background. This made it impossible for users to see what they were typing when searching for icons, significantly impacting the user experience in dark mode.

Related issue

Fixes #4822

Test plan

  1. Navigate to the documentation site locally: cd docs && npm start
  2. Go to the Icons page in the documentation
  3. Toggle to dark theme using the theme switcher
  4. Try typing in the "Find icon by name…" search input
  5. Verify that:
    • Text is now visible while typing (white text on dark background)
    • Placeholder text is visible with appropriate contrast
    • Input background changes on hover/focus for better UX
    • All states work correctly in both light and dark themes

Before: Text was invisible (white on white)
After: Text is clearly visible with proper contrast using Infima CSS variables

@callstack-bot

Copy link
Copy Markdown

Hey @mensonones, thank you for your pull request 🤗. The documentation from this branch can be viewed here.

xdimota7x and others added 29 commits April 28, 2026 16:23
* chore: remove md2 support

* docs: remove md2 references from docs

* chore: update example to use md3 only, removing md2 references

* chore: remove Typography/v2 and version references from types

* chore: remove subtitle and subtitleStyle from AppbarContent

* chore: remove getColor from BottomNavigation
* docs: remove md2 references from docs

* fix: pre-commit hook lint issues

* fix: ripple not showing
* chore: remove md2 support

* fix: update colors as per material-components color tokens

* see https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/color/res/values/tokens.xml

* fix: update the color schema for LightTheme and DarkTheme

* see: https://m3.material.io/styles/color/roles

* feat: add DynamicTheme

* Known limitation: surface/container roles on API 31-33 use
* @color/m3_ref_palette_dynamic_neutral_variant* (MCL resources that require a
* native DynamicColors setup). No @android:color/ equivalent exists for those
* slots. Reference palette values are used as fallback on API 31-33.

* refactor: remove usage of expo-material3-theme

* refactor: rename "device colors" to "Dynamic Theme"

* feat: update Colors and stateOpacity tokens
for PlatformColor compatibility

* surfaceDisabled, onSurfaceDisabled and backdrop which were not part of the MD standard were removed
* the reference theme elevation colors now use the correct neutral tones; see https://m3.material.io/blog/tone-based-surface-color-m3
* replace usage of "alpha" with opacity or surface colors
* remove disabled FAB prop
* refactor: remove MD3 prefix and use deprecated aliases

* refactor: strip remaining v3 version markers
Adds src/theme/tokens/sys/color/roles.ts with a roleToTone table keyed
by (mode, contrast) and a buildScheme() function. LightTheme and
DarkTheme replace their hand-duplicated color literals with a single
buildScheme() call each. Output shape is identical; tone values match
the existing hand-written spec.
…#4917)

* feat: add theme.state opacity tokens and split theme types

* feat: add disabled and enabled opacity to theme.state

* fix: code review findings
…stack#4920)

Adds 15 *Emphasized entries per M3 Design Kit: Display/Headline/TitleLarge/Body use Medium (500), TitleMedium/TitleSmall/Label use Bold (700). Adds weightBold to ref.typeface. Fixes displayLarge letterSpacing (0 -> -0.25) and bodyLarge letterSpacing (0.15 -> 0.5).
Adds theme.motion with two preset schemes (expressiveMotion default, standardMotion), M3 easing curves, and duration constants verified against the material.io spec. Includes toRawSpring() helper to convert the spec damping ratio to the raw coefficient expected by Animated.spring and Reanimated
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>
…eme export

  - DynamicTheme.android: replace duplicated light/dark tables with a
    single colorRoleMap + buildDynamicColors helper; use Palette.* tokens
    directly for the ref fallback instead of reading back through
    LightTheme.colors.*/DarkTheme.colors.*; export isDynamicColorSupported
    and short-circuit map construction when unsupported
  - PaperProvider: respect theme.dark when picking the base scheme and
    shallow-merge colors so partial color overrides survive
  - Remove public DefaultTheme export (use LightTheme); update internal
    imports and babel-import-rewrite fixtures
Adds an `error?: boolean` prop to Checkbox, CheckboxAndroid and
CheckboxIOS. When true, the outline (unchecked) and container (checked /
indeterminate) use `theme.colors.error`. The `disabled` state and
explicit `color` / `uncheckedColor` overrides take precedence.

Addresses one bullet from callstack#4937 / callstack#4949 (Checkbox section,
"Error state not implemented"). Verified visually on iOS Simulator
and Android Emulator across light and dark themes.
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
…#4952)

* add focusIndicator tokens
* add shadow overrides
* include mass in toRawSpring
* add contentColorFor helper
k0ndee and others added 23 commits September 9, 2026 16:19
`PortalHost` queues portal operations that arrive before its
`PortalManager` ref is attached, which is every portal that mounts in the
first commit. `componentDidMount` drained that queue with `pop()`,
replaying the operations LIFO, so portals mounted in the same commit were
stacked in reverse source order.

Drain with `shift()` instead.
…allstack#5126)

- Render Modal and Dialog in their own portals
- Hide the app and lower portal layers from assistive technology and focus while a modal is open
- Preserve reduced motion settings in portal content

BREAKING CHANGE: This adds `Portal` to `Modal` and `Dialog` internally. So they need to remove any wrapper `Portal` and must be rendered inside a `Portal.Host` or `PaperProvider`.

---------

Co-authored-by: Konstantin Marushchak <konstantin.maruschak@callstack.com>
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>
Co-authored-by: Konstantin Marushchak <konstantin.maruschak@callstack.com>
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>
* chore: automate example app publishing

The example app in the stores drifts away from the library: it was released
eighteen times in nine years against eighty-three library releases, all by
hand, and the last one was twenty months ago. Ship it from the release that
prompts it instead.

What it ships depends on whether native code changed. `runtimeVersion` uses
the fingerprint policy, so the workflow can compare the project against the
builds already out there: unchanged means the new JavaScript runs on what
people already have, and goes out as an update; changed means a build and a
trip through the stores. Only a build carries a version to a store, so only a
build bumps one, and that bump comes back as a pull request.

This replaces the updates workflow, which published updates when a labelled
pull request merged. It never ran once: it triggers on push, where the
pull_request it tests does not exist, so all sixty-nine runs skipped. Tying
both outcomes to the release removes the label nobody remembered to add.

Prereleases and stable releases build against separate channels so an update
published for an alpha cannot reach the stable app. Where a build lands is
decided by the tag rather than by the release's prerelease flag, because
.release-it.json pins every release to `preRelease: true` for the 6.0 alpha
cycle, and reading that flag would route a stable 6.0.0 to the internal track.

Publishing runs after a release already exists, so it cannot fail, revoke or
roll back one. A run that does not succeed says so on its own run page, where
the mail GitHub already sends the publisher leads, and says the release is
unaffected.

Store credentials live in EAS rather than here, so EXPO_TOKEN is the only
secret this needs. Setup and the known limitations are in CONTRIBUTING.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(ci): add a dry run to the example app workflow

Whether EXPO_TOKEN still works could otherwise only be found out by a real
run, which builds and submits. A dry run authenticates, works out whether the
release would build or update, reports that, and stops.

Also check authentication in its own step, so a missing or expired token fails
in seconds with a message that says so rather than several minutes later
inside a build.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: keep the example app fingerprint stable across pod install

ExpoModulesJSI.podspec builds an xcframework into its own source directory
from a prepare_command, and that directory is fingerprinted. EAS fingerprints
after installing pods and the CLI fingerprints before, so the two disagreed
and the build stopped with a runtime version mismatch.

Ignore the generated products. The sources they are built from are
fingerprinted already, so nothing that changes the native runtime stops being
noticed. Without this the workflow would also never publish an update: the
fingerprint it computes on a runner could never match the one EAS recorded.

Drop the build number and version code from the app config as well, now that
EAS assigns both remotely and warns on every command that the values in the
config are ignored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* refactor: drop the dry run from the example app workflow

The dry run existed to answer whether EXPO_TOKEN still worked and whether the
store credentials would resolve, without spending a real run. Both have since
been answered by building and submitting for real, so what is left is a second
path through the workflow kept alive to derisk a first run whose worst outcome
is that a demo app does not update.

Trim what publishing adds to CONTRIBUTING.md down to what would otherwise go
wrong quietly: that nothing reaches the App Store on its own, that the version
bump pull request has to be merged before the next release, where the
credentials live, and which generated files have to stay out of the
fingerprint. The run page and the issue a failed run opens already say the
rest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: replace AI prose with human comments, trim tests

* chore: simplify deployment output logs

* fix: address review feedback on example app deployment

* refactor: set example app version from the release tag

* fix: harden the example app deployment workflow

* fix: address second round of example app deployment review

Pass the release tag from the check job, pin eas-cli, build only the
platforms whose native code changed, queue preview and production runs
separately, and read the EAS Node version from .nvmrc.

* fix: tighten the example app deployment workflow

Publish updates before builds so a slow build can't hold them up, fail
on a missing fingerprint or commit lookup, work out the profile once in
the check job, and drop the 2-hour timeout in favour of the default.

---------

Co-authored-by: Radoslaw Nowacki <radoslaw.nowacki@callastack.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ack#5149)

The release script ran `release-it --only-version`. release-it 13.7.2 has
no such option and parses only --dry-run and --ci as boolean flags, so
`yarn release 6.0.0-alpha.1` took the version as the flag's value and
released the recommended bump instead: 6.0.0.

.release-it.json pinned npm.tag to "alpha" and github.preRelease to true.
A configured tag always wins, so every release, 6.0.0 included, would go
to the alpha tag as a GitHub prerelease and leave 5.15.3 on latest.

- Run plain `release-it`, so the version passed is the version released.
- Drop npm.tag and github.preRelease: release-it takes the tag from the
  prerelease id (alpha, beta, rc) or uses latest for a stable version,
  and marks prereleases on GitHub by itself.
- Create the GitHub release as a draft, so the example app pipeline
  (which runs when a release is published) waits until npm has the
  package.
- Rewrite "Publishing a release" in CONTRIBUTING.md to match.
)

The v6 getting-started and theming guides link to src/styles/themes/v3/LightTheme.tsx, which no longer exists on main. Point them at src/theme/schemes/LightTheme.tsx.

Also correct spelling in the v5 guides: platfrom, Additionaly, oficially, follwing.
Co-authored-by: John Fanidis <johnfanidis@gmail.com>
The customVariant example under "Material Design 3 -> Using configureFonts helper" uses Platform.select() but never imports Platform from react-native. This throws a "ReferenceError: : Platform is not defined".

Added the missing import.

Co-authored-by: John Fanidis <johnfanidis@gmail.com>
…ck#5136)

The light-only and dark-only overloads of adaptNavigationTheme returned the
narrow NavigationTheme type, dropping `fonts` and custom colors from the
input theme even though they are preserved at runtime. This made the result
unassignable to React Navigation's Theme. Return the input theme type, as
the overload for both themes already does.

Fixes callstack#4751
* fix(menu): avoid focusing hidden anchors on mount

* test(menu): name animation timer duration
@Doberjohn

Copy link
Copy Markdown
Collaborator

Thanks for this but the problem is still there: in dark mode the Icons search field keeps its light background with light text. Since the docs moved to Rspress (#5004), this branch's CSS no longer reaches the site, and on main dark mode is marked by the dark class on html (there's no data-theme), with --rp-c-* variables instead of --ifm-*. Would you like to open the same fix against main, using html.dark .icons-list-searchbar? If not, we're happy to port it and credit you.

The install command now uses the alpha tag, because the untagged package
still installs 5.x. The page also states that 6.x requires React 19 and
the New Architecture, and the Customization example imports LightTheme
instead of the removed MD3LightTheme.

The Expo tab now installs @react-native-vector-icons/material-design-icons,
since Paper no longer falls back to @expo/vector-icons.
@mensonones

Copy link
Copy Markdown
Contributor Author

Closing in favor of #5158, which ports the fix to main using the Rspress dark-mode class and --rp-c-* variables (as suggested by @Doberjohn). This branch was based on 5.0 and no longer applies to the current docs.

@mensonones mensonones closed this Nov 3, 2026
@Doberjohn

Copy link
Copy Markdown
Collaborator

Thanks for closing (and opening the new one) @mensonones. I will take a look at the new one and get back to you!

This branch was successfully deployed

1 active deployment
github-pages — 4200dea1 Deployed Nov 3, 2026 by Doberjohn via Deploy docs #64
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.

Docs: Icon search in dark theme