Skip to content

Conversation

@ArgoZhang
Copy link
Member

@ArgoZhang ArgoZhang commented Dec 22, 2025

Link issues

fixes #858

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Add UniverSheet integration with BootstrapBlazor theme change events to support automatic dark mode switching and proper cleanup on disposal.

New Features:

  • Automatically toggle UniverSheet dark mode in response to global BootstrapBlazor theme change events when the sheet is in auto mode.

Enhancements:

  • Register UniverSheet as a BootstrapBlazor module and ensure theme change event handlers are correctly attached and detached during component lifecycle.

Copilot AI review requested due to automatic review settings December 22, 2025 06:08
@bb-auto bb-auto bot added the enhancement New feature or request label Dec 22, 2025
@bb-auto bb-auto bot added this to the v9.2.0 milestone Dec 22, 2025
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 22, 2025

Reviewer's Guide

Adds automatic dark mode switching for UniverSheet by wiring it into BootstrapBlazor’s theme change events, including registration and cleanup of a theme-change handler and a helper to update UniverSheet instances based on the current theme.

Sequence diagram for UniverSheet automatic dark mode switching

sequenceDiagram
    actor User
    participant Browser
    participant BootstrapBlazorTheme as BootstrapBlazorThemeManager
    participant UniverSheetModule as UniverSheetModule
    participant UniverSheetInstance as UniverSheetInstance
    participant UniverAPI as UniverAPI

    User->>Browser: Toggle theme control
    Browser->>BootstrapBlazorTheme: Change theme
    BootstrapBlazorTheme-->>Browser: Dispatch changed.bb.theme event
    Browser->>UniverSheetModule: updateTheme(event)
    UniverSheetModule->>UniverSheetModule: Query .bb-univer-sheet elements
    UniverSheetModule->>UniverSheetInstance: Resolve instance from Data by id
    UniverSheetModule->>UniverSheetModule: Check darkMode is null
    UniverSheetModule->>UniverAPI: toggleDarkMode(theme == dark)
    UniverAPI-->>UniverSheetInstance: Apply dark or light theme
Loading

Flow diagram for UniverSheet init and theme event lifecycle

flowchart TD
    A[init called with id invoke options] --> B[Get DOM element by id]
    B --> C[createUniverSheetAsync]
    C --> D[Store instance in Data with id]
    D --> E[invoke TriggerReadyAsync]
    E --> F[registerBootstrapBlazorModule UniverSheet id]
    F --> G[EventHandler.on document changed.bb.theme updateTheme]

    G --> H[changed.bb.theme event fires]
    H --> I[updateTheme handler]
    I --> J[Query .bb-univer-sheet elements]
    J --> K[For each element get id]
    K --> L[Get univerSheet instance from Data]
    L --> M{univerSheet exists and darkMode is null}
    M -- Yes --> N[Call univerAPI.toggleDarkMode with theme is dark]
    M -- No --> O[Do nothing]

    P[dispose called with id] --> Q[Get univerSheet from Data]
    Q --> R[Call univerSheet.dispose if available]
    R --> S[Get UniverSheet from window.BootstrapBlazor]
    S --> T{UniverSheet exists}
    T -- Yes --> U[UniverSheet.dispose id callback]
    U --> V[EventHandler.off document changed.bb.theme updateTheme]
    T -- No --> W[Skip event handler cleanup]
Loading

File-Level Changes

Change Details Files
Wire UniverSheet instances into BootstrapBlazor module lifecycle and theme change events to support auto dark mode toggling.
  • Extend utility imports to include module registration and event handling helpers
  • After UniverSheet initialization, register a BootstrapBlazor module instance keyed by component id that subscribes to the global 'changed.bb.theme' document event
  • On dispose, invoke the UniverSheet module cleanup hook and detach the theme change listener for the disposed instance
  • Add an updateTheme handler that iterates all .bb-univer-sheet elements, reads their stored UniverSheet instances, and toggles dark mode based on the current theme when darkMode is not explicitly set
src/components/BootstrapBlazor.UniverSheet/Components/UniverSheet.razor.js

Assessment against linked issues

Issue Objective Addressed Explanation
#858 Implement automatic dark mode switching for UniverSheet based on the application/theme change events.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@ArgoZhang ArgoZhang merged commit 97c4e67 into master Dec 22, 2025
5 of 6 checks passed
@ArgoZhang ArgoZhang deleted the feat-univer branch December 22, 2025 06:09
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The global theme handler is attached with EventHandler.on(document, 'changed.bb.theme', updateTheme) on every init call, which can lead to multiple identical listeners; consider registering this handler once (e.g., globally or keyed by module name) rather than per sheet instance.
  • In updateTheme, querying document.querySelectorAll('.bb-univer-sheet') on every theme change and then resolving each instance via Data.get may be unnecessarily expensive; you could instead iterate directly over the stored UniverSheet instances in Data or maintain a registry of relevant IDs to avoid repeated DOM scanning.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The global theme handler is attached with `EventHandler.on(document, 'changed.bb.theme', updateTheme)` on every `init` call, which can lead to multiple identical listeners; consider registering this handler once (e.g., globally or keyed by module name) rather than per sheet instance.
- In `updateTheme`, querying `document.querySelectorAll('.bb-univer-sheet')` on every theme change and then resolving each instance via `Data.get` may be unnecessarily expensive; you could instead iterate directly over the stored UniverSheet instances in `Data` or maintain a registry of relevant IDs to avoid repeated DOM scanning.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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 adds automatic dark mode switching functionality to the UniverSheet component, allowing it to respond to theme changes in the BootstrapBlazor framework. When the application theme changes, UniverSheet instances will automatically toggle their dark mode (unless manually configured).

  • Implements theme change listener to automatically switch UniverSheet dark mode
  • Integrates with BootstrapBlazor's module system for proper lifecycle management
  • Bumps component version from 10.0.4 to 10.0.5

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
UniverSheet.razor.js Adds event handler registration for theme changes, implements updateTheme function to toggle dark mode, and updates dispose logic to clean up event listeners
BootstrapBlazor.UniverSheet.csproj Increments package version to 10.0.5

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

Comment on lines +56 to 71
const updateTheme = e => {
const theme = e.theme;

[...document.querySelectorAll('.bb-univer-sheet')].forEach(s => {
const id = s.getAttribute('id');
if (id) {
const univerSheet = Data.get(id);
if (univerSheet && univerSheet.darkMode === null) {
const { univerAPI } = univerSheet;
if (univerAPI) {
univerAPI.toggleDarkMode(theme === 'dark');
}
}
}
});
}
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The event handler cleanup logic has a potential issue. The updateTheme function is defined at module level, which means it's shared across all UniverSheet instances. When removing the event listener in dispose, it will remove the handler for ALL instances, not just the one being disposed. This will break theme switching for any remaining UniverSheet instances.

The DockView component handles this correctly by storing instance-specific handler references. Consider storing the updateTheme handler reference per instance in the Data store, similar to how DockView does it.

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +53
const { UniverSheet } = window.BootstrapBlazor;
if (UniverSheet) {
UniverSheet.dispose(id, () => {
EventHandler.off(document, 'changed.bb.theme', updateTheme);
});
}
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

Event handler registration happens inside the registerBootstrapBlazorModule callback, but cleanup happens conditionally based on window.BootstrapBlazor.UniverSheet existence. This creates an asymmetry - if the module system registers the handler but the global object isn't available during disposal, the event handler will leak.

Additionally, the handler is registered on document level for each instance, which means multiple instances will register the same handler multiple times. Consider registering the handler only once globally, or ensure proper cleanup that matches the registration pattern.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +70
[...document.querySelectorAll('.bb-univer-sheet')].forEach(s => {
const id = s.getAttribute('id');
if (id) {
const univerSheet = Data.get(id);
if (univerSheet && univerSheet.darkMode === null) {
const { univerAPI } = univerSheet;
if (univerAPI) {
univerAPI.toggleDarkMode(theme === 'dark');
}
}
}
});
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The updateTheme function queries all .bb-univer-sheet elements on every theme change, even if there's only one instance. This could impact performance if there are many instances. Additionally, the function doesn't verify that the queried elements are actual UniverSheet instances before attempting to retrieve data for them. Consider optimizing by only processing the relevant instance, or add validation before data retrieval.

Copilot uses AI. Check for mistakes.
import { isFunction, registerBootstrapBlazorModule } from '../../BootstrapBlazor/modules/utility.js'
import { createUniverSheetAsync } from '../univer.js'
import Data from '../../BootstrapBlazor/modules/data.js'
import EventHandler from "../../BootstrapBlazor/modules/event-handler.js"
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

Import statements are inconsistent with string quote usage. Lines 1, 2, and 3 use single quotes, but line 4 uses double quotes. For consistency, all import statements should use the same quote style.

Suggested change
import EventHandler from "../../BootstrapBlazor/modules/event-handler.js"
import EventHandler from '../../BootstrapBlazor/modules/event-handler.js'

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(UniverSheet): add auto switch darkmode function

2 participants