Skip to content

Commit

Permalink
Enable CSS-in-JS styling with emotion (#98157)
Browse files Browse the repository at this point in the history
* emotion deps

* kbn-babel

* kbn-test

* examples

* babel-plugin-styled-components config

* css prop type fixes

* type context

* declaration location

* some emotion types resolved

* clean up

* emotion v10 accomodations

* types

* kbn-crypto

* kbn-telemetry-tools

* bazel

* eslint rule; shared file regex array

* update paths

* Update packages/kbn-eslint-plugin-eslint/rules/module_migration.js

Co-authored-by: Spencer <email@spalger.com>

* remove placeholder styles

* doc api changes

* snapshot updates

* storybook comments

* use constant

* bump new deps

* condense versions

Co-authored-by: Spencer <email@spalger.com>
  • Loading branch information
thompsongl and Spencer committed Jul 12, 2021
1 parent f5fdacc commit 4926f46
Show file tree
Hide file tree
Showing 25 changed files with 280 additions and 115 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
"@elastic/safer-lodash-set": "link:bazel-bin/packages/elastic-safer-lodash-set",
"@elastic/search-ui-app-search-connector": "^1.6.0",
"@elastic/ui-ace": "0.2.3",
"@emotion/react": "^11.4.0",
"@hapi/accept": "^5.0.2",
"@hapi/boom": "^9.1.1",
"@hapi/cookie": "^11.0.2",
Expand Down Expand Up @@ -451,6 +452,8 @@
"@elastic/eslint-plugin-eui": "0.0.2",
"@elastic/github-checks-reporter": "0.0.20b3",
"@elastic/makelogs": "^6.0.0",
"@emotion/babel-preset-css-prop": "^11.2.0",
"@emotion/jest": "^11.3.0",
"@istanbuljs/schema": "^0.1.2",
"@jest/reporters": "^26.6.2",
"@kbn/babel-code-parser": "link:bazel-bin/packages/kbn-babel-code-parser",
Expand Down
10 changes: 9 additions & 1 deletion packages/elastic-eslint-config-kibana/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { USES_STYLED_COMPONENTS } = require('@kbn/dev-utils');

module.exports = {
extends: [
'./javascript.js',
Expand Down Expand Up @@ -79,7 +81,13 @@ module.exports = {
from: 'react-intl',
to: '@kbn/i18n/react',
disallowedMessage: `import from @kbn/i18n/react instead`
}
},
{
from: 'styled-components',
to: false,
exclude: USES_STYLED_COMPONENTS,
disallowedMessage: `Prefer using @emotion/react instead. To use styled-components, ensure you plugin is enabled in @kbn/dev-utils/src/babel.ts.`
},
],
],
},
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-babel-preset/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ DEPS = [
"@npm//@babel/preset-env",
"@npm//@babel/preset-react",
"@npm//@babel/preset-typescript",
"@npm//@emotion/babel-preset-css-prop",
"@npm//babel-plugin-add-module-exports",
"@npm//babel-plugin-styled-components",
"@npm//babel-plugin-transform-react-remove-prop-types",
Expand Down
34 changes: 26 additions & 8 deletions packages/kbn-babel-preset/webpack_preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Side Public License, v 1.
*/

const { USES_STYLED_COMPONENTS } = require.resolve('@kbn/dev-utils');

module.exports = () => {
return {
presets: [
Expand All @@ -21,14 +23,6 @@ module.exports = () => {
],
require('./common_preset'),
],
plugins: [
[
require.resolve('babel-plugin-styled-components'),
{
fileName: false,
},
],
],
env: {
production: {
plugins: [
Expand All @@ -42,5 +36,29 @@ module.exports = () => {
],
},
},
overrides: [
{
include: USES_STYLED_COMPONENTS,
plugins: [
[
require.resolve('babel-plugin-styled-components'),
{
fileName: false,
},
],
],
},
{
exclude: USES_STYLED_COMPONENTS,
presets: [
[
require.resolve('@emotion/babel-preset-css-prop'),
{
labelFormat: '[local]',
},
],
],
},
],
};
};
3 changes: 2 additions & 1 deletion packages/kbn-crypto/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/node-forge",
"@npm//@types/testing-library__jest-dom",
"@npm//resize-observer-polyfill"
"@npm//resize-observer-polyfill",
"@npm//@emotion/react",
]

DEPS = SRC_DEPS + TYPES_DEPS
Expand Down
11 changes: 11 additions & 0 deletions packages/kbn-dev-utils/src/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,14 @@ export async function transformFileWithBabel(file: File) {
file.extname = '.js';
transformedFiles.add(file);
}

/**
* Synchronized regex list of files that use `styled-components`.
* Used by `kbn-babel-preset` and `elastic-eslint-config-kibana`.
*/
export const USES_STYLED_COMPONENTS = [
/packages[\/\\]kbn-ui-shared-deps[\/\\]/,
/src[\/\\]plugins[\/\\](data|kibana_react)[\/\\]/,
/x-pack[\/\\]plugins[\/\\](apm|beats_management|cases|fleet|infra|lists|observability|osquery|security_solution|timelines|uptime)[\/\\]/,
/x-pack[\/\\]test[\/\\]plugin_functional[\/\\]plugins[\/\\]resolver_test[\/\\]/,
];
23 changes: 22 additions & 1 deletion packages/kbn-eslint-plugin-eslint/rules/module_migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ module.exports = {
disallowedMessage: {
type: 'string',
},
include: {
type: 'array',
},
exclude: {
type: 'array',
},
},
anyOf: [
{
Expand All @@ -95,7 +101,22 @@ module.exports = {
],
},
create: (context) => {
const mappings = context.options[0];
const filename = path.relative(KIBANA_ROOT, context.getFilename());

const mappings = context.options[0].filter((mapping) => {
// exclude mapping rule if it is explicitly excluded from this file
if (mapping.exclude && mapping.exclude.some((p) => p.test(filename))) {
return false;
}

// if this mapping rule is only included in specific files, optionally include it
if (mapping.include) {
return mapping.include.some((p) => p.test(filename));
}

// include all mapping rules by default
return true;
});

return {
ImportDeclaration(node) {
Expand Down
20 changes: 19 additions & 1 deletion packages/kbn-storybook/lib/default_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
* Side Public License, v 1.
*/

import * as path from 'path';
import { StorybookConfig } from '@storybook/core/types';
import { REPO_ROOT } from './constants';

const toPath = (_path: string) => path.join(REPO_ROOT, _path);
export const defaultConfig: StorybookConfig = {
addons: ['@kbn/storybook/preset', '@storybook/addon-a11y', '@storybook/addon-essentials'],
stories: ['../**/*.stories.tsx'],
Expand All @@ -22,6 +25,21 @@ export const defaultConfig: StorybookConfig = {

config.node = { fs: 'empty' };

return config;
// Remove when @storybook has moved to @emotion v11
// https://github.com/storybookjs/storybook/issues/13145
const emotion11CompatibleConfig = {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve?.alias,
'@emotion/core': toPath('node_modules/@emotion/react'),
'@emotion/styled': toPath('node_modules/@emotion/styled'),
'emotion-theming': toPath('node_modules/@emotion/react'),
},
},
};

return emotion11CompatibleConfig;
},
};
1 change: 1 addition & 0 deletions packages/kbn-storybook/lib/theme_switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export function ThemeSwitcher() {
closeOnClick
tooltip={({ onHide }) => <Menu onHide={onHide} />}
>
{/* @ts-ignore Remove when @storybook has moved to @emotion v11 */}
<IconButton key="eui-theme" title="Change the EUI theme">
<Icons icon={selectedTheme?.includes('dark') ? 'heart' : 'hearthollow'} />
</IconButton>
Expand Down
3 changes: 2 additions & 1 deletion packages/kbn-telemetry-tools/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/normalize-path",
"@npm//@types/testing-library__jest-dom",
"@npm//resize-observer-polyfill"
"@npm//resize-observer-polyfill",
"@npm//@emotion/react",
]

DEPS = SRC_DEPS + TYPES_DEPS
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-test/jest-preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ module.exports = {
snapshotSerializers: [
'<rootDir>/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts',
'<rootDir>/node_modules/enzyme-to-json/serializer',
'<rootDir>/node_modules/@emotion/jest/serializer',
],

// The test environment that will be used for testing
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-ui-shared-deps/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ SRC_DEPS = [
"@npm//@elastic/charts",
"@npm//@elastic/eui",
"@npm//@elastic/numeral",
"@npm//@emotion/react",
"@npm//abortcontroller-polyfill",
"@npm//angular",
"@npm//babel-loader",
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-ui-shared-deps/src/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const KbnI18n = require('@kbn/i18n');
export const KbnI18nAngular = require('@kbn/i18n/angular');
export const KbnI18nReact = require('@kbn/i18n/react');
export const Angular = require('angular');
export const EmotionReact = require('@emotion/react');
export const Moment = require('moment');
export const MomentTimezone = require('moment-timezone/moment-timezone');
export const KbnMonaco = require('@kbn/monaco');
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-ui-shared-deps/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ exports.externals = {
'@kbn/i18n': '__kbnSharedDeps__.KbnI18n',
'@kbn/i18n/angular': '__kbnSharedDeps__.KbnI18nAngular',
'@kbn/i18n/react': '__kbnSharedDeps__.KbnI18nReact',
'@emotion/react': '__kbnSharedDeps__.EmotionReact',
jquery: '__kbnSharedDeps__.Jquery',
moment: '__kbnSharedDeps__.Moment',
'moment-timezone': '__kbnSharedDeps__.MomentTimezone',
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { CoreSetup } from 'src/core/public';
import { CoreSetup as CoreSetup_2 } from 'kibana/public';
import { CoreStart } from 'kibana/public';
import { CoreStart as CoreStart_2 } from 'src/core/public';
import * as CSS from 'csstype';
import { Datatable as Datatable_2 } from 'src/plugins/expressions';
import { Datatable as Datatable_3 } from 'src/plugins/expressions/common';
import { DatatableColumn as DatatableColumn_2 } from 'src/plugins/expressions';
Expand Down Expand Up @@ -72,13 +71,12 @@ import { Plugin } from 'src/core/public';
import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public';
import { PluginInitializerContext as PluginInitializerContext_3 } from 'kibana/public';
import { PopoverAnchorPosition } from '@elastic/eui';
import * as PropTypes from 'prop-types';
import { PublicContract } from '@kbn/utility-types';
import { PublicMethodsOf } from '@kbn/utility-types';
import { PublicUiSettingsParams } from 'src/core/server/types';
import { RangeFilter as RangeFilter_2 } from 'src/plugins/data/public';
import React from 'react';
import * as React_3 from 'react';
import * as React_2 from 'react';
import { RecursiveReadonly } from '@kbn/utility-types';
import { Request as Request_2 } from '@hapi/hapi';
import { RequestAdapter } from 'src/plugins/inspector/common';
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions src/plugins/embeddable/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { ApiResponse } from '@elastic/elasticsearch/lib/Transport';
import { ApplicationStart as ApplicationStart_2 } from 'kibana/public';
import Boom from '@hapi/boom';
import { ConfigDeprecationProvider } from '@kbn/config';
import * as CSS from 'csstype';
import { DetailedPeerCertificate } from 'tls';
import { EmbeddableStart as EmbeddableStart_2 } from 'src/plugins/embeddable/public/plugin';
import { EnvironmentMode } from '@kbn/config';
Expand Down Expand Up @@ -44,7 +43,6 @@ import { PackageInfo } from '@kbn/config';
import { Path } from 'history';
import { PeerCertificate } from 'tls';
import { PluginInitializerContext } from 'src/core/public';
import * as PropTypes from 'prop-types';
import { PublicMethodsOf } from '@kbn/utility-types';
import { PublicUiSettingsParams } from 'src/core/server/types';
import React from 'react';
Expand Down Expand Up @@ -95,8 +93,7 @@ export interface Adapters {
//
// @public (undocumented)
export class AddPanelAction implements Action_3<ActionContext_2> {
// Warning: (ae-forgotten-export) The symbol "React" needs to be exported by the entry point index.d.ts
constructor(getFactory: EmbeddableStart_2['getEmbeddableFactory'], getAllFactories: EmbeddableStart_2['getEmbeddableFactories'], overlays: OverlayStart_2, notifications: NotificationsStart_2, SavedObjectFinder: React_2.ComponentType<any>, reportUiCounter?: ((appName: string, type: import("@kbn/analytics").UiCounterMetricType, eventNames: string | string[], count?: number | undefined) => void) | undefined);
constructor(getFactory: EmbeddableStart_2['getEmbeddableFactory'], getAllFactories: EmbeddableStart_2['getEmbeddableFactories'], overlays: OverlayStart_2, notifications: NotificationsStart_2, SavedObjectFinder: React.ComponentType<any>, reportUiCounter?: ((appName: string, type: import("@kbn/analytics").UiCounterMetricType, eventNames: string | string[], count?: number | undefined) => void) | undefined);
// (undocumented)
execute(context: ActionExecutionContext_2<ActionContext_2>): Promise<void>;
// (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"types": [
"node",
"jest",
"react"
"react",
"@emotion/react/types/css-prop"
]
},
"include": [
Expand Down
2 changes: 1 addition & 1 deletion test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true,
"types": ["node", "resize-observer-polyfill"]
"types": ["node", "resize-observer-polyfill", "@emotion/react/types/css-prop"]
},
"include": [
"**/*",
Expand Down
Loading

0 comments on commit 4926f46

Please sign in to comment.