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

TS updates #34

Merged
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
44 changes: 25 additions & 19 deletions src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,16 @@ export interface EuiButtonProps extends CommonProps {
}

export interface EuiButtonDisplayProps extends EuiButtonProps {
element: 'a' | 'button' | 'label';
element: keyof JSX.IntrinsicElements;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, what is this/does this mean?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, would React.createElement help here in any way?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyof JSX.IntrinsicElements

It will allow for basically any HTML element

Also, would React.createElement help here in any way?

That's an interesting idea. Let me try it out; I'm not actually sure what TS will do it.

}

/**
*
* *INTERNAL ONLY* Component for displaying any element as a button
* EuiButton is largely responsible for providing relevant props
* and the logic for element-specific attributes
*/
const EuiButtonDisplay = React.forwardRef<
HTMLAnchorElement | HTMLButtonElement | HTMLLabelElement,
EuiButtonDisplayProps
>(
const EuiButtonDisplay = React.forwardRef<HTMLElement, EuiButtonDisplayProps>(
(
{
children,
Expand All @@ -127,14 +126,11 @@ const EuiButtonDisplay = React.forwardRef<
contentProps,
textProps,
fullWidth,
element: Element = 'button',
element = 'button',
...rest
},
ref
) => {
// If in the loading state, force disabled to true
isDisabled = isLoading ? true : isDisabled;

const classes = classNames(
'euiButton',
color ? colorToClassNameMap[color] : null,
Expand Down Expand Up @@ -170,10 +166,14 @@ const EuiButtonDisplay = React.forwardRef<
</EuiButtonContent>
);

return (
<Element className={classes} disabled={isDisabled} ref={ref} {...rest}>
{innerNode}
</Element>
return React.createElement(
element,
{
className: classes,
ref,
...rest,
},
innerNode
);
}
);
Expand Down Expand Up @@ -210,11 +210,17 @@ export const EuiButton: FunctionComponent<Props> = ({
buttonRef,
...rest
}) => {
const buttonIsDisabled = isDisabled || disabled;
// <Element> elements don't respect the `disabled` attribute. So if we're disabled, we'll just pretend
// this is a button and piggyback off its disabled styles.
const buttonIsDisabled = rest.isLoading || isDisabled || disabled;
const element = href && !isDisabled ? 'a' : 'button';

let elementProps = {};
// Props for all elements
elementProps = { ...elementProps, isDisabled: buttonIsDisabled };
// Element-specific attributes
if (element === 'button') {
elementProps = { ...elementProps, disabled: buttonIsDisabled };
}

const relObj: {
rel?: string;
href?: string;
Expand All @@ -233,10 +239,10 @@ export const EuiButton: FunctionComponent<Props> = ({
return (
<EuiButtonDisplay
element={element}
isDisabled={buttonIsDisabled}
{...elementProps}
{...relObj}
ref={buttonRef as Ref<HTMLButtonElement & HTMLAnchorElement>}
{...rest as HTMLAttributes<HTMLAnchorElement | HTMLButtonElement>}
ref={buttonRef}
{...rest}
/>
);
};