Skip to content

Conversation

@JasonXuDeveloper
Copy link
Owner

@JasonXuDeveloper JasonXuDeveloper commented Jan 28, 2026

Summary

Modernizes JEngine's Unity Editor UI with a clean, professional monochrome design system inspired by shadcn/ui. The new design features true grayscale inversion between light and dark themes, improved visual hierarchy, and performance optimizations.

Key Changes

🎨 Design System

  • Monochrome color palette: Pure neutral greys (R=G=B) with no color tints
  • True theme inversion: Dark theme colors are exact inversions of light theme
    • Light Primary (#374151) ↔ Dark Secondary (#374151)
    • Light Secondary (#D0D0D0) ↔ Dark Primary (#D0D0D0)
  • 5-layer background system: Base, Subtle, Surface, Elevated, Overlay
  • Improved contrast: All colors meet WCAG AA standards
  • Differentiated inputs: Input fields now have distinct backgrounds from surrounding surfaces

📦 New Package Structure

  • Extracted MessageBox to separate com.jasonxudeveloper.jengine.ui package
  • Includes complete component library: buttons, forms, layout, feedback components
  • Theme-aware design tokens system in Tokens.cs

🧩 Components

Layout:

  • JCard, JSection, JStack, JRow, JBreadcrumb

Forms:

  • JTextField, JObjectField, JDropdown, JToggle, JFormField

Buttons:

  • JButton, JToggleButton (with Primary/Secondary variants)

Feedback:

  • JStatusBar, JLogView, JProgressBar

All components feature:

  • Consistent styling with design tokens
  • Smooth 200ms transitions
  • Proper hover/focus states
  • Theme-aware colors

⚡ Performance Improvements

  • Eliminated closure allocations: Replaced 14 lambda closures with static lambdas + state parameters (C#9)
  • Optimized event handlers: Used static methods to avoid heap allocations
  • Affected files: JBreadcrumb, JCard, JStack, JToggle, JObjectField, JTextField

🎯 Visual Improvements

Dark Theme:

  • Pure neutral greys: #0A0A0A, #1A1A1A, #2A2A2A, #353535, #374151
  • Lighter input backgrounds (#353535) for better differentiation
  • Visible separators/dividers (#454545 BorderSubtle)
  • Lighter log view background (#252525 BgSubtle)

Light Theme:

  • Preserved original clean aesthetic
  • No changes to colors

Both Themes:

  • Primary buttons use consistent text colors (PrimaryText token)
  • Secondary buttons maintain proper contrast
  • Toggle switches match button color scheme
  • Status bars use neutral grey (no colored backgrounds)

📝 Documentation

  • Restructured CLAUDE.md into modular rules
  • Added package creation guidelines
  • Updated copilot instructions with design token references

Testing

  • Verified dark theme inversion is accurate
  • Tested all button states (hover, active, disabled)
  • Confirmed input field visibility in both themes
  • Checked separator/divider visibility
  • Validated toggle component colors match buttons
  • Tested Bootstrap inspector and JEngine Panel UIs

Breaking Changes

None. All changes are internal to the new UI package. Existing code is unaffected.

Screenshots

Before

Original dark theme with blue-tinted colors and less contrast

After

Clean monochrome design with true grayscale inversion:

  • Dark theme: Pure neutral greys with proper hierarchy
  • Light theme: Unchanged (preserved original design)
  • All inputs clearly differentiated from surfaces
  • Consistent button styling across themes

Design Philosophy: Shadcn-style monochrome with professional, clean aesthetics. Dark theme is a perfect grayscale inversion of light theme for consistency.

Co-Authored-By: Claude Sonnet 4.5 [email protected]

Make core lightweight by extracting MessageBox with an abstraction layer:

- Add Prompt abstraction in core for user dialogs (delegate-based)
- Create new jengine.ui package for UI utilities
- Move MessageBox from core to ui package (namespace: JEngine.UI)
- Update Bootstrap to use Prompt.ShowDialogAsync instead of MessageBox
- Add PromptInitializer.cs for easy UI integration

Package structure after changes:
- jengine.core: Independent hot update only, with Prompt abstraction
- jengine.ui: Optional UI utilities (MessageBox)

Users can customize prompt behavior by:
1. Using the default MessageBox via PromptInitializer
2. Implementing custom dialog providers

This keeps core non-invasive (无侵入式) for hot updates while allowing
UI customization through the optional ui package.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Copilot AI review requested due to automatic review settings January 28, 2026 11:49
@github-actions github-actions bot added documentation Improvements or additions to documentation ci core tests editor labels Jan 28, 2026
JasonXuDeveloper and others added 14 commits January 28, 2026 22:50
- Make ShowDialogAsync thread-safe with volatile backing field and Interlocked.Exchange
- Improve XML documentation for Prompt class with usage examples
- Change default behavior to log error and return false (safer default)
- Add namespace to PromptInitializer (JEngine)
- Add TextMeshPro dependency to jengine.ui package.json
- Remove JEngine.UI dependency from HotUpdate.Code (use Prompt abstraction instead)
- Update EntryPoint.cs to use Prompt.ShowDialogAsync instead of MessageBox.Show

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
- Use null-coalescing in getter instead of field initializer
- Remove namespace from PromptInitializer (user-level code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
HotUpdate code should not directly depend on utility packages.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
New package should start at 0.0.0.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
- New packages should start at version 0.0.0
- Document naming convention and required files
- Add ui scope to commit message conventions

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Split verbose CLAUDE.md (295 lines) into focused files:
- .claude/rules/commit-conventions.md
- .claude/rules/package-creation.md
- .claude/rules/coding-patterns.md

Main CLAUDE.md now 84 lines with essential info only.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
- Add @imports to CLAUDE.md for .claude/rules/ files
- Update copilot instructions to allow no-namespace code in Assets/Scripts/
- Add JEngine.UI namespace to instruction files

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Major UI overhaul implementing shadcn-inspired design with glassmorphic
elements in dark mode and clean monochromatic styling in light mode.

## New UI Package (com.jasonxudeveloper.jengine.ui)

### Components
- **Button**: JButton, JToggleButton, JButtonGroup with 5 variants
- **Form**: JFormField, JTextField, JDropdown, JToggle, JObjectField
- **Layout**: JCard, JSection, JStack, JRow for composition
- **Feedback**: JStatusBar, JLogView, JProgressBar
- **Navigation**: JBreadcrumb with clean hierarchical display

### Theme System
- Design tokens (Tokens.cs) with dark/light theme support
- Glassmorphic palette for dark mode (translucent layers, vibrant accents)
- shadcn-style monochromatic palette for light mode (black/white/grey only)
- 8px spacing grid, typography scale, border radius system
- Smooth transitions (150-300ms)

### Enhanced Editor UIs
- BootstrapEditorUI: Redesigned Bootstrap inspector with modern components
- PanelUI: Redesigned Panel window with enhanced scene management

## Core Package Improvements

### Code Deduplication
- **EditorUtils.cs**: Extracted 6 shared helper methods from BootstrapEditor
  and BootstrapEditorUI (GetAvailableAsmdefFiles, GetAvailableHotScenes,
  GetAvailableHotClasses, GetAvailableHotMethods,
  GetAvailableDynamicSecretKeys, GetAvailableAOTDataFiles)
- **BuildHelper.cs**: New shared build execution logic with UI callbacks,
  eliminating ~200 lines of duplication between Panel.cs and PanelUI.cs

### Bug Fixes
- Panel.cs: Added null checks in LogMessage to prevent crashes when using
  enhanced PanelUI
- PanelUI: Creates its own BuildManager with proper log routing to JLogView

## Design Decisions

### Light Theme Philosophy
- Monochromatic black/white/grey only (no colors except semantic highlights)
- Buttons use grey shades (Primary: gray-700, Secondary: gray-300)
- Clean, minimal aesthetic inspired by shadcn/ui

### Dark Theme Philosophy
- Glassmorphic translucent layers (40-80% opacity)
- Vibrant cyan accents (#06B6D4) with subtle glow effects
- 5-level glass system (Base → Subtle → Surface → Elevated → Overlay)

### Component Patterns
- Fluent API for chaining (.WithText().FullWidth())
- Consistent spacing and sizing across all components
- Theme-aware colors (automatically adapt to Unity editor theme)
- Proper keyboard navigation with visible focus states

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Replace lambda closures with static lambdas and state parameters to avoid
heap allocations in RegisterCallback calls. Updated 6 component files:

- JBreadcrumb: static methods with state parameters
- JCard: instance methods
- JStack: static lambda with tuple state
- JToggle: static lambdas with state parameters
- JObjectField: instance methods + static lambdas with state
- JTextField: static lambdas with state parameters

This improves performance by eliminating 14 closure allocations across
the UI toolkit components using C#9 static lambda support.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Replace vibrant glassmorphic design with clean monochrome palette where
dark theme is the grayscale inversion of light theme.

Changes:
- Remove all vibrant accent colors (cyan, emerald, rose, amber)
- Dark theme now uses black/white/greys inverted from light theme
- Light theme colors remain unchanged
- Remove opacity-based glass layers, use solid greys
- Update JToggle to use Primary/Secondary instead of Accent
- Simplify comments to reflect new monochrome approach

Color mapping (dark theme inverted from light):
- BgBase: #0F1419 (near-black) ← #FFFFFF (white)
- BgSurface: #374151 (gray-700) ← #E5E7EB (gray-200)
- TextPrimary: #FFFFFF (white) ← #111827 (gray-900)
- Primary: #D1D5DB (gray-300) ← #374151 (gray-700)
- Borders: #4B5563 (gray-600) ← #D1D5DB (gray-300)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Improved dark theme to use truly neutral RGB greys (R=G=B) instead of
blue-tinted colors. Fixed three visual issues from user feedback:

1. Primary button color too dark - changed dark theme to use lighter
   #C8C8C8 grey for better contrast with white text
2. Status bar showing blue - removed colored backgrounds in dark mode,
   now uses neutral grey like light mode (monochrome design)
3. Log view too black - changed from BgBase (#0A0A0A) to BgSubtle
   (#1A1A1A) for slightly lighter background

Color changes (dark theme only, light theme unchanged):
- BgBase: #0F1419 → #0A0A0A (pure neutral black)
- BgSubtle: #1F2937 → #1A1A1A (pure neutral dark grey)
- BgSurface: #374151 → #2A2A2A (pure neutral grey)
- BgElevated: #4B5563 → #3A3A3A (pure neutral medium-dark grey)
- BgOverlay: #6B7280 → #4A4A4A (pure neutral medium grey)
- Primary: #D1D5DB → #C8C8C8 (lighter for better button contrast)
- All text/borders now use neutral greys (#FFFFFF, #D0D0D0, etc.)

JStatusBar now uses monochrome design in both themes (no colored
backgrounds in dark mode).

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
…trast

Fixed multiple visual issues in dark theme based on user feedback:

1. Button colors now properly inverted:
   - Dark Primary (#D0D0D0) = Light Secondary
   - Dark Secondary (#374151) = Light Primary
   - True grayscale inversion between themes

2. Input field backgrounds differentiated:
   - New BgInput color (#353535) lighter than BgSurface in dark mode
   - Applies to JTextField, JObjectField, and JDropdown
   - Better visual separation from surrounding surface

3. Toggle styling fixed:
   - Track colors match Primary/Secondary button colors
   - Thumb stays white in both themes (no inversion)

4. Separator/divisor visibility improved:
   - BorderSubtle lightened to #454545 in dark mode
   - Now visible against darker backgrounds

5. Button text colors use theme tokens:
   - JButton and JToggleButton use PrimaryText/SecondaryText
   - No more hardcoded Color.white
   - Dark Primary buttons now have black text (#111111)

6. Log view lightened:
   - Uses BgSubtle (#252525) instead of BgBase
   - More readable background

Color mapping (dark theme):
- Primary: #D0D0D0 (light grey, black text)
- Secondary: #374151 (dark grey, white text)
- BgInput: #353535 (for inputs)
- BgSubtle: #252525 (for log view)
- BorderSubtle: #454545 (for separators)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
Fixed Primary button hover and active states to properly invert with light
theme's Secondary colors:

Dark mode Primary (was wrong):
- Hover: #E0E0E0 → #9A9A9A (now matches light's SecondaryHover)
- Active: #C0C0C0 → #6A6A6A (now matches light's SecondaryActive)

Now the inversion is complete and consistent across all button states.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: JasonXuDeveloper - 傑 <[email protected]>
@JasonXuDeveloper JasonXuDeveloper force-pushed the feat/ui-modernization-shadcn-style branch from 58faf0e to 3859505 Compare January 28, 2026 11:51
@github-actions
Copy link

github-actions bot commented Jan 28, 2026

Unity Test Results

EditMode: All tests passed
PlayMode: All tests passed

Unity Version: 2022.3.55f1
Project Path: UnityProject

✅ All tests passed! The PR is ready for review.

View workflow run

Click here to view the full workflow run

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR modernizes JEngine's Unity Editor UI by introducing a new com.jasonxudeveloper.jengine.ui package with a clean, professional monochrome design system. The changes extract MessageBox from the core package, create a new Prompt abstraction layer, add comprehensive UI components with performance optimizations, and enhance editor integration with extensible handler registration.

Changes:

  • New UI package with monochrome design system (Tokens, JTheme, 15+ components)
  • MessageBox extraction from core with test infrastructure (TestHandler, SimulateNoPrefab)
  • Prompt abstraction layer for dialog provider decoupling with thread-safe registration
  • Performance optimizations using static lambdas to eliminate closure allocations
  • Enhanced editor integration with handler registration pattern for PanelUI and BootstrapEditorUI

Reviewed changes

Copilot reviewed 109 out of 109 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
com.jasonxudeveloper.jengine.ui/* New package with UI components, theming system, and MessageBox
MessageBox.cs Moved to UI package with testability features (InternalsVisibleTo, TestHandler)
Prompt.cs New abstraction layer for dialogs with thread-safe registration
Bootstrap.cs Updated to use Prompt.ShowDialogAsync instead of MessageBox.Show
Panel.cs Added CreatePanelContentHandler for UI package integration
BootstrapEditor.cs Added CreateInspectorHandler, moved helper methods to EditorUtils
EditorUtils.cs New helper methods for package/assembly/scene discovery
BuildHelper.cs Extracted build execution logic with callback pattern
PromptInitializer.cs Runtime initializer to register MessageBox as dialog provider
.github/workflows/* Updated release and test workflows for UI package
CLAUDE.md Restructured into modular rules files

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

Comment on lines +46 to +58
foreach (var button in buttons)
{
if (button != null)
{
// Apply group styling to buttons - compact
button.style.marginRight = Tokens.Spacing.Sm;
button.style.marginBottom = Tokens.Spacing.Xs;
button.style.flexGrow = 1;
button.style.flexShrink = 0;
button.style.minWidth = 100;
base.Add(button);
}
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +83
foreach (var child in children)
{
if (child != null)
{
base.Add(child);
}
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +83
foreach (var button in buttons)
{
if (button != null)
{
button.style.marginRight = Tokens.Spacing.Sm;
button.style.marginBottom = Tokens.Spacing.Xs;
button.style.flexGrow = 1;
button.style.flexShrink = 0;
button.style.minWidth = 100;
base.Add(button);
}
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
Comment on lines +105 to +111
foreach (var child in children)
{
if (child != null)
{
_fields.Add(child);
}
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
Comment on lines +149 to +155
foreach (var child in children)
{
if (child != null)
{
_controlContainer.Add(child);
}
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +98
foreach (var child in children)
{
if (child != null)
{
_content.Add(child);
}
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
@JasonXuDeveloper
Copy link
Owner Author

Closing to recreate PR from correct base (master already has MessageBox extraction from #590)

@JasonXuDeveloper JasonXuDeveloper deleted the feat/ui-modernization-shadcn-style branch January 28, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci core documentation Improvements or additions to documentation editor tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants