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

[EuiButtonGroup] Convert to Emotion #6841

Merged
merged 14 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/components/button/_index.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@import 'button_content';
@import 'button_empty/index';
@import 'button_icon/index';
@import 'button_group/index';
143 changes: 1 addition & 142 deletions src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,7 @@
* Side Public License, v 1.
*/

import React, {
forwardRef,
FunctionComponent,
Ref,
CSSProperties,
HTMLAttributes,
ReactNode,
} from 'react';
import classNames from 'classnames';
import React, { FunctionComponent, Ref, ReactNode } from 'react';

import {
CommonProps,
Expand All @@ -23,7 +15,6 @@ import {
PropsForButton,
} from '../common';

import { EuiButtonContentDeprecated as EuiButtonContent } from './_button_content_deprecated';
import {
BUTTON_COLORS,
useEuiButtonColorCSS,
Expand Down Expand Up @@ -137,135 +128,3 @@ EuiButton.defaultProps = {
size: 'm',
color: 'primary',
};

export type EuiButtonDisplayProps = EuiButtonProps &
HTMLAttributes<HTMLElement> & {
/**
* Provide a valid element to render the element as
*/
element: 'a' | 'button' | 'span' | 'label';
/**
* Provide the component's base class name to build the class list on
*/
baseClassName: string;
};

export const sizeToClassNameMap: { [size in EuiButtonSize]: string | null } = {
s: '--small',
m: null,
};

export const colorToClassNameMap: {
[color in EuiButtonColor]: string | null;
} = {
primary: '--primary',
accent: '--accent',
success: '--success',
warning: '--warning',
danger: '--danger',
ghost: '--ghost',
text: '--text',
};

/**
* *DEPRECATED*
* EuiButtonDisplay is an internal-only component used for displaying
* any element as a button.
* NOTE: This component *must* be below EuiButton in the file and
* EuiButton must also set a displayName for react-docgen-typescript
* to correctly set EuiButton's docgenInfo and display a props table.
* This component has been deprecated in favor of the new EuiButtonDisplay
* that can be found in `src/components/button/button_display/_button_display.tsx`
*/
export const EuiButtonDisplayDeprecated = forwardRef<
HTMLElement,
EuiButtonDisplayProps
>(
(
{
element = 'button',
baseClassName,
children,
className,
iconType,
iconSide = 'left',
color,
size = 'm',
isDisabled,
isLoading,
isSelected,
contentProps,
textProps,
fullWidth,
minWidth,
style,
...rest
},
ref
) => {
const buttonIsDisabled = isButtonDisabled({ isLoading, isDisabled });

const classes = classNames(
baseClassName,
color && colorToClassNameMap[color]
? `${baseClassName}${colorToClassNameMap[color]}`
: undefined,
size && sizeToClassNameMap[size]
? `${baseClassName}${sizeToClassNameMap[size]}`
: null,
fullWidth && `${baseClassName}--fullWidth`,
className
);

/**
* Not changing the content or text class names to match baseClassName yet,
* as it is a major breaking change.
*/
const contentClassNames = classNames(
'euiButton__content',
contentProps && contentProps.className
);

const textClassNames = classNames(
'euiButton__text',
textProps && textProps.className
);

const innerNode = (
<EuiButtonContent
isLoading={isLoading}
iconType={iconType}
iconSide={iconSide}
textProps={{ ...textProps, className: textClassNames }}
{...contentProps}
// className has to come last to override contentProps.className
className={contentClassNames}
>
{children}
</EuiButtonContent>
);

let calculatedStyle: CSSProperties | undefined = style;
if (minWidth !== undefined || minWidth !== null) {
calculatedStyle = {
...calculatedStyle,
// @ts-ignore - deprecated component
minWidth,
};
}

return React.createElement(
element,
{
className: classes,
style: calculatedStyle,
disabled: element === 'button' && buttonIsDisabled,
'aria-pressed': element === 'button' ? isSelected : undefined,
ref,
...rest,
},
innerNode
);
}
);
EuiButtonDisplayDeprecated.displayName = 'EuiButtonDisplay';
41 changes: 40 additions & 1 deletion src/components/button/button_display/_button_display.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { EuiButtonDisplay } from './_button_display';

describe('EuiButtonDisplay', () => {
shouldRenderCustomStyles(<EuiButtonDisplay>Text</EuiButtonDisplay>, {
childProps: ['textProps'],
childProps: ['contentProps', 'textProps'],
});

it('renders', () => {
Expand Down Expand Up @@ -54,6 +54,45 @@ describe('EuiButtonDisplay', () => {
});
});

describe('element', () => {
const elements = ['a', 'button', 'span', 'label'] as const;

const getButtonElement = (container: HTMLElement) =>
container.firstChild!.nodeName.toLowerCase();

elements.forEach((element) => {
test(element, () => {
const { container } = render(
<EuiButtonDisplay element={element} className="testing">
Content
</EuiButtonDisplay>
);

expect(getButtonElement(container)).toEqual(element);
});
});

it('always renders a `button` element if disabled', () => {
const { container } = render(
<EuiButtonDisplay element="label" isDisabled>
Content
</EuiButtonDisplay>
);

expect(getButtonElement(container)).toEqual('button');
});

it('always renders an `a` element if a href is passed', () => {
const { container } = render(
<EuiButtonDisplay element="span" href="#">
Content
</EuiButtonDisplay>
);

expect(getButtonElement(container)).toEqual('a');
});
});

describe('disabled behavior', () => {
it('disables hrefs with javascript in them and renders a button instead of a link', () => {
const { container } = render(
Expand Down
6 changes: 4 additions & 2 deletions src/components/button/button_display/_button_display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type EuiButtonDisplaySizes = (typeof SIZES)[number];
export interface EuiButtonDisplayCommonProps
extends EuiButtonDisplayContentProps,
CommonProps {
element?: 'a' | 'button' | 'span' | 'label';
children?: ReactNode;
size?: EuiButtonDisplaySizes;
/**
Expand Down Expand Up @@ -109,6 +110,8 @@ export function isButtonDisabled({
export const EuiButtonDisplay = forwardRef<HTMLElement, EuiButtonDisplayProps>(
(
{
element: _element = 'button',
type = 'button',
children,
iconType,
iconSide = 'left',
Expand All @@ -125,7 +128,6 @@ export const EuiButtonDisplay = forwardRef<HTMLElement, EuiButtonDisplayProps>(
href,
target,
rel,
type = 'button',
style,
...rest
},
Expand Down Expand Up @@ -164,7 +166,7 @@ export const EuiButtonDisplay = forwardRef<HTMLElement, EuiButtonDisplayProps>(
</EuiButtonDisplayContent>
);

const element = href && !buttonIsDisabled ? 'a' : 'button';
const element = buttonIsDisabled ? 'button' : href ? 'a' : _element;
let elementProps = {};
// Element-specific attributes
if (element === 'button') {
Expand Down
Loading