Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/react/src/Dialog/Dialog.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,11 @@ body:not([data-dialog-scroll-optimized]):has(.Dialog.DisableScroll) {
}

/*
* PERFORMANCE OPTIMIZATION: Direct class on body - O(1) lookup
* PERFORMANCE OPTIMIZATION: Direct attribute on body - O(1) lookup
* Active when primer_react_css_has_selector_perf flag is ON
*/
body:global(.DialogScrollDisabled) {
/* stylelint-disable-next-line selector-no-qualifying-type */
body[data-dialog-scroll-disabled] {
/* stylelint-disable-next-line primer/spacing */
padding-right: var(--prc-dialog-scrollgutter) !important;
overflow: hidden !important;
Expand Down
12 changes: 6 additions & 6 deletions packages/react/src/Dialog/Dialog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,12 @@ describe('Footer button loading states', () => {
)

expect(document.body.hasAttribute('data-dialog-scroll-optimized')).toBe(true)
expect(document.body.classList.contains('DialogScrollDisabled')).toBe(true)
expect(document.body.hasAttribute('data-dialog-scroll-disabled')).toBe(true)

unmount()

expect(document.body.hasAttribute('data-dialog-scroll-optimized')).toBe(false)
expect(document.body.classList.contains('DialogScrollDisabled')).toBe(false)
expect(document.body.hasAttribute('data-dialog-scroll-disabled')).toBe(false)
})

it('handles multiple dialogs with ref counting when flag is ON', () => {
Expand All @@ -380,7 +380,7 @@ describe('Footer button loading states', () => {
)

expect(document.body.hasAttribute('data-dialog-scroll-optimized')).toBe(true)
expect(document.body.classList.contains('DialogScrollDisabled')).toBe(true)
expect(document.body.hasAttribute('data-dialog-scroll-disabled')).toBe(true)

// Render second dialog
const {unmount: unmount2} = render(
Expand All @@ -391,21 +391,21 @@ describe('Footer button loading states', () => {

// Attribute should still be present
expect(document.body.hasAttribute('data-dialog-scroll-optimized')).toBe(true)
expect(document.body.classList.contains('DialogScrollDisabled')).toBe(true)
expect(document.body.hasAttribute('data-dialog-scroll-disabled')).toBe(true)

// Unmount first dialog
unmount1()

// Attribute and class should still be present (second dialog is still open)
expect(document.body.hasAttribute('data-dialog-scroll-optimized')).toBe(true)
expect(document.body.classList.contains('DialogScrollDisabled')).toBe(true)
expect(document.body.hasAttribute('data-dialog-scroll-disabled')).toBe(true)

// Unmount second dialog
unmount2()

// Now both should be removed
expect(document.body.hasAttribute('data-dialog-scroll-optimized')).toBe(false)
expect(document.body.classList.contains('DialogScrollDisabled')).toBe(false)
expect(document.body.hasAttribute('data-dialog-scroll-disabled')).toBe(false)
})

it('handles multiple dialogs correctly when flag is OFF', () => {
Expand Down
8 changes: 5 additions & 3 deletions packages/react/src/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,9 @@ const _Dialog = React.forwardRef<HTMLDivElement, React.PropsWithChildren<DialogP
document.body.style.setProperty('--prc-dialog-scrollgutter', `${scrollbarWidth}px`)

if (usePerfOptimization) {
// Optimized path: set attribute and class on body
// Optimized path: set attributes on body
document.body.setAttribute('data-dialog-scroll-optimized', '')
document.body.classList.add('DialogScrollDisabled')
document.body.setAttribute('data-dialog-scroll-disabled', '')
} else {
// Legacy path: only add class (CSS :has() selector handles the rest)
document.body.classList.add('DialogScrollDisabled')
Expand All @@ -319,9 +319,11 @@ const _Dialog = React.forwardRef<HTMLDivElement, React.PropsWithChildren<DialogP
if (remainingDialogs.length === 0) {
// No more dialogs open, clean up body
document.body.style.removeProperty('--prc-dialog-scrollgutter')
document.body.classList.remove('DialogScrollDisabled')
if (usePerfOptimization) {
document.body.removeAttribute('data-dialog-scroll-optimized')
document.body.removeAttribute('data-dialog-scroll-disabled')
} else {
document.body.classList.remove('DialogScrollDisabled')
}
}
}
Expand Down
Loading