@@ -10,6 +10,12 @@ import Text from '../Text'
1010import type { ComponentProps } from '../utils/types'
1111import { useRefObjectAsForwardedRef } from '../hooks/useRefObjectAsForwardedRef'
1212import { XIcon } from '@primer/octicons-react'
13+ import { toggleStyledComponent } from '../internal/utils/toggleStyledComponent'
14+ import { useFeatureFlag } from '../FeatureFlags'
15+ import { clsx } from 'clsx'
16+ import classes from './Dialog.module.css'
17+
18+ const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team'
1319
1420// Dialog v1
1521const noop = ( ) => null
@@ -19,41 +25,50 @@ type StyledDialogBaseProps = {
1925 wide ?: boolean
2026} & SxProp
2127
22- const DialogBase = styled . div < StyledDialogBaseProps > `
23- box-shadow: ${ get ( 'shadows.shadow.large' ) } ;
24- border-radius: ${ get ( 'radii.2' ) } ;
25- position: fixed;
26- top: 0;
27- left: 50%;
28- transform: translateX(-50%);
29- max-height: 80vh;
30- z-index: 999;
31- margin: 10vh auto;
32- background-color: ${ get ( 'colors.canvas.default' ) } ;
33- width: ${ props => ( props . narrow ? '320px' : props . wide ? '640px' : '440px' ) } ;
34- outline: none;
35-
36- @media screen and (max-width: 750px) {
37- width: 100dvw;
38- margin: 0;
39- border-radius: 0;
40- height: 100dvh;
41- }
28+ const DialogBase = toggleStyledComponent (
29+ CSS_MODULES_FEATURE_FLAG ,
30+ 'div' ,
31+ styled . div < StyledDialogBaseProps > `
32+ box-shadow: ${ get ( 'shadows.shadow.large' ) } ;
33+ border-radius: ${ get ( 'radii.2' ) } ;
34+ position: fixed;
35+ top: 0;
36+ left: 50%;
37+ transform: translateX(-50%);
38+ max-height: 80vh;
39+ z-index: 999;
40+ margin: 10vh auto;
41+ background-color: ${ get ( 'colors.canvas.default' ) } ;
42+ width: ${ props => ( props . narrow ? '320px' : props . wide ? '640px' : '440px' ) } ;
43+ outline: none;
44+
45+ @media screen and (max-width: 750px) {
46+ width: 100dvw;
47+ margin: 0;
48+ border-radius: 0;
49+ height: 100dvh;
50+ }
4251
43- ${ sx } ;
44- `
52+ ${ sx } ;
53+ ` ,
54+ )
4555
46- const DialogHeaderBase = styled ( Box ) < SxProp > `
47- border-radius: ${ get ( 'radii.2' ) } ${ get ( 'radii.2' ) } 0px 0px;
48- border-bottom: 1px solid ${ get ( 'colors.border.default' ) } ;
49- display: flex;
56+ const DialogHeaderBase = toggleStyledComponent (
57+ CSS_MODULES_FEATURE_FLAG ,
58+ 'div' ,
59+ styled ( Box ) < SxProp > `
60+ border-radius: ${ get ( 'radii.2' ) } ${ get ( 'radii.2' ) } 0px 0px;
61+ border-bottom: 1px solid ${ get ( 'colors.border.default' ) } ;
62+ display: flex;
5063
51- @media screen and (max-width: 750px) {
52- border-radius: 0px;
53- }
64+ @media screen and (max-width: 750px) {
65+ border-radius: 0px;
66+ }
67+
68+ ${ sx } ;
69+ ` ,
70+ )
5471
55- ${ sx } ;
56- `
5772export type DialogHeaderProps = ComponentProps < typeof DialogHeaderBase >
5873
5974function DialogHeader ( { theme, children, backgroundColor = 'canvas.subtle' , ...rest } : DialogHeaderProps ) {
@@ -65,28 +80,40 @@ function DialogHeader({theme, children, backgroundColor = 'canvas.subtle', ...re
6580 )
6681 }
6782
83+ const enabled = useFeatureFlag ( CSS_MODULES_FEATURE_FLAG )
84+
6885 return (
69- < DialogHeaderBase theme = { theme } p = { 3 } backgroundColor = { backgroundColor } { ...rest } >
86+ < DialogHeaderBase
87+ theme = { theme }
88+ p = { 3 }
89+ backgroundColor = { backgroundColor }
90+ { ...rest }
91+ className = { enabled ? classes . Header : undefined }
92+ >
7093 { children }
7194 </ DialogHeaderBase >
7295 )
7396}
7497
75- const Overlay = styled . span `
76- &:before {
77- position: fixed;
78- top: 0;
79- right: 0;
80- bottom: 0;
81- left: 0;
82- display: block;
83- cursor: default;
84- content: ' ';
85- background: transparent;
86- z-index: 99;
87- background: ${ get ( 'colors.primer.canvas.backdrop' ) } ;
88- }
89- `
98+ const Overlay = toggleStyledComponent (
99+ CSS_MODULES_FEATURE_FLAG ,
100+ 'span' ,
101+ styled . span `
102+ &:before {
103+ position: fixed;
104+ top: 0;
105+ right: 0;
106+ bottom: 0;
107+ left: 0;
108+ display: block;
109+ cursor: default;
110+ content: ' ';
111+ background: transparent;
112+ z-index: 99;
113+ background: ${ get ( 'colors.primer.canvas.backdrop' ) } ;
114+ }
115+ ` ,
116+ )
90117
91118type InternalDialogProps = {
92119 isOpen ?: boolean
@@ -96,7 +123,7 @@ type InternalDialogProps = {
96123} & ComponentProps < typeof DialogBase >
97124
98125const Dialog = forwardRef < HTMLDivElement , InternalDialogProps > (
99- ( { children, onDismiss = noop , isOpen, initialFocusRef, returnFocusRef, ...props } , forwardedRef ) => {
126+ ( { children, onDismiss = noop , isOpen, initialFocusRef, returnFocusRef, className , ...props } , forwardedRef ) => {
100127 const overlayRef = useRef ( null )
101128 const modalRef = useRef < HTMLDivElement > ( null )
102129 useRefObjectAsForwardedRef ( forwardedRef , modalRef )
@@ -118,17 +145,32 @@ const Dialog = forwardRef<HTMLDivElement, InternalDialogProps>(
118145 returnFocusRef,
119146 overlayRef,
120147 } )
148+
149+ const enabled = useFeatureFlag ( CSS_MODULES_FEATURE_FLAG )
150+
151+ const iconStyles = enabled
152+ ? { className : classes . CloseIcon }
153+ : { sx : { position : 'absolute' , top : '8px' , right : '16px' } }
154+
121155 return isOpen ? (
122156 < >
123- < Overlay ref = { overlayRef } />
124- < DialogBase tabIndex = { - 1 } ref = { modalRef } role = "dialog" aria-modal = "true" { ...props } { ...getDialogProps ( ) } >
157+ < Overlay className = { enabled ? classes . Overlay : undefined } ref = { overlayRef } />
158+ < DialogBase
159+ tabIndex = { - 1 }
160+ ref = { modalRef }
161+ role = "dialog"
162+ aria-modal = "true"
163+ { ...props }
164+ { ...getDialogProps ( ) }
165+ className = { clsx ( { [ classes . Dialog ] : enabled } , className ) }
166+ >
125167 < IconButton
126168 icon = { XIcon }
127169 ref = { closeButtonRef }
128170 onClick = { onCloseClick }
129- sx = { { position : 'absolute' , top : '8px' , right : '16px' } }
130171 aria-label = "Close"
131172 variant = "invisible"
173+ { ...iconStyles }
132174 />
133175 { children }
134176 </ DialogBase >
0 commit comments