Skip to content

refactor(ui): make design tokens dark-mode-ready (breakpoint 1)#28884

Open
chirag-madlani wants to merge 2 commits into
mainfrom
dark-theme-token-foundation
Open

refactor(ui): make design tokens dark-mode-ready (breakpoint 1)#28884
chirag-madlani wants to merge 2 commits into
mainfrom
dark-theme-token-foundation

Conversation

@chirag-madlani

Copy link
Copy Markdown
Collaborator

Breakpoint 1 — design-token foundation for dark mode

First of a stack of PRs adding dark theme. This one is the token plumbing only — it aligns the three styling layers (Tailwind/core-components, Ant Design, legacy Less) onto a single --color-* source of truth so dark mode can propagate without per-library color tables.

No toggle switch / activation in this PR — these tokens are inert and light mode is unchanged until dark mode is wired up in a later PR.

Root cause this fixes

The app compiles core-components Tailwind with prefix(tw), which freezes each @theme color into --tw-color-* at build time. The existing .dark-mode block sets the unprefixed --color-* names — which nothing reads at runtime. So dark-mode overrides were effectively dead.

Changes

  • globals.css — wrap the 374 @theme tokens that .dark-mode overrides as var(--token, <original>). Tailwind preserves the var() into --tw-color-*, so the existing .dark-mode block finally flips them at runtime. Light mode is byte-identical (the original value is the fallback).
  • variables.less — alias the standard @grey-50..900 scale (a byte-exact match to --color-gray-*), @background-color and @background-primary to the shared --tw-color-* tokens. Light unchanged, now dark-aware across all files that use the scale.
  • ExploreSearchCard — hardcoded card bg/border/highlight/muted-text hex → semantic tokens (reference conversion).
  • 3 fade(@grey-*) Less calls → color-mix() (Less color fns can't take var()).

Verification

  • Compiled the real app tailwind.css: 619 color vars compared light-mode vs. pre-change — zero differences.
  • Confirmed each touched token resolves at :root in light and flips under .dark-mode.
  • All changed .less files + app.less compile cleanly through the less renderer.

⚠️ Not yet visually validated in a running app (no dark-mode trigger exists until the activation PR). Light mode is verified unchanged.

🤖 Generated with Claude Code

Wire the legacy theming layers to the shared design-token source of truth
so dark mode can propagate without per-library color tables. No toggle
switch is included here; these tokens are inert until dark mode is
activated in a later PR.

- globals.css: wrap the 374 @theme color tokens that .dark-mode overrides
  as `var(--token, <original>)`. Tailwind's prefix(tw) freezes the light
  value into --tw-color-* at build time, so the .dark-mode block (which
  sets unprefixed --color-*) was never read at runtime. The var()
  indirection lets the existing .dark-mode overrides flip --tw-color-* at
  runtime. Light mode is byte-identical (the original value is the
  var() fallback).
- variables.less: alias the standard @grey-50..900 scale, @background-color
  and @background-primary to the shared --tw-color-* tokens. Light values
  are unchanged; they are now dark-aware.
- ExploreSearchCard: replace hardcoded card background/border/highlight and
  muted-text hex with semantic tokens.
- Convert 3 fade(@grey-*) Less calls to color-mix(), since Less color
  functions cannot operate on var() values.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chirag-madlani chirag-madlani requested review from a team and karanh37 as code owners June 9, 2026 15:23
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions github-actions Bot added safe to test Add this label to run secure Github workflows on PRs UI UI specific issues labels Jun 9, 2026
Comment thread openmetadata-ui/src/main/resources/ui/src/styles/variables.less Outdated
…Card light deltas

- variables.less: alias @Grey-25 to var(--tw-color-gray-25) (light #fdfdfd
  unchanged, now dark-aware) for consistency with the rest of the scale.
- ExploreSearchCard: pick closest light-matching tokens so the conversion
  no longer shifts light-mode colors:
    - card bg  #f8f9fc -> bg-secondary  (#fafafa, was bg-primary #ffffff)
    - muted text #757575 -> text-quaternary (#717680, was text-tertiary #535862)
  border (#eaecf5 -> #e9eaeb) and highlight (#eff8ff exact) were already
  within rounding. All four tokens remain dark-aware.

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

gitar-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Aligns Tailwind, Ant Design, and legacy Less styling layers onto shared design tokens to enable future dark mode support. Resolved previous light-mode color inconsistencies and CSS variable mapping issues.

✅ 2 resolved
Quality: @Grey-25 left as static hex, breaks dark-mode consistency

📄 openmetadata-ui/src/main/resources/ui/src/styles/variables.less:439-452
The neutral scale @grey-50..900 was aliased to the shared var(--tw-color-gray-*) tokens so they follow dark mode, but @grey-25 (line 439) was left as the static literal #fdfdfd. A matching --color-gray-25 token does exist in globals.css (it is wrapped as var(--color-gray-25, #fdfdfd) in this same PR), so the omission appears unintentional. The consequence is that anything using @grey-25 will stay light in dark mode while the rest of the grey scale flips — an inconsistency that surfaces in the later activation PR. Suggest aliasing it for consistency unless there is a specific reason to keep it static (in which case a comment would help).

Quality: ExploreSearchCard token swap changes light-mode colors

📄 openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/explore-search-card.less:21-22 📄 openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/explore-search-card.less:31 📄 openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreSearchCard/explore-search-card.less:42
Unlike the rest of the PR (which keeps light mode byte-identical via fallbacks), these ExploreSearchCard conversions change the rendered light-mode colors:

  • background-color: @grey-9 (#f8f9fc) → var(--tw-color-bg-primary) (white #ffffff)
  • border: ... #eaecf5var(--tw-color-border-secondary) (gray-200 #e9eaeb)
  • background: @primary-50 (#eff8ff) → var(--tw-color-bg-brand-primary) (brand-50)
  • color: @text-grey-muted (@grey-4) → var(--tw-color-text-tertiary) (gray-600 #535862)

The PR describes these as intentional 'reference conversions', so this is likely accepted, but it contradicts the 'light mode byte-identical' claim and these are user-visible deltas on a card component. Recommend a quick visual/design sign-off on the new light-mode appearance, or pick fallback-preserving tokens if no color change is intended.

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 62%
63.1% (66630/105579) 43.98% (36505/82988) 46.14% (10834/23480)

@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (8 flaky)

✅ 4254 passed · ❌ 0 failed · 🟡 8 flaky · ⏭️ 88 skipped

Shard Passed Failed Flaky Skipped
✅ Shard 1 299 0 0 4
🟡 Shard 2 801 0 2 9
🟡 Shard 3 801 0 2 8
🟡 Shard 4 844 0 1 12
🟡 Shard 5 718 0 1 47
🟡 Shard 6 791 0 2 8
🟡 8 flaky test(s) (passed on retry)
  • Features/Glossary/GlossaryTermRelationsGraph.spec.ts › search in the Relations Graph filters to matching node and its neighbours (shard 2, 1 retry)
  • Features/Glossary/GlossaryWorkflow.spec.ts › should start term as Draft when glossary has reviewers (shard 2, 1 retry)
  • Features/KnowledgeCenter.spec.ts › Article mentions in description should working for Knowledge Center (shard 3, 1 retry)
  • Features/UserProfileOnlineStatus.spec.ts › Should show "Active recently" for users active within last hour (shard 3, 1 retry)
  • Pages/CustomProperties.spec.ts › Markdown (shard 4, 1 retry)
  • Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts › Should remove user owner for knowledgeCenter (shard 5, 1 retry)
  • Pages/Lineage/DataAssetLineage.spec.ts › Column lineage for dashboardDataModel -> dashboardDataModel (shard 6, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify lineage schema filter selection (shard 6, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant