Skip to content

Commit

Permalink
fix: css-only hydration to prevent FOUC (#991) (#4856)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulcpederson authored Jul 9, 2022
1 parent 7e4dad6 commit dae9586
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ node_modules/
support/output-targets/custom-elements/bundles/
src/**/components.d.ts
src/**/*.js
src/assets/styles/_hydration.scss
__docs-temp__/*

# User Settings, Caches & Temp Files
Expand Down
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
"hydrate/"
],
"scripts": {
"build": "npm run util:copy-icons && stencil build && npm run util:patch-es5-helpers",
"build:watch": "npm run util:copy-icons && stencil build --watch",
"build:watch-dev": "npm run util:copy-icons && stencil build --dev --watch",
"build-storybook": "npm run util:copy-icons && stencil build --config stencil.config.ts && build-storybook --static-dir ./www --output-dir ./docs",
"build": "npm run util:hydration-styles && npm run util:copy-icons && stencil build && npm run util:patch-es5-helpers",
"build:watch": "npm run util:hydration-styles && npm run util:copy-icons && stencil build --watch",
"build:watch-dev": "npm run util:hydration-styles && npm run util:copy-icons && stencil build --dev --watch",
"build-storybook": "npm run util:hydration-styles && npm run util:copy-icons && stencil build --config stencil.config.ts && build-storybook --static-dir ./www --output-dir ./docs",
"deps:update": "updtr --exclude chalk cheerio typescript @types/jest jest jest-cli ts-jest puppeteer && npm audit fix",
"docs": "concurrently --kill-others --raw \"npm:util:build-docs && build-storybook --static-dir ./__docs-temp__ --output-dir ./docs\" \"ts-node ./support/cleanOnProcessExit.ts --path ./__docs-temp__\"",
"docs:preview": "concurrently --raw \"npm:util:build-docs && start-storybook --static-dir ./__docs-temp__\" \"ts-node ./support/cleanOnProcessExit.ts --path ./__docs-temp__\"",
Expand All @@ -43,17 +43,18 @@
"test:prerender": "stencil build --no-docs --prerender",
"test:storybook": "concurrently --raw \"npm:util:build-docs && screener-storybook --conf screener.config.js\"",
"test:watch": "npm run util:run-tests -- --watchAll",
"util:build-docs": "npm run util:copy-icons && stencil build --config stencil.storybook.config.ts",
"util:build-docs": "npm run util:hydration-styles && npm run util:copy-icons && stencil build --config stencil.storybook.config.ts",
"util:clean-tested-build": "npm ci && npm test && npm run build",
"util:copy-icons": "cpy \"./node_modules/@esri/calcite-ui-icons/js/*.json\" \"./src/components/icon/assets/icon/\" --flat",
"util:deploy-next": "npm run util:prep-next && npm run util:push-tags && npm run util:publish-next",
"util:deploy-next-from-ci": "ts-node --project ./tsconfig-node-scripts.json support/deployNextFromCI.ts",
"util:hydration-styles": "ts-node support/hydrationStyles.ts",
"util:patch-es5-helpers": "ts-node support/patchES5Helpers.ts",
"util:prep-next": "ts-node --project ./tsconfig-node-scripts.json support/prepReleaseCommit.ts --next && npm run build",
"util:publish-next": "npm publish --tag next",
"util:check-squash-mergeable-branch": "ts-node --project ./tsconfig-node-scripts.json support/checkSquashMergeableBranch.ts",
"util:push-tags": "git push --atomic --follow-tags origin master",
"util:run-tests": "npm run util:copy-icons && stencil test --no-docs --spec --e2e"
"util:run-tests": "npm run util:hydration-styles && npm run util:copy-icons && stencil test --no-docs --spec --e2e"
},
"repository": {
"type": "git",
Expand Down
3 changes: 3 additions & 0 deletions src/assets/styles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
/* CSS vars (@include in global) */
@import "type";

/* Hydration styles to hide non-hydrated components */
@import "hydration";

@mixin calcite-theme-light-extended {
@include calcite-theme-light();
--calcite-theme-name: "light";
Expand Down
1 change: 1 addition & 0 deletions stencil.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export const create: () => Config = () => ({
}
}
],
invisiblePrehydration: false,
globalStyle: "src/assets/styles/global.scss",
plugins: [
sass({
Expand Down
25 changes: 25 additions & 0 deletions support/hydrationStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const fs = require("fs");
const path = require("path");

const basePath = path.normalize(`${__dirname}/../src/components/`);

async function isCalciteComponent(entry): Promise<boolean> {
if (!entry.isDirectory()) {
return false;
}
const files = await fs.promises.readdir(path.join(basePath, entry.name));
return files?.includes(`${entry.name}.tsx`);
}

(async function () {
const stylePath = path.normalize(`${__dirname}/../src/assets/styles/_hydration.scss`);
const components = await fs.promises.readdir(basePath, { withFileTypes: true });
const selectors = components.filter(isCalciteComponent).map(({ name }) => `calcite-${name}:not([calcite-hydrated])`);
const fileContents = `// generated by support/hydrationStyles.ts
${selectors.join(",\n")} {
visibility: hidden;
pointer-events: none;
}`;
await fs.promises.writeFile(stylePath, fileContents);
process.exit(0);
})();

0 comments on commit dae9586

Please sign in to comment.