Skip to content

Commit

Permalink
Added internationalized screen reader helpers to EuiMark. (#5739)
Browse files Browse the repository at this point in the history
* Added internationalized screen reader helpers to EuiMark.
* Added SR-only text using EuiScreenReaderOnly.
* Adding i18n to the highlight start and end.
* Updating tests and declaring React Fragment.
* Adding a new changelog entry for 3072.
* Uploading the correct CHANGELOG file number.
* Update upcoming_changelogs/5739.md
Co-authored-by: Greg Thompson <thompson.glowe@gmail.com>
* Refactoring to use CSS-in-JS
* Refactoring to toggle helper text.
* Extending euiMarkStyles method locally instead of globally.
* Adding hasScreenReaderHelpText prop to Highlight component.
* Simplifying the highlight type checks and adding Emotion output to unit test.
* Picking EuiMark prop for cleaner EuiHighlight typing.
* Updated EuiMark test to include Emotion output in snapshot.
* Fixing lint errors.
* Renaming a test for better context.
Co-authored-by: Greg Thompson <thompson.glowe@gmail.com>
  • Loading branch information
1Copenut committed Apr 7, 2022
1 parent ea931b5 commit 6912640
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 17 deletions.
32 changes: 27 additions & 5 deletions src/components/highlight/__snapshots__/highlight.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ exports[`EuiHighlight behavior loose matching matches strings with different cas
<span>
different
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
case
</mark>
Expand All @@ -15,19 +15,41 @@ exports[`EuiHighlight behavior loose matching matches strings with different cas
exports[`EuiHighlight behavior matching applies to all matches 1`] = `
<span>
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
match
</mark>
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
match
</mark>
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
match
</mark>
</span>
`;

exports[`EuiHighlight behavior matching hasScreenReaderHelpText can be false 1`] = `
<span>
<mark
class="euiMark css-dtzpxu-euiMarkStyles-EuiMark"
>
match
</mark>
<mark
class="euiMark css-dtzpxu-euiMarkStyles-EuiMark"
>
match
</mark>
<mark
class="euiMark css-dtzpxu-euiMarkStyles-EuiMark"
>
match
</mark>
Expand All @@ -37,7 +59,7 @@ exports[`EuiHighlight behavior matching applies to all matches 1`] = `
exports[`EuiHighlight behavior matching only applies to first match 1`] = `
<span>
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
match
</mark>
Expand Down
14 changes: 14 additions & 0 deletions src/components/highlight/highlight.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ describe('EuiHighlight', () => {

expect(component).toMatchSnapshot();
});

test('hasScreenReaderHelpText can be false', () => {
const component = render(
<EuiHighlight
search="match"
highlightAll
hasScreenReaderHelpText={false}
>
match match match
</EuiHighlight>
);

expect(component).toMatchSnapshot();
});
});

describe('loose matching', () => {
Expand Down
30 changes: 25 additions & 5 deletions src/components/highlight/highlight.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import React, { Fragment, HTMLAttributes, FunctionComponent } from 'react';
import { CommonProps } from '../common';
import { EuiMark } from '../mark';
import { EuiMark, EuiMarkProps } from '../mark';

interface EuiHighlightChunk {
/**
Expand All @@ -25,7 +25,10 @@ interface EuiHighlightChunk {
highlight?: boolean;
}

type EuiMarkPropHelpText = Pick<EuiMarkProps, 'hasScreenReaderHelpText'>;

export type EuiHighlightProps = HTMLAttributes<HTMLSpanElement> &
EuiMarkPropHelpText &
CommonProps & {
/**
* string to highlight as this component's content
Expand All @@ -52,7 +55,8 @@ const highlight = (
searchSubject: string,
searchValue: string,
isStrict: boolean,
highlightAll: boolean
highlightAll: boolean,
hasScreenReaderHelpText: boolean
) => {
if (!searchValue) {
return searchSubject;
Expand All @@ -70,7 +74,14 @@ const highlight = (
const { end, highlight, start } = chunk;
const value = searchSubject.substr(start, end - start);
if (highlight) {
return <EuiMark key={start}>{value}</EuiMark>;
return (
<EuiMark
key={start}
hasScreenReaderHelpText={hasScreenReaderHelpText}
>
{value}
</EuiMark>
);
}
return value;
})}
Expand Down Expand Up @@ -101,7 +112,9 @@ const highlight = (
return (
<Fragment>
{preMatch}
<EuiMark>{match}</EuiMark>
<EuiMark hasScreenReaderHelpText={hasScreenReaderHelpText}>
{match}
</EuiMark>
{postMatch}
</Fragment>
);
Expand Down Expand Up @@ -158,11 +171,18 @@ export const EuiHighlight: FunctionComponent<EuiHighlightProps> = ({
search,
strict = false,
highlightAll = false,
hasScreenReaderHelpText = true,
...rest
}) => {
return (
<span className={className} {...rest}>
{highlight(children, search, strict, highlightAll)}
{highlight(
children,
search,
strict,
highlightAll,
hasScreenReaderHelpText
)}
</span>
);
};
42 changes: 39 additions & 3 deletions src/components/mark/__snapshots__/mark.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,58 @@
exports[`EuiMark is rendered 1`] = `
<mark
aria-label="aria-label"
class="euiMark testClass1 testClass2 css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark testClass1 testClass2 css-b9vly9-euiMarkStyles-EuiMark"
data-test-subj="test subject string"
>
Marked
</mark>
`;

exports[`EuiMark is rendered: renders with emotion styles 1`] = `
.css-1izqibv-euiMarkStyles-EuiMark {
.css-b9vly9-euiMarkStyles-EuiMark {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
.css-b9vly9-euiMarkStyles-EuiMark:before,
.css-b9vly9-euiMarkStyles-EuiMark:after {
-webkit-clip-path: inset(100%);
clip-path: inset(100%);
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
.css-b9vly9-euiMarkStyles-EuiMark:before {
content: ' [highlight start] ';
}
.css-b9vly9-euiMarkStyles-EuiMark:after {
content: ' [highlight end] ';
}
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
Marked
</mark>
`;

exports[`No screen reader helper text is rendered without CSS :before and :after text 1`] = `
.css-dtzpxu-euiMarkStyles-EuiMark {
background-color: rgba(0,119,204,0.1);
font-weight: 700;
color: #343741;
}
<mark
aria-label="aria-label"
class="euiMark testClass1 testClass2 css-dtzpxu-euiMarkStyles-EuiMark"
data-test-subj="test subject string"
>
Marked
</mark>
Expand Down
1 change: 1 addition & 0 deletions src/components/mark/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
* Side Public License, v 1.
*/

export type { EuiMarkProps } from './mark';
export { EuiMark } from './mark';
36 changes: 35 additions & 1 deletion src/components/mark/mark.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@
import { css } from '@emotion/react';
import { UseEuiTheme, transparentize } from '../../services';

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

Expand All @@ -22,5 +33,28 @@ export const euiMarkStyles = ({ euiTheme, colorMode }: UseEuiTheme) => {
// 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};
// https://seanconnolly.dev/emotion-conditionals
${hasScreenReaderHelpText === true &&
`
&:before,
&:after {
clip-path: inset(100%);
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
&:before {
content: ' [${highlightStart}] ';
}
&:after {
content: ' [${highlightEnd}] ';
}
`}
`;
};
14 changes: 14 additions & 0 deletions src/components/mark/mark.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,17 @@ describe('EuiMark', () => {
).toMatchSnapshot();
});
});

describe('No screen reader helper text', () => {
renderWithStyles(<EuiMark>Marked</EuiMark>);

test('is rendered without CSS :before and :after text', () => {
expect(
render(
<EuiMark hasScreenReaderHelpText={false} {...requiredProps}>
Marked
</EuiMark>
)
).toMatchSnapshot();
});
});
18 changes: 17 additions & 1 deletion src/components/mark/mark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@

import React, { HTMLAttributes, FunctionComponent, ReactNode } from 'react';
import classNames from 'classnames';
import { useEuiI18n } from '../i18n';
import { CommonProps } from '../common';
import { useEuiTheme } from '../../services';
import { euiMarkStyles } from './mark.styles';
export type EuiMarkProps = HTMLAttributes<HTMLElement> &
CommonProps & {
/**
* Set to `false` to remove the CSS :before and :after
* screen reader helper text
*/
hasScreenReaderHelpText?: boolean;
/**
* ReactNode to render as this component's content
*/
Expand All @@ -22,10 +28,20 @@ export type EuiMarkProps = HTMLAttributes<HTMLElement> &
export const EuiMark: FunctionComponent<EuiMarkProps> = ({
children,
className,
hasScreenReaderHelpText = true,
...rest
}) => {
const useTheme = useEuiTheme();
const styles = euiMarkStyles(useTheme);
const highlightStart = useEuiI18n(
'euiMark.highlightStart',
'highlight start'
);
const highlightEnd = useEuiI18n('euiMark.highlightEnd', 'highlight end');
const styles = euiMarkStyles(useTheme, {
hasScreenReaderHelpText,
highlightStart,
highlightEnd,
});
const classes = classNames('euiMark', className);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2222,7 +2222,7 @@ exports[`EuiSelectableListItem props searchValue 1`] = `
>
<span>
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
Mi
</mark>
Expand Down Expand Up @@ -2417,7 +2417,7 @@ exports[`EuiSelectableListItem props searchValue 2`] = `
>
<span>
<mark
class="euiMark css-1izqibv-euiMarkStyles-EuiMark"
class="euiMark css-b9vly9-euiMarkStyles-EuiMark"
>
Mi
</mark>
Expand Down
1 change: 1 addition & 0 deletions upcoming_changelogs/5739.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added internationalized screen reader helpers to `EuiMark`

0 comments on commit 6912640

Please sign in to comment.