Skip to content

Commit

Permalink
fix(s2): Remove all: revert-layer to avoid Safari bugs (#7598)
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett authored Jan 16, 2025
1 parent ce54e26 commit 1286a65
Show file tree
Hide file tree
Showing 11 changed files with 26 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .storybook-s2/docs/Icons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {highlight} from './highlight' with {type: 'macro'};

export function Icons() {
return (
<div className={style({marginX: 'auto'})}>
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
<div className={style({marginX: 48})}>
<h1 className={style({font: 'heading-2xl', marginBottom: 48})}>
Workflow icons
Expand Down
2 changes: 1 addition & 1 deletion .storybook-s2/docs/Illustrations.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useState } from 'react';
export function Illustrations() {
let [gradientStyle, setStyle] = useState('generic1');
return (
<div className={style({marginX: 'auto'})}>
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
<div className={style({marginX: 48})}>
<h1 className={style({font: 'heading-2xl', marginBottom: 48})}>
Illustrations
Expand Down
14 changes: 6 additions & 8 deletions .storybook-s2/docs/Intro.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {H2, H3, H4, P, Pre, Code, Strong, Link} from './typography';

export function Docs() {
return (
<div className={style({marginX: 'auto', marginY: 48})}>
<div className={'sb-unstyled ' + style({marginX: 'auto', marginY: 48})}>
<header
style={{
backgroundImage: `url(${new URL('wallpaper_collaborative_S2_desktop.webp', import.meta.url).toString()})`,
Expand Down Expand Up @@ -228,7 +228,7 @@ import {ActionButton} from '@react-spectrum/s2';
</ul>
<H3>UNSAFE Style Overrides</H3>
<P>We highly discourage overriding the styles of React Spectrum components because it may break at any time when we change our implementation, making it difficult for you to update in the future. Consider using <Link href="https://react-spectrum.adobe.com/react-aria/" target="_blank">React Aria Components</Link> with our <Link href="?path=/docs/style-macro--docs" target="_top">style macro</Link> to build a custom component with Spectrum styles instead.</P>
<P>That said, just like in React Spectrum v3, the <Code>UNSAFE_className</Code> and <Code>UNSAFE_style</Code> props are supported on Spectrum 2 components as last-resort escape hatches. However, unlike in v3, UNSAFE_classNames must be placed in a special <Code>UNSAFE_overrides</Code> <Link href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers" target="_blank">CSS cascade layer</Link>. This guarentees that your overrides will always win over other styles on the page, no matter the order or specificity of the selector.</P>
<P>That said, just like in React Spectrum v3, the <Code>UNSAFE_className</Code> and <Code>UNSAFE_style</Code> props are supported on Spectrum 2 components as last-resort escape hatches.</P>
<Pre>{highlight(`/* YourComponent.tsx */
import {Button} from '@react-spectrum/s2';
import './YourComponent.css';
Expand All @@ -237,12 +237,10 @@ function YourComponent() {
return <Button UNSAFE_className="your-unsafe-class">Button</Button>;
}`)}</Pre>
<Pre>{highlight(`/* YourComponent.css */
@layer UNSAFE_overrides {
/* Wrap all UNSAFE_className rules in this layer. */
.your-unsafe-class {
background: red;
}
}`, 'CSS')}</Pre>
.your-unsafe-class {
background: red;
}
`, 'CSS')}</Pre>
</main>
</div>
)
Expand Down
2 changes: 1 addition & 1 deletion .storybook-s2/docs/MDXLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const mdxComponents = {

export function MDXLayout({children}) {
return (
<div className={style({marginX: 'auto'})}>
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
<main className={style({marginX: 48})}>
<MDXProvider components={mdxComponents}>
{children}
Expand Down
2 changes: 1 addition & 1 deletion .storybook-s2/docs/Migrating.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {P, Code, Pre, H3, H2, Link} from './typography';

export function Migrating() {
return (
<div className={style({marginX: 'auto', fontFamily: 'sans'})}>
<div className={'sb-unstyled ' + style({marginX: 'auto', fontFamily: 'sans'})}>
<div className={style({marginX: 48})}>
<h1 className={style({font: 'heading-2xl', marginBottom: 48})}>
Migrating to Spectrum 2
Expand Down
2 changes: 1 addition & 1 deletion .storybook-s2/docs/StyleMacro.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Colors} from './Colors';

export function StyleMacro() {
return (
<div className={style({marginX: 'auto'})}>
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
<header
className={style({
paddingX: 48,
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/s2/src/Skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const loadingStyle = raw(`
* {
visibility: hidden;
}
`, 'UNSAFE_overrides');
`, 'L'); // add to a separate layer so it overrides default style macro styles

export function useSkeletonText(children: ReactNode, style: CSSProperties | undefined): [ReactNode, CSSProperties | undefined] {
let isSkeleton = useContext(SkeletonContext);
Expand Down
3 changes: 1 addition & 2 deletions packages/@react-spectrum/s2/stories/ActionButton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ export const UnsafeClassName: Story = {
render: (args) => {
return (
<div className={style({display: 'flex', gap: 8, justifyContent: 'center', overflow: 'auto'})}>
<ActionButton {...args} UNSAFE_className="unsafe1">Global unsafe does not apply</ActionButton>
<ActionButton {...args} UNSAFE_className="unsafe2">@layer UNSAFE_overrides works</ActionButton>
<ActionButton {...args} UNSAFE_className="unsafe2">UNSAFE_className works</ActionButton>
</div>
);
},
Expand Down
18 changes: 3 additions & 15 deletions packages/@react-spectrum/s2/stories/unsafe.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,7 @@
* governing permissions and limitations under the License.
*/

button {
/* This should not apply */
background: red;
}

html body .unsafe1 {
/* This should not apply */
background: red;
}

@layer UNSAFE_overrides {
.unsafe2 {
/* This one should work */
background: hotpink;
}
.unsafe2 {
/* This one should work */
background: hotpink;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ describe('style-macro', () => {
});

expect(css).toMatchInlineSnapshot(`
".\\.:not(#a#b) { all: revert-layer }
@layer _.a, _.b, _.c, UNSAFE_overrides;
"@layer _.a, _.b, _.c;
@layer _.b {
.A-13alit4c {
Expand Down Expand Up @@ -72,9 +70,7 @@ describe('style-macro', () => {
});

expect(css).toMatchInlineSnapshot(`
".\\.:not(#a#b) { all: revert-layer }
@layer _.a, _.b, UNSAFE_overrides;
"@layer _.a, _.b;
@layer _.a {
.uc {
Expand Down
10 changes: 8 additions & 2 deletions packages/@react-spectrum/s2/style/style-macro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export function createTheme<T extends Theme>(theme: T): StyleFunction<ThemePrope
// The :not(#a#b) raises the specificity of the selector by 2 ids,
// which can never occur on a real element, and will win over other
// selectors such as class and element selectors.
let css = '.\\.:not(#a#b) { all: revert-layer }\n\n';
let css = '';

// Declare layers for each priority ahead of time so the order is always correct.
css += '@layer ';
Expand All @@ -235,7 +235,7 @@ export function createTheme<T extends Theme>(theme: T): StyleFunction<ThemePrope
}
css += layerName(generateName(i, true));
}
css += ', UNSAFE_overrides;\n\n';
css += ';\n\n';

// If allowed overrides are provided, generate code to match the input override string and include only allowed classes.
// Also generate a variable for each overridable property that overlaps with the style definition. If those are defined,
Expand Down Expand Up @@ -644,6 +644,12 @@ export function raw(this: MacroContext | void, css: string, layer = '_.a') {
${css}
}
}`;

// Ensure layer is always declared after the _ layer used by style macro.
if (!layer.startsWith('_.')) {
css = `@layer _, ${layer};\n` + css;
}

if (this && typeof this.addAsset === 'function') {
this.addAsset({
type: 'css',
Expand Down

1 comment on commit 1286a65

@rspbot
Copy link

@rspbot rspbot commented on 1286a65 Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.