Skip to content

Commit

Permalink
[CSS-in-JS] Convert EuiMark (elastic#4575)
Browse files Browse the repository at this point in the history
* placeholder docs

* CL TODO

* converting euimark styles to emotion

* import location

* move CL

* rename style file; style factory pattern

* use simple return

* update generated classname pattern

* update snapshots

* better class name generation

* cl

* Update src/components/mark/mark.styles.ts

Co-authored-by: Caroline Horn <[email protected]>

* clean up

* better wiki

* more wiki

* Update wiki/creating-components-manually.md

Co-authored-by: Constance <[email protected]>

Co-authored-by: Caroline Horn <[email protected]>
Co-authored-by: Constance <[email protected]>
  • Loading branch information
3 people authored Mar 15, 2022
1 parent fddf0d2 commit e7b3917
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 32 deletions.
3 changes: 2 additions & 1 deletion .babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ module.exports = {
[
"@emotion/babel-preset-css-prop",
{
"labelFormat": "[filename]-[local]"
"autoLabel": "always",
"labelFormat": "[local]"
},
],
],
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

- Removed Legacy theme including compiled CSS ([#5688](https://github.com/elastic/eui/pull/5688))

**CSS-in-JS conversions**

- Converted `EuiMark` to CSS-in-JS styling ([#4575](https://github.com/elastic/eui/pull/4575))

## [`51.1.0`](https://github.com/elastic/eui/tree/v51.1.0)

- Updated `testenv` mock for `EuiFlyout` to include default `aria-label` on the close button ([#5702](https://github.com/elastic/eui/pull/5702))
Expand Down
28 changes: 23 additions & 5 deletions src/components/highlight/__snapshots__/highlight.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EuiHighlight behavior loose matching matches strings with different casing 1`] = `
.emotion-0 {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
<span>
different
<mark
class="euiMark"
class="euiMark emotion-0"
>
case
</mark>
Expand All @@ -13,31 +19,43 @@ exports[`EuiHighlight behavior loose matching matches strings with different cas
`;

exports[`EuiHighlight behavior matching applies to all matches 1`] = `
.emotion-0 {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
<span>
<mark
class="euiMark"
class="euiMark emotion-0"
>
match
</mark>
<mark
class="euiMark"
class="euiMark emotion-0"
>
match
</mark>
<mark
class="euiMark"
class="euiMark emotion-0"
>
match
</mark>
</span>
`;

exports[`EuiHighlight behavior matching only applies to first match 1`] = `
.emotion-0 {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
<span>
<mark
class="euiMark"
class="euiMark emotion-0"
>
match
</mark>
Expand Down
1 change: 0 additions & 1 deletion src/components/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
@import 'list_group/index';
@import 'loading/index';
@import 'markdown_editor/index';
@import 'mark/index';
@import 'modal/index';
@import 'notification/index';
@import 'overlay_mask/index';
Expand Down
8 changes: 7 additions & 1 deletion src/components/mark/__snapshots__/mark.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EuiMark is rendered 1`] = `
.emotion-0 {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
<mark
class="euiMark"
class="euiMark emotion-0"
>
Marked
</mark>
Expand Down
1 change: 0 additions & 1 deletion src/components/mark/_index.scss

This file was deleted.

7 changes: 0 additions & 7 deletions src/components/mark/_mark.scss

This file was deleted.

26 changes: 26 additions & 0 deletions src/components/mark/mark.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { css } from '@emotion/react';
import { UseEuiTheme, transparentize } from '../../services';

export const euiMarkStyles = ({ euiTheme, colorMode }: UseEuiTheme) => {
// TODO: Was $euiFocusBackgroundColor
const transparency = { LIGHT: 0.1, DARK: 0.3 };

return css`
background-color: ${transparentize(
euiTheme.colors.primary,
transparency[colorMode]
)};
font-weight: ${euiTheme.font.weight.bold};
// Override the browser's black color.
// Can't use 'inherit' because the text to background color contrast may not be sufficient
color: ${euiTheme.colors.text};
`;
};
8 changes: 6 additions & 2 deletions src/components/mark/mark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
*/

import React, { HTMLAttributes, FunctionComponent, ReactNode } from 'react';
import { CommonProps } from '../common';
import classNames from 'classnames';
import { CommonProps } from '../common';
import { useEuiTheme } from '../../services';
import { euiMarkStyles } from './mark.styles';
export type EuiMarkProps = HTMLAttributes<HTMLElement> &
CommonProps & {
/**
Expand All @@ -22,10 +24,12 @@ export const EuiMark: FunctionComponent<EuiMarkProps> = ({
className,
...rest
}) => {
const useTheme = useEuiTheme();
const styles = euiMarkStyles(useTheme);
const classes = classNames('euiMark', className);

return (
<mark className={classes} {...rest}>
<mark css={[styles]} className={classes} {...rest}>
{children}
</mark>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2127,6 +2127,12 @@ exports[`EuiSelectableListItem props rowHeight 1`] = `
`;

exports[`EuiSelectableListItem props searchValue 1`] = `
.emotion-0 {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
<div
class="euiSelectableList testClass1 testClass2"
data-test-subj="test subject string"
Expand Down Expand Up @@ -2222,7 +2228,7 @@ exports[`EuiSelectableListItem props searchValue 1`] = `
>
<span>
<mark
class="euiMark"
class="euiMark emotion-0"
>
Mi
</mark>
Expand Down Expand Up @@ -2322,6 +2328,12 @@ exports[`EuiSelectableListItem props searchValue 1`] = `
`;

exports[`EuiSelectableListItem props searchValue 2`] = `
.emotion-0 {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
<div
class="euiSelectableList testClass1 testClass2"
data-test-subj="test subject string"
Expand Down Expand Up @@ -2417,7 +2429,7 @@ exports[`EuiSelectableListItem props searchValue 2`] = `
>
<span>
<mark
class="euiMark"
class="euiMark emotion-0"
>
Mi
</mark>
Expand Down
1 change: 0 additions & 1 deletion src/themes/amsterdam/overrides/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
@import 'list_group_item';
@import 'image';
@import 'key_pad_menu';
@import 'mark';
@import 'markdown_editor';
@import 'modal';
@import 'notification_badge';
Expand Down
3 changes: 0 additions & 3 deletions src/themes/amsterdam/overrides/_mark.scss

This file was deleted.

11 changes: 4 additions & 7 deletions wiki/creating-components-manually.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
# Creating components manually

## Create component SCSS files
## Create component style files

1. Create a directory for your component in `src/components`.
2. In this directory, create `_{component name}.scss`.
3. _Optional:_ Create any other components that should be [logically-grouped][docs-logical-group] in this directory.
4. Create an `_index.scss` file in this directory that import all of the new component SCSS files you created.
5. Import the `_index.scss` file into `src/components/index.scss`.
2. Create a `{component name}.styles.ts` file inside the directory

This makes your styles available to your project and to the [EUI documentation][docs].
Refer to the [Writing styles with emotion](./writing-styles-with-emotion.md) guidelines for more instruction.

## Create the React component

1. Create the React component(s) (preferably as TypeScript) in the same directory as the related SCSS file(s).
1. Create the React component(s) (preferably as TypeScript) in the same directory as the related style file(s).
2. Export these components from an `index.ts` file.
3. Re-export these components from `src/components/index.ts`.

Expand Down
38 changes: 37 additions & 1 deletion wiki/writing-styles-with-emotion.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
EUI uses [`Emotion`](https://emotion.sh/) when writing CSS-in-JS styles.
A general knowledge of writing CSS is enough in most cases, but there are some JavaScript-related differences that can result in unintended output. Similarly, there are feaures that don't exist in CSS of which we like to take advantage.


## File patterns

```ts
/* {component name}.styles.ts */
import { css } from '@emotion/react';
import { UseEuiTheme } from '../../services';

export const euiComponentNameStyles = ({ euiTheme }: UseEuiTheme) => {
return css`
color: ${euiTheme.colors.primary};
`;
};
```

```tsx
/* {component name}.tsx */
import { useEuiTheme } from '../../services';
import { euiComponentNameStyles } from './{component name}.styles.ts';

export const EuiComponent = () => {
const theme = useEuiTheme();
const styles = euiComponentStyles(theme);

return (
<div css={[styles]} />
);
};
```

## Conditional styles

Styles can be added conditionally based on environment variables, such as the active theme, using nested string template literals.
Expand All @@ -22,4 +52,10 @@ Although possible in some contexts, it is not recommended to "shortcut" logic us

## The `css` prop

TBD
_Work in progress_

* Use an array inside of the `css` prop for optimal style composition and class name generation. This is relevant even if only a single style object is passed.

```tsx
<EuiComponent css={[styles.default, styles.stateful]} />
```

0 comments on commit e7b3917

Please sign in to comment.