Skip to content

refactor(react-portal): remove Griffel dependency from usePortalMountNode#35994

Merged
dmytrokirpa merged 12 commits intomasterfrom
refactor/portal-mount-node-griffel
Apr 16, 2026
Merged

refactor(react-portal): remove Griffel dependency from usePortalMountNode#35994
dmytrokirpa merged 12 commits intomasterfrom
refactor/portal-mount-node-griffel

Conversation

@dmytrokirpa
Copy link
Copy Markdown
Contributor

@dmytrokirpa dmytrokirpa commented Apr 16, 2026

Context

Portal is used in many Fluent UI components (Dialog, Tooltip, Popover, etc.) as part of their render methods. We are introducing headless components that need to be re-usable in non-Fluent environments — environments that may not have Griffel set up. Because Portal was previously importing @griffel/react to apply styles to its mount node, it was pulling Griffel in as a transitive dependency of every component that uses Portal. This change removes that dependency.

Previous Behavior

usePortalMountNode used a Griffel makeStyles() hook to apply position: absolute, top/left/right: 0, and z-index: 1000000 to the portal mount node via a generated atomic CSS class. This required @griffel/react at runtime.

New Behavior

The portal mount node styles are now applied via a dynamically injected <style> element using a stable, using the existing attribute [data-portal-node]. The injection logic lives in the new usePortalMountNodeStyles hook, which:

  • Injects a single shared <style> element per document (supporting iframes) using a WeakMap-based reference count
  • Removes the <style> element when the last portal using that document unmounts
  • Returns the class name so it can be composed into the mount node's className alongside theme and consumer classes

This is not a breaking change:

  • Consumers can override individual properties (e.g. position: fixed) via their own class names passed through mountNode={{ className: '...' }}
  • The existing Storybook example using mountNode with custom styles confirms the override behavior works correctly
  • z-index, position, and other properties are all still applied
Screenshot 2026-04-16 at 10 52 18

Related Issue(s)

  • Fixes #

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 16, 2026

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-charts
AreaChart
412.511 kB
126.45 kB
412.925 kB
126.644 kB
414 B
194 B
react-charts
DeclarativeChart
763.273 kB
220.535 kB
763.687 kB
220.664 kB
414 B
129 B
react-charts
DonutChart
322.93 kB
97.01 kB
323.344 kB
97.162 kB
414 B
152 B
react-charts
FunnelChart
314.483 kB
94.069 kB
314.891 kB
94.176 kB
408 B
107 B
react-charts
GanttChart
395.62 kB
119.97 kB
396.033 kB
120.15 kB
413 B
180 B
react-charts
GaugeChart
322.361 kB
96.466 kB
322.777 kB
96.591 kB
416 B
125 B
react-charts
GroupedVerticalBarChart
403.492 kB
122.546 kB
403.908 kB
122.719 kB
416 B
173 B
react-charts
HeatMapChart
397.691 kB
121.832 kB
398.105 kB
122.05 kB
414 B
218 B
react-charts
HorizontalBarChart
302.658 kB
89.15 kB
303.074 kB
89.306 kB
416 B
156 B
react-charts
Legends
242.552 kB
71.625 kB
242.965 kB
71.798 kB
413 B
173 B
react-charts
LineChart
423.849 kB
128.529 kB
424.265 kB
128.706 kB
416 B
177 B
react-charts
PolarChart
351.497 kB
107.403 kB
351.913 kB
107.57 kB
416 B
167 B
react-charts
SankeyChart
220.432 kB
67.873 kB
220.845 kB
68 kB
413 B
127 B
react-charts
ScatterChart
403.231 kB
122.654 kB
403.647 kB
122.833 kB
416 B
179 B
react-charts
VerticalBarChart
439.961 kB
128.242 kB
440.377 kB
128.322 kB
416 B
80 B
react-charts
VerticalStackedBarChart
409.503 kB
124.059 kB
409.919 kB
124.239 kB
416 B
180 B
react-combobox
Combobox (including child components)
105.599 kB
34.274 kB
106.012 kB
34.448 kB
413 B
174 B
react-combobox
Dropdown (including child components)
106.23 kB
34.229 kB
106.643 kB
34.38 kB
413 B
151 B
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
236.774 kB
68.762 kB
237.187 kB
68.891 kB
413 B
129 B
react-components
react-components: entire library
1.3 MB
324.826 kB
1.3 MB
324.941 kB
414 B
115 B
react-datepicker-compat
DatePicker Compat
225.158 kB
63.633 kB
225.627 kB
63.656 kB
469 B
23 B
react-menu
Menu (including children components)
170.393 kB
51.915 kB
170.806 kB
52.028 kB
413 B
113 B
react-menu
Menu (including selectable components)
173.571 kB
52.494 kB
173.984 kB
52.61 kB
413 B
116 B
react-popover
Popover
133.719 kB
41.451 kB
134.131 kB
41.552 kB
412 B
101 B
react-portal
Portal
15.55 kB
5.394 kB
11.219 kB
3.602 kB
-4.331 kB
-1.792 kB
react-tag-picker
@fluentui/react-tag-picker - package
186.766 kB
55.907 kB
187.178 kB
55.977 kB
412 B
70 B
react-timepicker-compat
TimePicker
108.565 kB
35.848 kB
108.977 kB
36.038 kB
412 B
190 B
react-toast
Toast (including Toaster)
102.56 kB
30.608 kB
102.974 kB
30.718 kB
414 B
110 B
react-tooltip
Tooltip
57.105 kB
19.698 kB
57.52 kB
19.808 kB
415 B
110 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-avatar
Avatar
48.479 kB
15.359 kB
react-avatar
AvatarGroup
17.482 kB
7.002 kB
react-avatar
AvatarGroupItem
61.867 kB
19.384 kB
react-breadcrumb
@fluentui/react-breadcrumb - package
115.162 kB
31.475 kB
react-charts
HorizontalBarChartWithAxis
63 B
83 B
react-charts
Sparkline
91.4 kB
28.708 kB
react-checkbox
Checkbox
33.7 kB
11.421 kB
react-components
react-components: Button, FluentProvider & webLightTheme
70.397 kB
19.96 kB
react-components
react-components: FluentProvider & webLightTheme
43.612 kB
14.022 kB
react-dialog
Dialog (including children components)
102.117 kB
30.367 kB
react-field
Field
22.393 kB
8.39 kB
react-input
Input
26.28 kB
8.702 kB
react-list
List
87.11 kB
25.762 kB
react-list
ListItem
111.018 kB
32.682 kB
react-overflow
hooks only
12.117 kB
4.627 kB
react-persona
Persona
55.434 kB
17.299 kB
react-portal-compat
PortalCompatProvider
8.386 kB
2.624 kB
react-positioning
usePositioning
28.889 kB
10.158 kB
react-positioning
useSafeZoneArea
12.445 kB
5 kB
react-progress
ProgressBar
20.212 kB
7.863 kB
react-radio
Radio
31.087 kB
9.656 kB
react-radio
RadioGroup
14.035 kB
5.7 kB
react-select
Select
26.165 kB
9.472 kB
react-slider
Slider
36.359 kB
12.03 kB
react-spinbutton
SpinButton
33.804 kB
11.125 kB
react-swatch-picker
@fluentui/react-swatch-picker - package
104.305 kB
29.944 kB
react-switch
Switch
36.333 kB
11.067 kB
react-table
DataGrid
159.783 kB
45.012 kB
react-table
Table (Primitives only)
40.997 kB
13.172 kB
react-table
Table as DataGrid
131.005 kB
36.012 kB
react-table
Table (Selection only)
69.391 kB
19.404 kB
react-table
Table (Sort only)
68.034 kB
19.022 kB
react-tags
InteractionTag
13.724 kB
5.47 kB
react-tags
Tag
29.648 kB
9.429 kB
react-tags
TagGroup
82.247 kB
24.152 kB
react-teaching-popover
TeachingPopover
112.414 kB
34.219 kB
react-textarea
Textarea
24.668 kB
8.969 kB
react-tree
FlatTree
148.099 kB
42.211 kB
react-tree
PersonaFlatTree
149.927 kB
42.585 kB
react-tree
PersonaTree
145.987 kB
41.411 kB
react-tree
Tree
144.165 kB
41.037 kB
🤖 This report was generated against e367467f8a3b1bb66f7b56217fcfd327ddd4ec84

@github-actions
Copy link
Copy Markdown

Pull request demo site: URL

@dmytrokirpa dmytrokirpa changed the title Refactor/portal mount node griffel refactor(react-portal): remove Griffel dependency from usePortalMountNode Apr 16, 2026
@dmytrokirpa dmytrokirpa marked this pull request as ready for review April 16, 2026 09:19
@dmytrokirpa dmytrokirpa requested a review from a team as a code owner April 16, 2026 09:19
…Element in value

Agent-Logs-Url: https://github.com/microsoft/fluentui/sessions/1388006f-49a7-4046-98e1-183a3df92ed0

Co-authored-by: layershifter <14183168+layershifter@users.noreply.github.com>
Copilot AI and others added 2 commits April 16, 2026 09:37
…ule for style injection

Agent-Logs-Url: https://github.com/microsoft/fluentui/sessions/eb7347c6-eac4-4401-8a91-75a630f87ca6

Co-authored-by: layershifter <14183168+layershifter@users.noreply.github.com>
…unter type, head.querySelector

Agent-Logs-Url: https://github.com/microsoft/fluentui/sessions/eb7347c6-eac4-4401-8a91-75a630f87ca6

Co-authored-by: layershifter <14183168+layershifter@users.noreply.github.com>
Copilot AI and others added 3 commits April 16, 2026 09:50
…getDocument

Agent-Logs-Url: https://github.com/microsoft/fluentui/sessions/46eebcbb-9695-4cee-953d-5b71aab87cab

Co-authored-by: layershifter <14183168+layershifter@users.noreply.github.com>
…d use in test cleanup

Agent-Logs-Url: https://github.com/microsoft/fluentui/sessions/05960f41-5ea6-4363-9fe0-70657b13acca

Co-authored-by: layershifter <14183168+layershifter@users.noreply.github.com>
@dmytrokirpa dmytrokirpa merged commit 48ff10f into master Apr 16, 2026
15 checks passed
@dmytrokirpa dmytrokirpa deleted the refactor/portal-mount-node-griffel branch April 16, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants