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

[Meta][CSS-in-JS] Component conversions #5685

Closed
30 tasks done
Tracked by #3912
thompsongl opened this issue Mar 3, 2022 · 4 comments
Closed
30 tasks done
Tracked by #3912

[Meta][CSS-in-JS] Component conversions #5685

thompsongl opened this issue Mar 3, 2022 · 4 comments
Assignees
Milestone

Comments

@thompsongl
Copy link
Contributor

thompsongl commented Mar 3, 2022

Wiki Doc for How to Write Styles with Emotion

Completed

Utilities

Partially complete

  1. emotion task
    cee-chen
  2. emotion task
    cee-chen
  3. emotion task
    cee-chen
  4. emotion task
    cee-chen
  5. emotion task
    cee-chen

Display

  1. emotion task
  2. emotion task
    cee-chen
  3. emotion task
    cee-chen

Navigation

  1. emotion task
    cee-chen
  2. emotion task
    cee-chen
  3. emotion task
  4. emotion task
    cee-chen
  5. emotion task
    cee-chen
  6. emotion
    breehall
  7. emotion
    miukimiu
  8. emotion
    1Copenut

Layout

  1. emotion task
    cee-chen
  2. emotion task

Tables

  1. emotion task
    cee-chen
  2. emotion task

Forms

  1. emotion task
    cee-chen
  2. emotion task
    cee-chen
  3. emotion task
    cee-chen
  4. emotion task
    cee-chen
  5. emotion task
    cee-chen
  6. emotion task
    cee-chen

Low priority (3rd party components or components that may move out of EUI)

  1. emotion task
    cee-chen
  2. emotion task
    cee-chen
  3. emotion task
    cee-chen
  4. emotion task
@breehall
Copy link
Contributor

breehall commented Apr 7, 2022

Component Conversion Process

Converting the Sass styles to Emotion

1. New file structure

  • In the component directory (in src/components/{component} ), create a new file for Emotion styling. Files should follow the {component}.styles.ts naming structure (i.e avatar.styles.ts). In this file, convert the existing Sass styles to Emotion. For detailed information on converting styles, formatting styles, and creating style helpers, see writing styles with Emotion. For more detailed conversion checklist see comment below.
  • Import the new Emotion style file into the component ({component}.tsx). Import useEuiTheme() from the services directory and configure the component to use Emotion styling.

Example

//imports
import { useEuiTheme } from '../../services';
import { euiAvatarStyles } from './avatar.styles';

//set the theme and configure Emotion styling
const euiTheme = useEuiTheme();
const styles = euiAvatarStyles(euiTheme);
  • Downstream components that take mounted snapshots including the converted component may see some <Insertion> component shenanigans. These snapshots should be addressed by one of the following options:
    • Converting mount() to render()
    • Converting mount() to mount().render()
    • Avoid taking a snapshot and instead using a more specific assertion, depending on the test (e.g. if a specific component is supposed to be present)

2a. Convert & Remove Sass component styles

  • Move the Sass styles into the newly created {component}.styles.ts
  • Remove the Sass modules and stylesheets found in the component directory (in src/components/{component} ). This should include the stylesheets and the_index.scss file found in the component folder. In src/components/index.scss, remove the import for the component Sass module

2b. Update style props types by removing classNameMaps where possible

See #5889 for examples.

If the modifier piece of the class name --{modifier} is the same string as the possible prop values, switch to applying the modifier piece of the class name directly as they key. Remove the manual maps of property value to class name maps and change the array of values as an exported array as const.

Example:

const sizeToClassNameMap = {
  s: 'euiAvatar--s',
  m: 'euiAvatar--m',
  l: 'euiAvatar--l',
  xl: 'euiAvatar--xl',
};

export const SIZES = keysOf(sizeToClassNameMap);
export type EuiAvatarSize = keyof typeof sizeToClassNameMap;

const classes = classNames(
  'euiAvatar',
  sizeToClassNameMap[size],
);

Becomes:

export const SIZES = ['s', 'm', 'l', 'xl'] as const;
export type EuiAvatarSize = typeof SIZES[number];

const classes = classNames(
  'euiAvatar',
  {
    [`euiAvatar--${size}`]: size,
  },
);

If they don't match completely 1:1, you will need to keep the map, but remove the euiComponentName-- part of the value and still apply the className directly in the function:

export const MARGINS = ['none', 'xs', 's', 'm', 'l', 'xl', 'xxl'] as const;
export type EuiHorizontalRuleMargin = typeof MARGINS[number];

const marginToClassNameMap: {
  [value in EuiHorizontalRuleMargin]: string | null;
} = {
  none: null,
  xs: 'marginXSmall',
  ...
  xxl: 'marginXXLarge',
};

const classes = classNames(
  'euiHorizontalRule',
  {
    [`euiHorizontalRule--${marginToClassNameMap[margin]}`]: margin && margin !== 'none',
  },
);

2c. Removing vs. keeping classNames

In the above scenarios, removing the -- modifier classNames/maps may be a perfectly valid choice as well to clean up our classNames logic. Be sure to search through Kibana first for the modifier(s) classes:

  1. If no frequent Kibana usages come up (e.g. in CSS overrides or test selectors) outside of snapshots, fantastic! Go ahead and remove the classes.
  2. If there are minor usages, consider replacing the modifier class with a [data] attribute instead that consumers can target instead of a class.

NOTE: Generally, do not remove the top level className (e.g. .euiComponent) or child element classNames (e.g. .euiComponent__child). These classes serve as useful hooks/markers for consumers to use (both for CSS overrides and test selectors).

3. Move and remove style Amsterdam overrides (if present)

Check src/themes/amsterdam/overrides for component style overrides. If overrides are present:

  • Find the Sass module containing the override styles in src/themes/amsterdam/overrides/. The file will be named _{component}.scss.
  • Prioritize/move these styles into the new {component}.styles.ts file
  • Delete the old Sass file
  • In src/themes/amsterdam/overrides/_index.scss, remove the component Sass module import

4. Update component tests

  • Once styling changes have been tested and verified in browser, update component snapshots
  • Update the component test file ({component}.test.tsx) to use the shouldRenderCustomStyles utility:

Example

import { shouldRenderCustomStyles } from '../../test/internal';

describe('EuiAvatar', () => {
  test('it renders', () => { ... });

  shouldRenderCustomStyles(<EuiAvatar name="name" />);

  // more tests
}

5. Remove styling variables used by the EUI documentation site (if present)

  • Remove any styling variables related to the component from the rendered .json files by running the command yarn compile-scss

6. Deprecate any component-specific mixins

  • Add an @warn message within the global_styling/mixins/{component name}.scss file providing a recommendation if possible

Example if the recommendation is to use the actual React component

@mixin componentMixin(){
  ...
  @warn 'componentMixin() has been deprecated. Wrap your usage with <EuiComponentName /> instead.';
}

7. Update the documentation site playground (if using withEuiTheme HOC)

  • Import and use the component class that is wrapped by withEuiTheme()
  • Pass true as the second argument to propUtilityForPlayground
-  const docgenInfo = Array.isArray(EuiAccordion.__docgenInfo)
-    ? EuiAccordion.__docgenInfo[0]
-    : EuiAccordion.__docgenInfo;
-  const propsToUse = propUtilityForPlayground(docgenInfo.props);
+  const docgenInfo = Array.isArray(EuiAccordionClass.__docgenInfo)
+    ? EuiAccordionClass.__docgenInfo[0]
+    : EuiAccordionClass.__docgenInfo;
+  const propsToUse = propUtilityForPlayground(docgenInfo.props, true);

8. Changelog

Be sure to add the following header:

**CSS-in-JS conversions**

- Converted ___ to Emotion

If any Sass variables or mixins were removed, append them to the line item use a semi-colon separator

- Converted __ to Emotion; Removed `$___`

@cchaos
Copy link
Contributor

cchaos commented Apr 7, 2022

EDIT: We've moved this conversion checklist to our GitHub PR template instead. See #6294

@cchaos

This comment was marked as outdated.

@miukimiu miukimiu mentioned this issue Jun 21, 2022
11 tasks
jonathonherbert added a commit to guardian/typerighter that referenced this issue Mar 29, 2023
Necessary to style components that are not yet converted to Emotion (elastic/eui#5685)
jonathonherbert added a commit to guardian/typerighter that referenced this issue Mar 29, 2023
Necessary to style components that are not yet converted to Emotion (elastic/eui#5685)
jonathonherbert added a commit to guardian/typerighter that referenced this issue Mar 30, 2023
Necessary to style components that are not yet converted to Emotion (elastic/eui#5685)
@JasonStoltz JasonStoltz added the task A task associated with a larger Meta issue label Apr 8, 2024
@JasonStoltz JasonStoltz added this to the 8.16 FF milestone Aug 28, 2024
@JasonStoltz JasonStoltz removed the task A task associated with a larger Meta issue label Aug 28, 2024
@cee-chen
Copy link
Member

2.5 years later - all EUI components have been converted!! 🚀 🥲

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants