diff --git a/doczrc.js b/doczrc.js index e92fecb5e..ec1200ff1 100644 --- a/doczrc.js +++ b/doczrc.js @@ -5,6 +5,18 @@ const path = require("path"); const fs = require("fs"); const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); const extensions = [".ts", ".tsx", ".js"]; +// TODO: There is some weird issue with including paths.ts here +const postCSSConfigPath = "./src/core/build/postcss.config"; +const isProduction = process.NODE_ENV === "production"; +const appDirectory = fs.realpathSync(process.cwd()); + +const styleLoader = { + loader: require.resolve("style-loader"), + options: { + sourceMap: true, + hmr: true, + }, +}; export default { title: "Talk 5.0", @@ -14,27 +26,69 @@ export default { port: parseInt(process.env.DOCZ_PORT, 10) || 3030, codeSandbox: false, // Too large to create code sandboxes.. modifyBundlerConfig: config => { + config.entry.app.push( + `${appDirectory}/src/core/client/ui/theme/variables.css.ts` + ); config.module.rules.push({ - test: /\.css$/, + test: /\.css\.ts$/, use: [ - require.resolve("style-loader"), + isProduction ? MiniCssExtractPlugin.loader : styleLoader, { loader: require.resolve("css-loader"), options: { modules: true, - importLoaders: 1, - localIdentName: - process.env.NODE_ENV === "production" - ? "[hash:base64]" - : "[name]-[local]-[hash:base64:5]", + importLoaders: 2, + localIdentName: "[name]-[local]-[hash:base64:5]", + sourceMap: true, }, }, { loader: require.resolve("postcss-loader"), options: { config: { - // TODO: There is some weird issue with including paths.ts here - path: "./src/core/build/postcss.config", + path: postCSSConfigPath, + }, + parser: "postcss-js", + }, + }, + { + loader: require.resolve("babel-loader"), + options: { + configFile: false, + babelrc: false, + presets: [ + "@babel/typescript", + [ + "@babel/env", + { targets: { node: "10.0.0" }, modules: "commonjs" }, + ], + ], + // This is a feature of `babel-loader` for webpack (not Babel itself). + // It enables caching results in ./node_modules/.cache/babel-loader/ + // directory for faster rebuilds. + cacheDirectory: true, + }, + }, + ], + }); + config.module.rules.push({ + test: /\.css$/, + use: [ + styleLoader, + { + loader: require.resolve("css-loader"), + options: { + modules: true, + importLoaders: 1, + localIdentName: "[name]-[local]-[hash:base64:5]", + sourceMap: true, + }, + }, + { + loader: require.resolve("postcss-loader"), + options: { + config: { + path: postCSSConfigPath, }, }, }, diff --git a/package-lock.json b/package-lock.json index d101c5608..e01d1ce4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2317,13 +2317,13 @@ } }, "@babel/preset-typescript": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.1.0.tgz", - "integrity": "sha512-LYveByuF9AOM8WrsNne5+N79k1YxjNB6gmpCQsnuSBAcV8QUeB+ZUxQzL7Rz7HksPbahymKkq2qBR+o36ggFZA==", + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.3.3.tgz", + "integrity": "sha512-mzMVuIP4lqtn4du2ynEfdO0+RYcslwrZiJHXu4MGaC1ctJiW2fyaeDrtjJGs7R/KebZ1sgowcIoWf4uRpEfKEg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-transform-typescript": "^7.1.0" + "@babel/plugin-transform-typescript": "^7.3.2" } }, "@babel/runtime": { @@ -3568,6 +3568,12 @@ "@types/express": "*" } }, + "@types/flat": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/@types/flat/-/flat-0.0.28.tgz", + "integrity": "sha1-XHiBSdhabPj/X18ACs3ZEs3qQnQ=", + "dev": true + }, "@types/fs-extra": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.4.tgz", @@ -4620,9 +4626,13 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } }, "ansi-wrap": { "version": "0.1.0", @@ -5360,6 +5370,14 @@ "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + } } } } @@ -6296,6 +6314,16 @@ "semver": "^5.3.0" } }, + "@babel/preset-typescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.1.0.tgz", + "integrity": "sha512-LYveByuF9AOM8WrsNne5+N79k1YxjNB6gmpCQsnuSBAcV8QUeB+ZUxQzL7Rz7HksPbahymKkq2qBR+o36ggFZA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.1.0" + } + }, "@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", @@ -9258,6 +9286,12 @@ "supports-color": "^2.0.0" }, "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -14658,6 +14692,14 @@ "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + } } } } @@ -16105,6 +16147,14 @@ "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + } } } } @@ -20768,6 +20818,14 @@ "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + } } }, "figures": { @@ -25140,50 +25198,19 @@ } }, "postcss-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.0.tgz", - "integrity": "sha512-9kAApW9G5kN8FkQ0ZdvSmbgbHIRrKmXtde2ZWYbwrW51gfEWfGsLlUu57mTpioPrmQlQFOgEvaeGYp+poqlX0A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.1.tgz", + "integrity": "sha512-8XQGohCbj6+kq8e3w6WlexkGaSjb5S8zoXnH49eB8JC6+qN2kQW+ib6fTjRgCpRRN9eeFOhMlD0NDjThW1DCBg==", "dev": true, "requires": { - "camelcase-css": "^2.0.0", - "postcss": "^7.0.0" + "camelcase-css": "^2.0.1", + "postcss": "^7.0.14" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "postcss": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", - "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", + "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -26467,6 +26494,12 @@ "supports-color": "^2.0.0" }, "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -29321,6 +29354,14 @@ "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + } } }, "cliui": { @@ -35102,6 +35143,11 @@ "xtend": "^4.0.0" }, "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", diff --git a/package.json b/package.json index e4a5367af..09ce80367 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,7 @@ "@babel/polyfill": "^7.4.4", "@babel/preset-env": "^7.4.4", "@babel/preset-react": "^7.0.0", + "@babel/preset-typescript": "^7.3.3", "@coralproject/rte": "^0.10.13", "@intervolga/optimize-cssnano-plugin": "^1.0.6", "@types/basic-auth": "^1.1.2", @@ -155,6 +156,7 @@ "@types/enzyme-adapter-react-16": "^1.0.3", "@types/eventemitter2": "^4.1.0", "@types/express": "^4.16.0", + "@types/flat": "0.0.28", "@types/fs-extra": "^5.0.4", "@types/graphql": "^0.13.3", "@types/html-minifier": "^3.5.2", @@ -210,6 +212,7 @@ "@types/webpack-dev-server": "^3.1.5", "@types/ws": "^5.1.2", "acorn": "^6.1.1", + "ansi-styles": "^3.2.0", "autoprefixer": "^9.5.1", "babel-core": "^7.0.0-bridge.0", "babel-jest": "^23.6.0", @@ -271,6 +274,7 @@ "postcss-flexbugs-fixes": "^4.1.0", "postcss-font-magician": "^2.2.1", "postcss-import": "^11.1.0", + "postcss-js": "^2.0.1", "postcss-loader": "^3.0.0", "postcss-mixins": "^6.2.1", "postcss-nested": "^4.1.1", diff --git a/src/core/build/createWebpackConfig.ts b/src/core/build/createWebpackConfig.ts index d4bb1c904..b5b4711ef 100644 --- a/src/core/build/createWebpackConfig.ts +++ b/src/core/build/createWebpackConfig.ts @@ -92,7 +92,7 @@ export default function createWebpackConfig( fallbackLocale: "en-US", // Common fluent files are always included in the locale bundles. - commonFiles: ["framework.ftl", "common.ftl"], + commonFiles: ["framework.ftl", "common.ftl", "ui.ftl"], // Locales that come with the main bundle. Others are loaded on demand. bundled: ["en-US"], @@ -350,6 +350,48 @@ export default function createWebpackConfig( : "assets/media/[name].[ext]", }, }, + { + test: /\.css\.ts$/, + use: [ + !watch ? MiniCssExtractPlugin.loader : styleLoader, + { + loader: require.resolve("css-loader"), + options: { + modules: true, + importLoaders: 2, + localIdentName: "[name]-[local]-[hash:base64:5]", + sourceMap: !disableSourcemaps, + }, + }, + { + loader: require.resolve("postcss-loader"), + options: { + config: { + path: paths.appPostCssConfig, + }, + parser: "postcss-js", + }, + }, + { + loader: require.resolve("babel-loader"), + options: { + configFile: false, + babelrc: false, + presets: [ + "@babel/typescript", + [ + "@babel/env", + { targets: { node: "10.0.0" }, modules: "commonjs" }, + ], + ], + // This is a feature of `babel-loader` for webpack (not Babel itself). + // It enables caching results in ./node_modules/.cache/babel-loader/ + // directory for faster rebuilds. + cacheDirectory: true, + }, + }, + ], + }, // Process JS with Babel. { test: /\.(ts|tsx)$/, @@ -373,7 +415,7 @@ export default function createWebpackConfig( }, }, { - loader: "ts-loader", + loader: require.resolve("ts-loader"), options: { configFile: paths.appTsconfig, compilerOptions: { diff --git a/src/core/build/postcss.config.js b/src/core/build/postcss.config.js index 6bbf0123b..03c0a3b04 100644 --- a/src/core/build/postcss.config.js +++ b/src/core/build/postcss.config.js @@ -9,7 +9,6 @@ const paths = require("./paths").default; const autoprefixer = require("autoprefixer"); const postcssFontMagician = require("postcss-font-magician"); const postcssFlexbugsFixes = require("postcss-flexbugs-fixes"); -const postcssVariables = require("postcss-css-variables"); const postcssPresetEnv = require("postcss-preset-env"); const postcssNested = require("postcss-nested"); const postcssImport = require("postcss-import"); @@ -49,7 +48,7 @@ module.exports = { // This allows us to define dynamic css variables. postcssPrependImports({ path: "", - files: [paths.appThemeVariablesCSS, paths.appThemeMixinsCSS], + files: [paths.appThemeMixinsCSS], }), // Needed by above plugin. postcssImport(), @@ -59,10 +58,6 @@ module.exports = { postcssNested(), // Sass style variables to be used in media queries. postcssAdvancedVariables({ variables: mediaQueryVariables }), - // CSS standard variables for everything else. - postcssVariables({ - variables: cssVariables, - }), // Provides a modern CSS environment. postcssPresetEnv(), // Does all the font handling logic. diff --git a/src/core/client/account/index.tsx b/src/core/client/account/index.tsx index db74f736f..7318db694 100644 --- a/src/core/client/account/index.tsx +++ b/src/core/client/account/index.tsx @@ -6,6 +6,9 @@ import App from "./App"; import { initLocalState } from "./local"; import localesData from "./locales"; +// Import css variables. +import "talk-ui/theme/variables.css"; + async function main() { const ManagedTalkContextProvider = await createManaged({ initLocalState, diff --git a/src/core/client/admin/index.tsx b/src/core/client/admin/index.tsx index d42226900..e86246149 100644 --- a/src/core/client/admin/index.tsx +++ b/src/core/client/admin/index.tsx @@ -6,6 +6,9 @@ import EntryContainer from "./containers/EntryContainer"; import { initLocalState } from "./local"; import localesData from "./locales"; +// Import css variables. +import "talk-ui/theme/variables.css"; + async function main() { const ManagedTalkContextProvider = await createManaged({ initLocalState, diff --git a/src/core/client/auth/index.tsx b/src/core/client/auth/index.tsx index 14c11ebbc..aa12ccf79 100644 --- a/src/core/client/auth/index.tsx +++ b/src/core/client/auth/index.tsx @@ -10,6 +10,9 @@ import { initLocalState } from "./local"; import localesData from "./locales"; import AppQuery from "./queries/AppQuery"; +// Import css variables. +import "talk-ui/theme/variables.css"; + /** * Adapt popup height to current content every 100ms. * diff --git a/src/core/client/framework/testHelpers/createFluentBundle.ts b/src/core/client/framework/testHelpers/createFluentBundle.ts index 1edc6d701..bbd9ca37b 100644 --- a/src/core/client/framework/testHelpers/createFluentBundle.ts +++ b/src/core/client/framework/testHelpers/createFluentBundle.ts @@ -7,7 +7,7 @@ import fs from "fs"; import path from "path"; // These locale prefixes are always loaded. -const commonPrefixes = ["common", "framework"]; +const commonPrefixes = ["ui", "common", "framework"]; function decorateErrorWhenMissing(bundle: FluentBundle) { const originalHasMessage = bundle.hasMessage; diff --git a/src/core/client/install/index.tsx b/src/core/client/install/index.tsx index ab548fb3e..879c7cd7e 100644 --- a/src/core/client/install/index.tsx +++ b/src/core/client/install/index.tsx @@ -7,6 +7,9 @@ import { createManaged } from "talk-framework/lib/bootstrap"; import App from "./components/App"; import localesData from "./locales"; +// Import css variables. +import "talk-ui/theme/variables.css"; + async function main() { const ManagedTalkContextProvider = await createManaged({ localesData, diff --git a/src/core/client/stream/index.tsx b/src/core/client/stream/index.tsx index d1f311dc3..ee7cb7029 100644 --- a/src/core/client/stream/index.tsx +++ b/src/core/client/stream/index.tsx @@ -16,6 +16,9 @@ import { import { initLocalState } from "./local"; import localesData from "./locales"; +// Import css variables. +import "talk-ui/theme/variables.css"; + const listeners = ( <> diff --git a/src/core/client/ui/components/Brand/BrandName.tsx b/src/core/client/ui/components/Brand/BrandName.tsx index 9f5f10d9a..8d5d69bab 100644 --- a/src/core/client/ui/components/Brand/BrandName.tsx +++ b/src/core/client/ui/components/Brand/BrandName.tsx @@ -22,7 +22,7 @@ const BrandName: FunctionComponent = ({ size, ...rest }) => ( - + v.toString()), + (_, k) => `--${kebabCase(k)}` +); + +// These are the default css standard variables. +const cssVariables = pickBy( + flatKebabVariables, + (v, k) => !k.startsWith("breakpoints-") +); + +const style = { + ":root": { + ...cssVariables, + "--mini-unit": "calc(1px * var(--mini-unit-small))", + }, + [`@media (min-width: ${variables.breakpoints.xs}px)`]: { + ":root": { + "--mini-unit": "calc(1px * var(--mini-unit-large))", + }, + }, +}; + +module.exports = style; diff --git a/src/locales/en-US/admin.ftl b/src/locales/en-US/admin.ftl index f62898109..9c09dc43f 100644 --- a/src/locales/en-US/admin.ftl +++ b/src/locales/en-US/admin.ftl @@ -1,8 +1,6 @@ ### Localization for Admin ## General - -general-brandName = { -product-name } general-notAvailable = Not available ## Story Status diff --git a/src/locales/en-US/ui.ftl b/src/locales/en-US/ui.ftl new file mode 100644 index 000000000..dd9ad4825 --- /dev/null +++ b/src/locales/en-US/ui.ftl @@ -0,0 +1 @@ +ui-brandName = { -product-name }