microsoft / microsoft/vscode-documentdb
[vscode-ext-webview-fluentui] Support consumer theme overrides on VSCodeFluentProvider
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 31
- Forks
- 22
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 21
Description
Enhancement
Add an optional, typed themeOverrides?: Partial<Theme> prop to VSCodeFluentProvider in @microsoft/vscode-ext-webview-fluentui.
The package should own theme detection, reactive color updates, palette generation and shared mappings, while consumers can retain intentional application-specific token choices without copying the theme engine.
Context from Cosmos DB adoption
We are adopting version 1.1.0 in microsoft/vscode-cosmosdb for Fluent and Monaco theming only. No optional component migration is involved.
The original Cosmos adaptive theme kept colorNeutralForeground1Selected on --vscode-editor-foreground. In dark mode, colorNeutralForeground2Selected used --vscode-foreground. The package instead maps those selected foregrounds to --vscode-list-inactiveSelectionForeground, with an editor-foreground fallback, and maps selected neutral backgrounds to inactive-list selection backgrounds.
This is a meaningful semantic change, not necessarily a bug. Fluent selected tokens can be consumed by different component recipes; selected does not always mean an inactive VS Code list row. Foreground and background must be evaluated together, and active selection, inactive selection, focus and pressed states must remain distinct. We have not established that the old Cosmos mappings are universally preferable, so this request is not to restore them as package defaults.
Cosmos also has intentional control-specific styles that should remain local:
- react-data-grid uses paired active-selection foreground/background colors and a focus-border token.
- Quick Start popovers explicitly map widget foreground/background, border and arrow outline for contrast.
Centralization should remove duplicated theme machinery, not prohibit such styling.
Proposed contract
- Obtain the base theme through the existing reactive
useActiveVSCodeTheme()hook. - Merge consumer overrides after the generated theme without mutating the shared object.
- Reapply the merge when the base theme or override props change, including same-kind theme switches and CSS-only color customizations.
- Preserve current behavior when overrides are omitted. An empty override object should behave equivalently.
- Support existing CSS variable expressions as token values.
- Define behavior for an unrecognized theme kind, where the base theme is undefined, and for explicitly undefined override values. Recommended: undefined values should not erase generated defaults.
- Preserve existing children and provider behavior. No new theme observer, stylesheet plugin system or Monaco dependency.
Example proposed usage:
<VSCodeFluentProvider themeOverrides={applicationThemeOverrides}>
<App />
</VSCodeFluentProvider>
This is a convenience API, not a missing fundamental capability. Today consumers can use useActiveVSCodeTheme() and merge overrides into a standard Fluent FluentProvider. Keep and document that lower-level option, including theme-kind-specific composition. A callback-based override API can be considered later if real use cases justify it.
Important CSS boundary
Importing the package root injects document-global component adaptations, including for portals. Some rules declare token variables directly on field controls. A provider-level token override is inherited and will not necessarily win against a declaration on the control itself, even though the package selector uses zero-specificity :where().
Document clearly that themeOverrides customizes provider tokens, not every component adaptation. A consumer may need scoped CSS for a specific control. Portal styling needs a class on the rendered portal surface rather than relying only on an application-root descendant selector. Do not advertise the prop as a universal override mechanism.
Acceptance criteria
- Tests for omitted, empty and populated overrides; changed props; immutable base themes; and defined handling of undefined values/base themes.
- Tests showing overrides survive light/dark, high-contrast, same-kind and root-style-only updates while unmodified tokens still follow the package.
- Documentation for simple token overrides, theme-kind-specific hook composition, and component-local CSS including portals.
- Selection examples evaluate foreground/background pairs and distinguish selection from focus.
- No changes to existing selection defaults solely to accommodate Cosmos. Shared mapping correctness and inherited high-contrast/neutral-token gaps should be evaluated separately with visual evidence.
References
- Reference adoption: https://github.com/tnaum-ms/vscode-webview-starter-kit/commit/82d0da55534ca0e6323e51793e779b99ac439de0
- Consumer grid styles: https://github.com/microsoft/vscode-cosmosdb/blob/main/src/webviews/cosmosdb/QueryEditor/ResultPanel/ReactDataGrid/vscodeTheme.scss
- Consumer Quick Start styles: https://github.com/microsoft/vscode-cosmosdb/blob/main/src/webviews/cosmosdb/QueryEditor/quickStart/QuickStartProvider.tsx
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at VSCodeFluentProvider and the existing useActiveVSCodeTheme() hook, then inspect the package's provider behavior and root documentation. Cover omitted, empty, populated, changed, and undefined overrides across theme and CSS-only updates, while preserving immutable base themes and existing children. Use the acceptance criteria to define the tests and document the provider-versus-component CSS boundary, including portals.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- devtools, frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100