Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Centralize semantic tokens for Airflow UI by odaneau-astro · Pull Request #56347 · apache/airflow · GitHub
Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Centralize semantic tokens for Airflow UI by odaneau-astro · Pull Request #56347 · apache/airflow · GitHub
Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Centralize semantic tokens for Airflow UI by odaneau-astro · Pull Request #56347 · apache/airflow · GitHub
Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Centralize semantic tokens for Airflow UI by odaneau-astro · Pull Request #56347 · apache/airflow · GitHub
Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Centralize semantic tokens for Airflow UI by odaneau-astro · Pull Request #56347 · apache/airflow · GitHub
Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Centralize semantic tokens for Airflow UI by odaneau-astro · Pull Request #56347 · apache/airflow · GitHub
Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Centralize semantic tokens for Airflow UI by odaneau-astro · Pull Request #56347 · apache/airflow · GitHub
Skip to content

Centralize semantic tokens for Airflow UI - #56347

Closed
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens
Closed

Centralize semantic tokens for Airflow UI#56347
odaneau-astro wants to merge 125 commits into
apache:mainfrom
odaneau-astro:centralized_tokens

Conversation

@odaneau-astro

@odaneau-astroodaneau-astro commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

Semantic Tokens Design Plan

Goal

Establish a well-structured semantic tokens hierarchy that provides clear separation between primitive design tokens, system-level semantic tokens, and component-specific tokens. This will improve maintainability, consistency, and developer experience when working with the Airflow UI theme system.

Current State

The current theme structure mixes reference tokens and semantic tokens without a clear hierarchy. Component-specific tokens are scattered throughout the codebase, making it difficult to maintain consistency and update the design system.

Proposed Solution: 3-Layer Token Hierarchy

Layer 1: Reference Tokens

Definition: All available Chakra UI "primitive" tokens. These tokens make up all of the style options available in Chakra UI's design system. The tokens point to a static value.

Example: tokens.colors.blue.50 is defined as "oklch(0.97 0.014 254.604)"

Chakra UI Token Types:

Purpose: These are the foundational building blocks. They represent raw design values and should rarely be used directly in components.

Layer 2: System Tokens

Definition: Airflow UI-specific "global" semantic tokens. The tokens point to a reference token and provide semantic meaning.

Example: semanticTokens.colors.info.solid is defined as tokens.colors.blue.600

Current System Tokens:

  • brand.* - Brand colors (solid, fg, bg, muted, subtle, emphasized, contrast, focusRing)
  • warning.* - Warning/alert colors
  • danger.* - Danger/error colors
  • error.* - Error colors
  • info.* - Informational colors
  • active.* - Active state colors
  • Task state colors: none.*, scheduled.*, queued.*, running.*, success.*, restarting.*, failed.*, skipped.*, upstream_failed.*, up_for_retry.*, up_for_reschedule.*, deferred.*, removed.*
  • System tokens: sys.text.*, sys.background.*, sys.surface.*, sys.border.*, sys.interaction.*

Purpose: These tokens provide semantic meaning and can be used across multiple components. They abstract away the specific color values and allow for easy theme updates.

Layer 3: Component Tokens

Definition: Single-use component-specific tokens that don't fit into the system-level semantic tokens.

Purpose: These tokens are specific to individual components and should be used sparingly. They allow for component-specific customization while maintaining consistency with the overall design system.

Out of scope:

  1. Chakra UI's styles feature:
  1. Chakra UI's recipe feature for component variants.

- Implement comprehensive UI playground showcasing Chakra UI v3 components
- Add sections for color palette, buttons, forms, progress indicators, charts, and graphs
- Update to Chakra UI v3 API patterns and best practices
- Fix all linting and formatting issues
- Add proper accessibility features and semantic HTML
- Implement collapsible sections with consistent styling
- Add task instance states visualization with progress bars
- Include ReactFlow graph components matching DAGs view
- Add comprehensive color matrix display similar to Tailwind CSS
- Remove all custom margins/padding for consistent design
- Add proper TypeScript types and error handling
- Ensure full ESLint and Prettier compliance
Components added:
- Playground.tsx - Main playground page with state management
- ColorPaletteSection.tsx - Color palette matrix display
- ButtonsCodeSection.tsx - Button variations and code examples
- FormsInputsSection.tsx - Form controls and input examples
- ProgressTaskStatesSection.tsx - Progress bars and task states
- ChartsGanttSection.tsx - Chart.js integration with proper theming
- GraphSection.tsx - ReactFlow graph visualization
- BadgesAvatarsSection.tsx - Badge and avatar components
- ModalDialog.tsx - Modal and dialog examples
- TableOfContents.tsx - Navigation with expand/collapse controls
- forms/ - Individual form component examples
Fixes:
- All ESLint errors resolved with proper disable comments where needed
- Prettier formatting applied consistently
- TypeScript compilation errors resolved
- Chakra UI v3 API migration completed
- Accessibility improvements implemented
# Conflicts:
#	airflow-core/src/airflow/ui/src/theme.ts
@boring-cyborgboring-cyborgBot added the area:UI Related to UI/UX. For Frontend Developers. label Oct 2, 2025
@odaneau-astro
odaneau-astroforce-pushed the centralized_tokens branch 4 times, most recently from cc4e1e1 to fb2f695CompareOctober 3, 2025 10:29

@bbovenzibbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big fan of moving all our colors to semantic tokens.

I think a number of these colors are too specific like calendar.hour-label.color and test-connection.icon.connected and we should try reuse more values. If we have a one-off difference, we should see if we can adjust that HTML element to fit an existing pattern before creating a new color token

{isParsing ? (
<Center mt={2}>
<Spinner color="brand.solid" marginRight={2} size="sm" /> Parsing file...
<Spinner color="import-variables.spinner.color" marginRight={2} size="sm" /> Parsing file...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels oddly specific. I feel like brand.solid was perfectly fine as a semantic token?

failed: { value: "{colors.red.500}" },
running: { value: "{colors.cyan.500}" },
queued: { value: "{colors.yellow.500}" },
skipped: { value: "{colors.gray.400}" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think skipped is supposed to be pink, no?

@odaneau-astro

odaneau-astro commented Oct 29, 2025

Copy link
Copy Markdown
ContributorAuthor

I agree, I'll do a second pass to regroup tokens, especially for reusable ones like Spinners, Boxes, Task States, etc.

@bbovenzi

Copy link
Copy Markdown
Contributor

Some merge conflicts

@pierrejeambrun

Copy link
Copy Markdown
Member

Gently pinging to know where we are on this one, should we convert it to draft in the meantime?

@guan404ming

Copy link
Copy Markdown
Member

Hi, this one looks really interesting and valuable for our ui consistency. Could I help finish this one? Thanks!

@jscheffl

Copy link
Copy Markdown
Contributor

@odaneau-astro This PR has been converted to draft because it does not yet meet our Pull Request quality criteria.

Issues found:

  • Merge conflicts: This PR has merge conflicts with the main branch. Your branch is 2988 commits behind main. Please rebase your branch (git fetch origin && git rebase origin/main), resolve the conflicts, and push again. See contributing quick start.

Note: Your branch is 2988 commits behind main. Some check failures may be caused by changes in the base branch rather than by your PR. Please rebase your branch and push again to get up-to-date CI results.

What to do next:

  • The comment informs you what you need to do.
  • Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - but only after making sure that all the issues are fixed.
  • Maintainers will then proceed with a normal review.

Converting a PR to draft is not a rejection — it is an invitation to bring the PR up to the project's standards so that maintainer review time is spent productively. If you have questions, feel free to ask on the Airflow Slack.

@jscheffl
jscheffl marked this pull request as draft March 15, 2026 21:55
rich7420and others added 5 commits March 17, 2026 19:56
* fix MyPy type errors in log_reader.py
* fix ruff errors
* remove cast
* Fix mypy warnings for SQLA2 migration
* Revert soucing from TaskInstanceState from common.compat.sdk
* Migrate FAB POST /roles to FastAPI
* Remove unnecessary casting and model
* Validate non-empty role name via Pydantic
* Move auth dep to provider security and fixtureize dependency_overrides
* Add test for roles data model and security provider
uranusjrand others added 27 commits March 17, 2026 19:56
…perator Now Share Common Startup Logic (apache#56875)
* Move container-related functions from PodManager to a separate file
* Moved unit tests
* Sync and async workflow use the same code to track Pod startup
* Reworked unit tests and pod startup logic
* Add api permission error detection for triggerer
* Fix pytest fixture
* Removed not requried code
---------
Co-authored-by: AutomationDev85 <AutomationDev85>
* Fix MyPy type errors in providers utils/sql.py
* fix: ignore MyPy arg-type error in select().filter()
* Fix: cast filter clauses to ColumnElement for MyPy compatibility
* Refactor: remove unnecessary cast to ColumnElement in filter clauses
* Fix MyPy type errors in providers utils/utils.py
* Fix mypy error in utils.py by modify type hint for tasksState
It was wrong to load the serdag and not use it. The initial idea was
to use the serdag at line 437 but was omitted. Thinking about it now,
it will be faster to only load serdag when there's a TI associated
with the dag version
- Replace getReactFlowThemeStyle with useToken + graph.* semantic tokens
in Playground/graphs/Graph.tsx (new file added to main after branch diverged)
- Replace getComputedCSSVariableValue with resolveTokenValue in
Playground/charts/Charts.tsx (same rename from main's theme.ts)
Made-with: Cursor
@bbovenzi

Copy link
Copy Markdown
Contributor

This is 3000 commits behind now. If we still want to do this then I would recommend we just open a fresh PR.

@bbovenzibbovenzi closed this Apr 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UIRelated to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@odaneau-astro@bbovenzi@pierrejeambrun@guan404ming@jscheffl@rich7420@KoviAnusha@RoyLee1224@chiuinggum@aaron-y-chen@Dev-iL@ris-tlp@vincbeck@TyrellHaywood@o-nikolas@potiuk@wjddn279@gopidesupavan@olegkachur-e@dheerajturaga