@@ -48,9 +48,13 @@ const iconFadedNegative = `color-mix(in oklab, ${colorVars['--cl-color-negative'
4848const iconFadedOnPrimary = `color-mix(in oklab, ${ colorVars [ '--cl-color-primary-foreground' ] } , ${ colorVars [ '--cl-color-primary' ] } 40%)` ;
4949const iconFadedOnNegative = `color-mix(in oklab, ${ colorVars [ '--cl-color-negative-foreground' ] } , ${ colorVars [ '--cl-color-negative' ] } 40%)` ;
5050
51- // Interactive states are gated on `:enabled`: the `disabled` attribute blocks activation but
52- // not matching, and the button stays hit-testable so `cursor: not-allowed` renders and a
53- // wrapping tooltip still gets the pointer. Disabled keeps its resting fill and only dims.
51+ // Interactive states are gated on `:not([data-disabled])`: the button stays hit-testable while
52+ // disabled so `cursor: not-allowed` renders and a wrapping tooltip still gets the pointer, which
53+ // means the states have to be suppressed by selector. Disabled keeps its resting fill and only dims.
54+ //
55+ // The gate is the reflected attribute rather than `:enabled`, because `focusableWhenDisabled` drops
56+ // the native `disabled` attribute to keep the button in the tab order. `data-disabled` is emitted
57+ // for both, so one selector covers them.
5458//
5559// Hover also excludes `:active` explicitly — StyleX gives at-rules extra priority, so a
5660// `@media (hover: hover)` `:hover` would outrank a bare `:active` and win while pressing.
@@ -90,7 +94,7 @@ export const styles = stylex.create({
9094 // `fast` — `:active` stops matching as the color heads back. Instant press, soft settle.
9195 transitionDuration : {
9296 default : durationVars [ '--cl-duration-fast' ] ,
93- ':enabled :active' : durationVars [ '--cl-duration-instant' ] ,
97+ ':not([data-disabled]) :active' : durationVars [ '--cl-duration-instant' ] ,
9498 } ,
9599 transitionProperty : 'background-color, border-color, color, opacity' ,
96100 // Linear, not `--cl-ease-default`: nothing here moves. An ease on already non-uniform
@@ -171,59 +175,59 @@ export const variants = stylex.create({
171175 'filled-primary' : {
172176 '--_cl-icon-color' : {
173177 default : iconFadedOnPrimary ,
174- ':enabled [data-open]' : colorVars [ '--cl-color-primary-foreground' ] ,
178+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-primary-foreground' ] ,
175179 '@media (hover: hover)' : {
176180 default : null ,
177- ':enabled :hover' : colorVars [ '--cl-color-primary-foreground' ] ,
181+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-primary-foreground' ] ,
178182 } ,
179183 } ,
180184 backgroundColor : {
181185 default : colorVars [ '--cl-color-primary' ] ,
182- ':enabled :active' : primaryActive ,
183- ':enabled [data-open]' : primaryActive ,
186+ ':not([data-disabled]) :active' : primaryActive ,
187+ ':not([data-disabled]) [data-open]' : primaryActive ,
184188 '@media (hover: hover)' : {
185189 default : null ,
186- ':enabled :hover:not(:active):not([data-open])' : primaryHover ,
190+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : primaryHover ,
187191 } ,
188192 } ,
189193 color : colorVars [ '--cl-color-primary-foreground' ] ,
190194 } ,
191195 'filled-neutral' : {
192196 '--_cl-icon-color' : {
193197 default : iconFadedNeutral ,
194- ':enabled [data-open]' : colorVars [ '--cl-color-neutral-foreground' ] ,
198+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-neutral-foreground' ] ,
195199 '@media (hover: hover)' : {
196200 default : null ,
197- ':enabled :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
201+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
198202 } ,
199203 } ,
200204 backgroundColor : {
201205 default : neutralStep0 ,
202- ':enabled :active' : neutralStep2 ,
203- ':enabled [data-open]' : neutralStep2 ,
206+ ':not([data-disabled]) :active' : neutralStep2 ,
207+ ':not([data-disabled]) [data-open]' : neutralStep2 ,
204208 '@media (hover: hover)' : {
205209 default : null ,
206- ':enabled :hover:not(:active):not([data-open])' : neutralStep1 ,
210+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : neutralStep1 ,
207211 } ,
208212 } ,
209213 color : colorVars [ '--cl-color-neutral-foreground' ] ,
210214 } ,
211215 'filled-negative' : {
212216 '--_cl-icon-color' : {
213217 default : iconFadedOnNegative ,
214- ':enabled [data-open]' : colorVars [ '--cl-color-negative-foreground' ] ,
218+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-negative-foreground' ] ,
215219 '@media (hover: hover)' : {
216220 default : null ,
217- ':enabled :hover' : colorVars [ '--cl-color-negative-foreground' ] ,
221+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-negative-foreground' ] ,
218222 } ,
219223 } ,
220224 backgroundColor : {
221225 default : colorVars [ '--cl-color-negative' ] ,
222- ':enabled :active' : negativeActive ,
223- ':enabled [data-open]' : negativeActive ,
226+ ':not([data-disabled]) :active' : negativeActive ,
227+ ':not([data-disabled]) [data-open]' : negativeActive ,
224228 '@media (hover: hover)' : {
225229 default : null ,
226- ':enabled :hover:not(:active):not([data-open])' : negativeHover ,
230+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : negativeHover ,
227231 } ,
228232 } ,
229233 color : colorVars [ '--cl-color-negative-foreground' ] ,
@@ -235,62 +239,62 @@ export const variants = stylex.create({
235239 'outline-primary' : {
236240 '--_cl-icon-color' : {
237241 default : iconFadedNeutral ,
238- ':enabled [data-open]' : colorVars [ '--cl-color-primary' ] ,
242+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-primary' ] ,
239243 '@media (hover: hover)' : {
240244 default : null ,
241- ':enabled :hover' : colorVars [ '--cl-color-primary' ] ,
245+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-primary' ] ,
242246 } ,
243247 } ,
244248 borderColor : colorVars [ '--cl-color-border' ] ,
245249 backgroundColor : {
246250 default : 'transparent' ,
247- ':enabled :active' : neutralStep1 ,
248- ':enabled [data-open]' : neutralStep1 ,
251+ ':not([data-disabled]) :active' : neutralStep1 ,
252+ ':not([data-disabled]) [data-open]' : neutralStep1 ,
249253 '@media (hover: hover)' : {
250254 default : null ,
251- ':enabled :hover:not(:active):not([data-open])' : neutralStep0 ,
255+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : neutralStep0 ,
252256 } ,
253257 } ,
254258 color : colorVars [ '--cl-color-primary' ] ,
255259 } ,
256260 'outline-neutral' : {
257261 '--_cl-icon-color' : {
258262 default : iconFadedNeutral ,
259- ':enabled [data-open]' : colorVars [ '--cl-color-neutral-foreground' ] ,
263+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-neutral-foreground' ] ,
260264 '@media (hover: hover)' : {
261265 default : null ,
262- ':enabled :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
266+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
263267 } ,
264268 } ,
265269 borderColor : colorVars [ '--cl-color-border' ] ,
266270 backgroundColor : {
267271 default : 'transparent' ,
268- ':enabled :active' : neutralStep1 ,
269- ':enabled [data-open]' : neutralStep1 ,
272+ ':not([data-disabled]) :active' : neutralStep1 ,
273+ ':not([data-disabled]) [data-open]' : neutralStep1 ,
270274 '@media (hover: hover)' : {
271275 default : null ,
272- ':enabled :hover:not(:active):not([data-open])' : neutralStep0 ,
276+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : neutralStep0 ,
273277 } ,
274278 } ,
275279 color : colorVars [ '--cl-color-neutral-foreground' ] ,
276280 } ,
277281 'outline-negative' : {
278282 '--_cl-icon-color' : {
279283 default : iconFadedNegative ,
280- ':enabled [data-open]' : colorVars [ '--cl-color-negative' ] ,
284+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-negative' ] ,
281285 '@media (hover: hover)' : {
282286 default : null ,
283- ':enabled :hover' : colorVars [ '--cl-color-negative' ] ,
287+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-negative' ] ,
284288 } ,
285289 } ,
286290 borderColor : colorVars [ '--cl-color-border' ] ,
287291 backgroundColor : {
288292 default : 'transparent' ,
289- ':enabled :active' : neutralStep1 ,
290- ':enabled [data-open]' : neutralStep1 ,
293+ ':not([data-disabled]) :active' : neutralStep1 ,
294+ ':not([data-disabled]) [data-open]' : neutralStep1 ,
291295 '@media (hover: hover)' : {
292296 default : null ,
293- ':enabled :hover:not(:active):not([data-open])' : neutralStep0 ,
297+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : neutralStep0 ,
294298 } ,
295299 } ,
296300 color : colorVars [ '--cl-color-negative' ] ,
@@ -299,39 +303,39 @@ export const variants = stylex.create({
299303 'ghost-primary' : {
300304 '--_cl-icon-color' : {
301305 default : iconFadedNeutral ,
302- ':enabled [data-open]' : colorVars [ '--cl-color-primary' ] ,
306+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-primary' ] ,
303307 '@media (hover: hover)' : {
304308 default : null ,
305- ':enabled :hover' : colorVars [ '--cl-color-primary' ] ,
309+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-primary' ] ,
306310 } ,
307311 } ,
308312 backgroundColor : {
309313 default : 'transparent' ,
310- ':enabled :active' : neutralStep1 ,
311- ':enabled [data-open]' : neutralStep1 ,
314+ ':not([data-disabled]) :active' : neutralStep1 ,
315+ ':not([data-disabled]) [data-open]' : neutralStep1 ,
312316 '@media (hover: hover)' : {
313317 default : null ,
314- ':enabled :hover:not(:active):not([data-open])' : neutralStep0 ,
318+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : neutralStep0 ,
315319 } ,
316320 } ,
317321 color : colorVars [ '--cl-color-primary' ] ,
318322 } ,
319323 'ghost-neutral' : {
320324 '--_cl-icon-color' : {
321325 default : iconFadedNeutral ,
322- ':enabled [data-open]' : colorVars [ '--cl-color-neutral-foreground' ] ,
326+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-neutral-foreground' ] ,
323327 '@media (hover: hover)' : {
324328 default : null ,
325- ':enabled :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
329+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
326330 } ,
327331 } ,
328332 backgroundColor : {
329333 default : 'transparent' ,
330- ':enabled :active' : neutralStep1 ,
331- ':enabled [data-open]' : neutralStep1 ,
334+ ':not([data-disabled]) :active' : neutralStep1 ,
335+ ':not([data-disabled]) [data-open]' : neutralStep1 ,
332336 '@media (hover: hover)' : {
333337 default : null ,
334- ':enabled :hover:not(:active):not([data-open])' : neutralStep0 ,
338+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : neutralStep0 ,
335339 } ,
336340 } ,
337341 color : colorVars [ '--cl-color-neutral-foreground' ] ,
@@ -341,19 +345,19 @@ export const variants = stylex.create({
341345 'ghost-negative' : {
342346 '--_cl-icon-color' : {
343347 default : iconFadedNegative ,
344- ':enabled [data-open]' : colorVars [ '--cl-color-negative' ] ,
348+ ':not([data-disabled]) [data-open]' : colorVars [ '--cl-color-negative' ] ,
345349 '@media (hover: hover)' : {
346350 default : null ,
347- ':enabled :hover' : colorVars [ '--cl-color-negative' ] ,
351+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-negative' ] ,
348352 } ,
349353 } ,
350354 backgroundColor : {
351355 default : 'transparent' ,
352- ':enabled :active' : `color-mix(in oklab, ${ colorVars [ '--cl-color-negative-faded' ] } , ${ colorVars [ '--cl-color-negative' ] } 8%)` ,
353- ':enabled [data-open]' : `color-mix(in oklab, ${ colorVars [ '--cl-color-negative-faded' ] } , ${ colorVars [ '--cl-color-negative' ] } 8%)` ,
356+ ':not([data-disabled]) :active' : `color-mix(in oklab, ${ colorVars [ '--cl-color-negative-faded' ] } , ${ colorVars [ '--cl-color-negative' ] } 8%)` ,
357+ ':not([data-disabled]) [data-open]' : `color-mix(in oklab, ${ colorVars [ '--cl-color-negative-faded' ] } , ${ colorVars [ '--cl-color-negative' ] } 8%)` ,
354358 '@media (hover: hover)' : {
355359 default : null ,
356- ':enabled :hover:not(:active):not([data-open])' : colorVars [ '--cl-color-negative-faded' ] ,
360+ ':not([data-disabled]) :hover:not(:active):not([data-open])' : colorVars [ '--cl-color-negative-faded' ] ,
357361 } ,
358362 } ,
359363 color : colorVars [ '--cl-color-negative' ] ,
@@ -366,14 +370,14 @@ export const variants = stylex.create({
366370 default : iconFadedNeutral ,
367371 '@media (hover: hover)' : {
368372 default : null ,
369- ':enabled :hover' : colorVars [ '--cl-color-primary' ] ,
373+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-primary' ] ,
370374 } ,
371375 } ,
372376 backgroundColor : 'transparent' ,
373377 color : colorVars [ '--cl-color-primary' ] ,
374378 paddingInlineEnd : 0 ,
375379 paddingInlineStart : 0 ,
376- textDecorationLine : { default : 'none' , ':enabled :hover' : 'underline' } ,
380+ textDecorationLine : { default : 'none' , ':not([data-disabled]) :hover' : 'underline' } ,
377381 textUnderlineOffset : '2px' ,
378382 height : 'auto' ,
379383 } ,
@@ -382,14 +386,14 @@ export const variants = stylex.create({
382386 default : iconFadedNeutral ,
383387 '@media (hover: hover)' : {
384388 default : null ,
385- ':enabled :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
389+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-neutral-foreground' ] ,
386390 } ,
387391 } ,
388392 backgroundColor : 'transparent' ,
389393 color : colorVars [ '--cl-color-neutral-foreground' ] ,
390394 paddingInlineEnd : 0 ,
391395 paddingInlineStart : 0 ,
392- textDecorationLine : { default : 'none' , ':enabled :hover' : 'underline' } ,
396+ textDecorationLine : { default : 'none' , ':not([data-disabled]) :hover' : 'underline' } ,
393397 textUnderlineOffset : '2px' ,
394398 height : 'auto' ,
395399 } ,
@@ -398,14 +402,14 @@ export const variants = stylex.create({
398402 default : iconFadedNegative ,
399403 '@media (hover: hover)' : {
400404 default : null ,
401- ':enabled :hover' : colorVars [ '--cl-color-negative' ] ,
405+ ':not([data-disabled]) :hover' : colorVars [ '--cl-color-negative' ] ,
402406 } ,
403407 } ,
404408 backgroundColor : 'transparent' ,
405409 color : colorVars [ '--cl-color-negative' ] ,
406410 paddingInlineEnd : 0 ,
407411 paddingInlineStart : 0 ,
408- textDecorationLine : { default : 'none' , ':enabled :hover' : 'underline' } ,
412+ textDecorationLine : { default : 'none' , ':not([data-disabled]) :hover' : 'underline' } ,
409413 textUnderlineOffset : '2px' ,
410414 height : 'auto' ,
411415 } ,
0 commit comments