Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CSS prefixer #378

Merged
merged 3 commits into from
Sep 17, 2024
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: 5 additions & 0 deletions .changeset/dirty-owls-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'docusaurus-theme-redoc': patch
---

Fixes incorrect CSS prefixing that breaks layout on mobile devices and resolves reintroduced issues with incorrect background color for code samples
3 changes: 3 additions & 0 deletions packages/docusaurus-theme-redoc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
"clsx": "^1.2.1",
"lodash": "^4.17.21",
"mobx": "^6.12.4",
"postcss": "^8.4.45",
"postcss-prefix-selector": "^1.16.1",
"redoc": "2.1.5",
"styled-components": "^6.1.11"
},
Expand All @@ -45,6 +47,7 @@
"@docusaurus/theme-common": "^3.4.0",
"@docusaurus/types": "^3.4.0",
"@types/lodash": "^4.14.200",
"@types/postcss-prefix-selector": "^1",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-is": "^18.3.0",
Expand Down
87 changes: 25 additions & 62 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/ServerStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,27 @@ import { AppStore, Redoc, RedocRawOptions } from 'redoc';
// eslint-disable-next-line import/no-extraneous-dependencies
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';
import postcss from 'postcss';
import prefixer from 'postcss-prefix-selector';

/**
* @see https://stackoverflow.com/a/54077142
*/
const prefixCssSelectors = function (rules: string, className: string) {
const classLen = className.length;
let char, nextChar, isAt, isIn;

// makes sure the className will not concatenate the selector
className += ' ';

// removes comments
rules = rules.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\/|[\r\n\t]+/g, '');

// makes sure nextChar will not target a space
rules = rules.replace(/}(\s*)@/g, '}@');
rules = rules.replace(/}(\s*)}/g, '}}');

for (let i = 0; i < rules.length - 2; i++) {
char = rules[i];
nextChar = rules[i + 1];
const prefixCssSelectors = function (css: string, className: string): string {
const processor = postcss().use(
prefixer({
prefix: className,
}),
);

if (char === '@' && nextChar !== 'f') isAt = true;
if (!isAt && char === '{') isIn = true;
if (isIn && char === '}') isIn = false;
return processor.process(css).css;
};

if (
!isIn &&
nextChar !== '@' &&
nextChar !== '}' &&
(char === '}' || char === ',' || ((char === '{' || char === ';') && isAt))
) {
rules = rules.slice(0, i + 1) + className + rules.slice(i + 1);
i += classLen;
isAt = false;
}
}
const renderCss = function (store: AppStore): string {
const styleSheet = new ServerStyleSheet();

// prefix the first select if it is not `@media` and if it is not yet prefixed
if (rules.indexOf(className) !== 0 && rules.indexOf('@') !== 0)
rules = className + rules;
renderToString(
styleSheet.collectStyles(React.createElement(Redoc, { store })),
);

return rules;
return String(styleSheet.instance);
};

const LIGHT_MODE_PREFIX = "html:not([data-theme='dark'])";
Expand All @@ -63,41 +41,26 @@ export function ServerStyles({
darkThemeOptions: RedocRawOptions;
}) {
const fullUrl = useBaseUrl(specProps.url, { absolute: true });
const css = {
light: '',
dark: '',
};
const lightSheet = new ServerStyleSheet();
const lightStore = new AppStore(specProps.spec, fullUrl, lightThemeOptions);
renderToString(
lightSheet.collectStyles(React.createElement(Redoc, { store: lightStore })),
);
const lightStyleTag = lightSheet.getStyleTags();
let lightCss = lightStyleTag.slice(lightStyleTag.indexOf('>') + 1);
lightCss = lightCss.slice(0, lightCss.indexOf('<style'));
css.light = prefixCssSelectors(lightCss, LIGHT_MODE_PREFIX);

const darkSheet = new ServerStyleSheet();
const darkStore = new AppStore(specProps.spec, fullUrl, darkThemeOptions);
renderToString(
darkSheet.collectStyles(React.createElement(Redoc, { store: darkStore })),
const lightCss = prefixCssSelectors(
renderCss(new AppStore(specProps.spec, fullUrl, lightThemeOptions)),
LIGHT_MODE_PREFIX,
);
const darkStyleTag = darkSheet.getStyleTags();
let darkCss = darkStyleTag.slice(darkStyleTag.indexOf('>') + 1);
darkCss = darkCss.slice(0, darkCss.indexOf('<style'));
css.dark = prefixCssSelectors(darkCss, DARK_MODE_PREFIX).slice(
DARK_MODE_PREFIX.length + 1,

const darkCss = prefixCssSelectors(
renderCss(new AppStore(specProps.spec, fullUrl, darkThemeOptions)),
DARK_MODE_PREFIX,
);

return (
<div className="redocusaurus-styles">
<style
key="light-mode-styles"
dangerouslySetInnerHTML={{ __html: css.light }}
dangerouslySetInnerHTML={{ __html: lightCss }}
/>
<style
key="dark-mode-styles"
dangerouslySetInnerHTML={{ __html: css.dark }}
dangerouslySetInnerHTML={{ __html: darkCss }}
/>
</div>
);
Expand Down
22 changes: 12 additions & 10 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,16 @@ html[data-theme='dark']
}

/* Fixes https://github.com/rohit-gohri/redocusaurus/issues/306 */
html[data-theme='dark']
.redocusaurus
html[data-theme='dark']
.redocusaurus
div[id^='tag']
button:has(span):has(.operation-type) {
background-color: var(--ifm-color-gray-800);
}

html[data-theme='dark']
.redocusaurus
div[id^='tag']
html[data-theme='dark']
.redocusaurus
div[id^='tag']
button + div {
background-color: var(--ifm-color-emphasis-0);
}
Expand All @@ -146,20 +146,22 @@ html[data-theme='dark']
margin-bottom: 10px;
}

/*
/*
* Code Samples
* @see https://github.com/rohit-gohri/redocusaurus/issues/217
*/
html:not([data-theme='dark'])
.redocusaurus
div[id^='react-tabs']
> div:nth-child(1)
> pre:nth-child(2) {
[role='tabpanel']
pre {
background-color: transparent;
}

/** https://github.com/rohit-gohri/redocusaurus/issues/45 */
html:not([data-theme='dark']) .redocusaurus div[id^='react-tabs'] code {
html:not([data-theme='dark'])
.redocusaurus
[role='tabpanel']
code {
color: var(--ifm-color-emphasis-0);
}

Expand Down
32 changes: 32 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3725,6 +3725,15 @@ __metadata:
languageName: node
linkType: hard

"@types/postcss-prefix-selector@npm:^1":
version: 1.16.3
resolution: "@types/postcss-prefix-selector@npm:1.16.3"
dependencies:
postcss: "npm:^8.4.27"
checksum: c0ece88bf7f5adfdcbf1f44436ce3e78d5fe0431fd84dce4040e53c03af2ca71fd3f1a36d127e1402c085c5507d5403fe461577670252c311556c102d7dc948d
languageName: node
linkType: hard

"@types/prismjs@npm:^1.26.0":
version: 1.26.2
resolution: "@types/prismjs@npm:1.26.2"
Expand Down Expand Up @@ -6357,6 +6366,7 @@ __metadata:
"@docusaurus/types": "npm:^3.4.0"
"@redocly/openapi-core": "npm:1.16.0"
"@types/lodash": "npm:^4.14.200"
"@types/postcss-prefix-selector": "npm:^1"
"@types/react": "npm:^18.3.3"
"@types/react-dom": "npm:^18.3.0"
"@types/react-is": "npm:^18.3.0"
Expand All @@ -6368,6 +6378,8 @@ __metadata:
lodash: "npm:^4.17.21"
mobx: "npm:^6.12.4"
nodemon: "npm:^3.1.0"
postcss: "npm:^8.4.45"
postcss-prefix-selector: "npm:^1.16.1"
react: "npm:^18.3.1"
react-dom: "npm:^18.3.1"
react-is: "npm:^18.3.1"
Expand Down Expand Up @@ -12402,6 +12414,15 @@ __metadata:
languageName: node
linkType: hard

"postcss-prefix-selector@npm:^1.16.1":
version: 1.16.1
resolution: "postcss-prefix-selector@npm:1.16.1"
peerDependencies:
postcss: ">4 <9"
checksum: e6a138f2c2f4be38013e778d0242f7fced1468759b508b3f85349ec1a5cd0bd6e7194998749508edb7a987fff9d4f3ee89b7d4f34e5df34dbf65130bf3bc680c
languageName: node
linkType: hard

"postcss-reduce-idents@npm:^6.0.3":
version: 6.0.3
resolution: "postcss-reduce-idents@npm:6.0.3"
Expand Down Expand Up @@ -12507,6 +12528,17 @@ __metadata:
languageName: node
linkType: hard

"postcss@npm:^8.4.27, postcss@npm:^8.4.45":
version: 8.4.45
resolution: "postcss@npm:8.4.45"
dependencies:
nanoid: "npm:^3.3.7"
picocolors: "npm:^1.0.1"
source-map-js: "npm:^1.2.0"
checksum: 7eaf7346d04929ee979548ece5e34d253eae6f175346e298b2c4621ad6f4ee00adfe7abe72688640e910c0361ae50537c5dda3e35fd1066491282c342b3ee5c8
languageName: node
linkType: hard

"preferred-pm@npm:^3.0.0":
version: 3.1.2
resolution: "preferred-pm@npm:3.1.2"
Expand Down
Loading