Skip to content

Commit

Permalink
Migrate EuiEmptyPromptand EuiCard to TS (#2387)
Browse files Browse the repository at this point in the history
This required some tweaks in a few places.

* Update changelog
  • Loading branch information
pugnascotia authored Sep 27, 2019
1 parent 28d51ad commit e788120
Show file tree
Hide file tree
Showing 21 changed files with 175 additions and 203 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ No public interface changes since `14.3.0`.
- Added `visAreaStacked`, `visBarVerticalStacked`, and `visBarHorizontalStacked` icons to glyph set ([#2379](https://github.com/elastic/eui/pull/2379))
- Adjusted style of beta badge on `EuiKeyPadMenuItem` ([#2375](https://github.com/elastic/eui/pull/2375))
- Migrate `EuiFacetGroup`, `EuiKeyPadMenu` and `EuiCallOut` to TS ([#2382](https://github.com/elastic/eui/pull/2382))
- Migrate `EuiEmptyPrompt`and `EuiCard` to TS ([#2387](https://github.com/elastic/eui/pull/2387))

**Bug fixes**

Expand Down
11 changes: 9 additions & 2 deletions src/components/button/button_empty/button_empty.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ import { EuiLoadingSpinner } from '../../loading';
import { getSecureRelForTarget } from '../../../services';
import { IconType, EuiIcon } from '../../icon';

const colorToClassNameMap = {
export type EuiButtonEmptyColor =
| 'primary'
| 'danger'
| 'disabled'
| 'text'
| 'ghost';

const colorToClassNameMap: { [color in EuiButtonEmptyColor]: string } = {
primary: 'euiButtonEmpty--primary',
danger: 'euiButtonEmpty--danger',
disabled: 'euiButtonEmpty--disabled',
Expand Down Expand Up @@ -47,7 +54,7 @@ export const FLUSH_TYPES = keysOf(flushTypeToClassNameMap);
export interface EuiButtonEmptyProps extends CommonProps {
iconType?: IconType;
iconSide?: keyof typeof iconSideToClassNameMap;
color?: keyof typeof colorToClassNameMap;
color?: EuiButtonEmptyColor;
size?: keyof typeof sizeToClassNameMap;
flush?: keyof typeof flushTypeToClassNameMap;
isDisabled?: boolean;
Expand Down
1 change: 1 addition & 0 deletions src/components/button/button_empty/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export {
ICON_SIDES,
EuiButtonEmpty,
EuiButtonEmptyProps,
EuiButtonEmptyColor,
} from './button_empty';
File renamed without changes.
180 changes: 91 additions & 89 deletions src/components/card/card.js → src/components/card/card.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,138 @@
import React from 'react';
import PropTypes from 'prop-types';
import React, { FunctionComponent, ReactElement, ReactNode } from 'react';
import classNames from 'classnames';
import { getSecureRelForTarget } from '../../services';

import { CommonProps, keysOf } from '../common';
import { getSecureRelForTarget } from '../../services';
import { EuiText } from '../text';
import { EuiTitle } from '../title';
import { EuiBetaBadge } from '../badge/beta_badge';
import { EuiIconProps } from '../icon';
import {
EuiCardSelect,
EuiCardSelectProps,
euiCardSelectableColor,
} from './card_select';
import makeId from '../form/form_row/make_id';

const textAlignToClassNameMap = {
type CardAlignment = 'left' | 'center' | 'right';

const textAlignToClassNameMap: { [alignment in CardAlignment]: string } = {
left: 'euiCard--leftAligned',
center: 'euiCard--centerAligned',
right: 'euiCard--rightAligned',
};

export const ALIGNMENTS = Object.keys(textAlignToClassNameMap);
export const ALIGNMENTS = keysOf(textAlignToClassNameMap);

type CardLayout = 'vertical' | 'horizontal';

const layoutToClassNameMap = {
const layoutToClassNameMap: { [layout in CardLayout]: string } = {
vertical: '',
horizontal: 'euiCard--horizontal',
};

export const LAYOUT_ALIGNMENTS = Object.keys(layoutToClassNameMap);
const oneOfLayouts = PropTypes.oneOf(LAYOUT_ALIGNMENTS);
export const LAYOUT_ALIGNMENTS = keysOf(layoutToClassNameMap);

const cardLayout = (props, propName, componentName, ...rest) => {
const oneOfResult = oneOfLayouts(props, propName, componentName, ...rest);
if (oneOfResult) return oneOfResult;
type EuiCardProps = CommonProps & {
title: NonNullable<ReactNode>;
/**
* Determines the title's heading element. Will force to 'span' if
* the card is a button.
*/
titleElement?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span';
description: NonNullable<ReactNode>;

if (props[propName] === 'horizontal') {
if (props.image || props.footer) {
return new Error(
`${componentName}: '${propName} = horizontal' cannot be used in conjunction with 'image', 'footer', or 'textAlign'.`
);
}
}
/**
* Requires a <EuiIcon> node
*/
icon?: ReactElement<EuiIconProps>;

/**
* Accepts a url in string form
*/
image?: string;

/**
* Accepts any combination of elements
*/
footer?: ReactNode;

/**
* Use only if you want to forego a button in the footer and make the whole card clickable
*/
onClick?: Function;
href?: string;
target?: string;
rel?: string;
textAlign?: CardAlignment;

/**
* Change to "horizontal" if you need the icon to be left of the content
*/
layout?: CardLayout;

/**
* Add a badge to the card to label it as "Beta" or other non-GA state
*/
betaBadgeLabel?: string;

/**
* Add a description to the beta badge (will appear in a tooltip)
*/
betaBadgeTooltipContent?: ReactNode;

/**
* Optional title will be supplied as tooltip title or title attribute otherwise the label will be used
*/
betaBadgeTitle?: string;

/**
* Adds a button to the bottom of the card to allow for in-place selection.
*/
selectable?: EuiCardSelectProps;

/**
* Add a decorative bottom graphic to the card.
* This should be used sparingly, consult the Kibana Design team before use.
*/
bottomGraphic?: ReactNode;

isClickable?: boolean;

isDisabled?: boolean;
};

export const EuiCard = ({
export const EuiCard: FunctionComponent<EuiCardProps> = ({
className,
description,
isDisabled,
title,
titleElement,
titleElement = 'span',
icon,
image,
footer,
onClick,
href,
rel,
target,
textAlign,
textAlign = 'center',
isClickable,
betaBadgeLabel,
betaBadgeTooltipContent,
betaBadgeTitle,
layout,
layout = 'vertical',
bottomGraphic,
selectable,
...rest
}) => {
if (layout === 'horizontal') {
if (image || footer) {
throw new Error(
"EuiCard: layout = horizontal' cannot be used in conjunction with 'image', 'footer', or 'textAlign'."
);
}
}

const selectableColorClass = selectable
? `euiCard--isSelectable--${euiCardSelectableColor(
selectable.color,
Expand Down Expand Up @@ -171,6 +239,7 @@ export const EuiCard = ({
}

return (
// @ts-ignore
<OuterElement
onClick={onClick}
className={classes}
Expand Down Expand Up @@ -205,73 +274,6 @@ export const EuiCard = ({
);
};

EuiCard.propTypes = {
className: PropTypes.string,
title: PropTypes.node.isRequired,
/**
* Determines the title's heading element. Will force to 'span' if
* the card is a button.
*/
titleElement: PropTypes.oneOf(['h2', 'h3', 'h4', 'h5', 'h6', 'span']),
description: PropTypes.node.isRequired,

/**
* Requires a <EuiIcon> node
*/
icon: PropTypes.node,

/**
* Accepts a url in string form
*/
image: PropTypes.string,

/**
* Accepts any combination of elements
*/
footer: PropTypes.node,

/**
* Use only if you want to forego a button in the footer and make the whole card clickable
*/
onClick: PropTypes.func,
href: PropTypes.string,
target: PropTypes.string,
rel: PropTypes.string,
textAlign: PropTypes.oneOf(ALIGNMENTS),

/**
* Change to "horizontal" if you need the icon to be left of the content
*/
layout: cardLayout,

/**
* Add a badge to the card to label it as "Beta" or other non-GA state
*/
betaBadgeLabel: PropTypes.string,

/**
* Add a description to the beta badge (will appear in a tooltip)
*/
betaBadgeTooltipContent: PropTypes.node,

/**
* Optional title will be supplied as tooltip title or title attribute otherwise the label will be used
*/
betaBadgeTitle: PropTypes.string,

/**
* Adds a button to the bottom of the card to allow for in-place selection.
*/
selectable: PropTypes.shape(EuiCardSelectProps),

/**
* Add a decorative bottom graphic to the card.
* This should be used sparingly, consult the Kibana Design team before use.
*/
bottomGraphic: PropTypes.node,
isDisabled: PropTypes.bool,
};

EuiCard.defaultProps = {
textAlign: 'center',
layout: 'vertical',
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import React, { FunctionComponent, MouseEventHandler, ReactNode } from 'react';
import classNames from 'classnames';

import {
EuiButtonEmpty,
COLORS as BUTTON_EMPTY_COLORS,
} from '../button/button_empty';
import { CommonProps } from '../common';
import { EuiButtonEmpty, EuiButtonEmptyColor } from '../button/button_empty';

import { EuiI18n } from '../i18n';

export const EuiCardSelect = ({
export type EuiCardSelectProps = CommonProps & {
/**
* You must handle the click event in order to have a select button
*/
onClick: MouseEventHandler<HTMLButtonElement>;
/**
* Is in the selected state
*/
isSelected?: boolean;
isDisabled?: boolean;
/**
* Override the default color with one of the available colors from `EuiButtonEmpty`
*/
color?: EuiButtonEmptyColor;
};

export const EuiCardSelect: FunctionComponent<EuiCardSelectProps> = ({
className,
onClick,
isSelected,
Expand Down Expand Up @@ -40,30 +53,11 @@ export const EuiCardSelect = ({
);
};

export const EuiCardSelectProps = {
className: PropTypes.string,
/**
* You must handle the click event in order to have a select button
*/
onClick: PropTypes.func.isRequired,
/**
* Is in the selected state
*/
isSelected: PropTypes.bool,
isDisabled: PropTypes.bool,
/**
* Override the default color with one of the available colors from `EuiButtonEmpty`
*/
color: PropTypes.oneOf(BUTTON_EMPTY_COLORS),
/**
* Override the content (text) of the button
*/
children: PropTypes.node,
};

EuiCardSelect.propTypes = EuiCardSelectProps;

function euiCardSelectableText(isSelected, isDisabled, children) {
function euiCardSelectableText(
isSelected: boolean | undefined,
isDisabled: boolean | undefined,
children: ReactNode
): ReactNode {
if (children) {
return children;
}
Expand All @@ -81,7 +75,10 @@ function euiCardSelectableText(isSelected, isDisabled, children) {
return text;
}

export function euiCardSelectableColor(color, isSelected) {
export function euiCardSelectableColor(
color: EuiButtonEmptyColor | undefined,
isSelected: boolean | undefined
): string {
let calculatedColor;
if (color) {
calculatedColor = color;
Expand Down
1 change: 0 additions & 1 deletion src/components/card/index.d.ts

This file was deleted.

File renamed without changes.
Loading

0 comments on commit e788120

Please sign in to comment.