Skip to content

Commit 301bd40

Browse files
authored
Fix RTL styling on WordPress Core components (#1998)
* Fix RTL styling on WordPress Core components * fix unit tests * fix error fallback component rtl
1 parent 6681c40 commit 301bd40

6 files changed

Lines changed: 48 additions & 12 deletions

File tree

‎src/components/default-error-fallback.tsx‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,16 @@ const RightPanel = () => {
8989
};
9090

9191
export default function DefaultErrorFallback() {
92+
const { isRTL } = useI18n();
93+
const isRtl = isRTL();
94+
95+
const href = isRtl
96+
? './main_window/styles/wordpress-components-style-rtl.css'
97+
: './main_window/styles/wordpress-components-style.css';
98+
9299
return (
93-
<div dir={ 'ltr' }>
94-
<DynamicStylesheet
95-
id="wordpress-components-style"
96-
href={ '../main_window/styles/wordpress-components-style.css' }
97-
/>
100+
<div dir={ isRtl ? 'rtl' : 'ltr' }>
101+
<DynamicStylesheet id="wordpress-components-style-error-fallback" href={ href } />
98102
<VStack
99103
className={ cx(
100104
'h-screen bg-chrome backdrop-blur-3xl pr-chrome app-drag-region',

‎src/components/dynamic-stylesheet.tsx‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ export const DynamicStylesheet = ( { id, href }: DynamicStylesheetProps ) => {
1717
linkElement.id = id;
1818
linkElement.rel = 'stylesheet';
1919
linkElement.type = 'text/css';
20-
document.head.appendChild( linkElement );
20+
const firstStylesheet =
21+
document.head.querySelector( 'link[rel="stylesheet"]' ) ||
22+
document.head.querySelector( 'style' );
23+
if ( firstStylesheet ) {
24+
document.head.insertBefore( linkElement, firstStylesheet );
25+
} else {
26+
document.head.appendChild( linkElement );
27+
}
2128
wasCreatedByUsRef = true;
2229
}
2330
linkElementRef.current = linkElement;

‎src/components/root.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import App from 'src/components/app';
88
import AuthProvider from 'src/components/auth-provider';
99
import CrashTester from 'src/components/crash-tester';
1010
import ErrorBoundary from 'src/components/error-boundary';
11+
import { WordPressStyles } from 'src/components/wordpress-styles';
1112
import { SyncSitesProvider } from 'src/hooks/sync-sites/sync-sites-context';
1213
import { ContentTabsProvider } from 'src/hooks/use-content-tabs';
1314
import { FeatureFlagsProvider } from 'src/hooks/use-feature-flags';
@@ -34,6 +35,7 @@ const Root = () => {
3435
<CacheProvider value={ emotionCache }>
3536
<ReduxProvider store={ store }>
3637
<I18nProvider i18n={ defaultI18n }>
38+
<WordPressStyles />
3739
<AuthProvider>
3840
<ContentTabsProvider>
3941
<SiteDetailsProvider>

‎src/components/tests/dynamic-stylesheet.test.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ describe( 'DynamicStylesheet', () => {
4343
);
4444
render( <DynamicStylesheet id="second-style" href="/second.css" /> );
4545

46-
// Get initial order
46+
// Get initial order (new elements are inserted before existing ones)
4747
const allLinks = document.head.querySelectorAll( 'link[id]' );
4848
const initialOrder = Array.from( allLinks ).map( ( link ) => link.id );
49-
expect( initialOrder ).toEqual( [ 'first-style', 'second-style' ] );
49+
expect( initialOrder ).toEqual( [ 'second-style', 'first-style' ] );
5050

5151
// Update href of the first element
5252
rerender1( <DynamicStylesheet id="first-style" href="/first-updated.css" /> );
5353

5454
// Order should be preserved
5555
const allLinksAfterUpdate = document.head.querySelectorAll( 'link[id]' );
5656
const orderAfterUpdate = Array.from( allLinksAfterUpdate ).map( ( link ) => link.id );
57-
expect( orderAfterUpdate ).toEqual( [ 'first-style', 'second-style' ] );
57+
expect( orderAfterUpdate ).toEqual( [ 'second-style', 'first-style' ] );
5858

5959
// Verify the href was actually updated
6060
const firstElement = document.getElementById( 'first-style' ) as HTMLLinkElement;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useI18n } from '@wordpress/react-i18n';
2+
import { DynamicStylesheet } from 'src/components/dynamic-stylesheet';
3+
4+
const WORDPRESS_STYLES_ID = 'wordpress-components-style';
5+
6+
// @ts-expect-error - import.meta syntax is not supported by TypeScript's commonjs module setting,
7+
// but Vite handles this at build time and replaces it with the actual value
8+
const isDevelopment = import.meta.env.DEV;
9+
10+
const WORDPRESS_STYLES_LTR = isDevelopment
11+
? '/node_modules/@wordpress/components/build-style/style.css'
12+
: './main_window/styles/wordpress-components-style.css';
13+
14+
const WORDPRESS_STYLES_RTL = isDevelopment
15+
? '/node_modules/@wordpress/components/build-style/style-rtl.css'
16+
: './main_window/styles/wordpress-components-style-rtl.css';
17+
18+
export const WordPressStyles = () => {
19+
const { isRTL } = useI18n();
20+
const isRtl = isRTL();
21+
22+
const href = isRtl ? WORDPRESS_STYLES_RTL : WORDPRESS_STYLES_LTR;
23+
24+
return <DynamicStylesheet id={ WORDPRESS_STYLES_ID } href={ href } />;
25+
};

‎src/index.css‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
/* Import WordPress component styles - these are handled by Vite */
2-
@import '@wordpress/components/build-style/style.css';
3-
1+
/* WordPress component styles are loaded dynamically via WordPressStyles component */
42
@tailwind base;
53
@tailwind components;
64
@tailwind utilities;

0 commit comments

Comments
 (0)