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

Typescript conversion of Chips #690

Merged
merged 2 commits into from
Oct 19, 2020
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: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ yarn.lock
public
# local docz testing
docz-fresh
.idea
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-undef */
import React from 'react'
import { render, cleanup, fireEvent, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
Expand All @@ -17,7 +16,7 @@ const StyledChips = styled(Chip)`

const { active: activeToken, error } = tokens

const rgbaTrim = (x) => x.split(' ').join('')
const rgbaTrim = (x: string) => x.split(' ').join('')

afterEach(cleanup)

Expand Down Expand Up @@ -64,8 +63,8 @@ describe('Chips', () => {
const chipText = 'hello, I am a chip'
const chipId = 'avatar-chip-test'
let callbackId = ''
const handleDelete = jest.fn((x) => {
callbackId = x.target.parentElement.id
const handleDelete = jest.fn((x: React.MouseEvent<HTMLElement>) => {
callbackId = (x.target as HTMLElement).parentElement.id
})

const { queryAllByTitle } = render(
Expand All @@ -85,8 +84,8 @@ describe('Chips', () => {
const chipText = 'hello, I am a chip'
const chipId = 'avatar-chip-test'
let callbackId = ''
const handleClick = jest.fn((x) => {
callbackId = x.target.id
const handleClick = jest.fn((x: React.MouseEvent<HTMLElement>) => {
callbackId = (x.target as HTMLElement).id
})

const { container } = render(
Expand All @@ -104,8 +103,8 @@ describe('Chips', () => {
const chipText = 'hello, I am a chip'
const chipId = 'avatar-chip-test'
let callbackId = ''
const handleClick = jest.fn((x) => {
callbackId = x.target.id
const handleClick = jest.fn((x: React.MouseEvent<HTMLElement>) => {
callbackId = (x.target as HTMLElement).id
})

const { container } = render(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable camelcase */
import { tokens } from '@equinor/eds-tokens'

const {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
// @ts-nocheck
import React, { forwardRef } from 'react'
import PropTypes from 'prop-types'
import styled, { css } from 'styled-components'
import { close } from '@equinor/eds-icons'
import { Icon } from './Icon'
import { chip as tokens } from './Chip.tokens'
import {
Expand All @@ -11,8 +8,6 @@ import {
typographyTemplate,
} from '../_common/templates'

Icon.add({ close })

const {
enabled,
disabled: disabledToken,
Expand All @@ -23,10 +18,19 @@ const {
outlineOffset,
} = tokens

const StyledChips = styled.div.attrs(({ clickable, deletable }) => ({
tabIndex: clickable || deletable ? 0 : null,
role: clickable ? 'button' : null,
}))`
type StyleProps = {
variant: 'active' | 'error' | 'default'
clickable: boolean
deletable: boolean
disabled: boolean
}

const StyledChips = styled.div.attrs<StyleProps>(
({ clickable, deletable }) => ({
tabIndex: clickable || deletable ? 0 : null,
role: clickable ? 'button' : null,
}),
)<StyleProps>`
background: ${enabled.background};
height: ${enabled.height};
width: fit-content;
Expand Down Expand Up @@ -61,7 +65,6 @@ const StyledChips = styled.div.attrs(({ clickable, deletable }) => ({
${spacingsTemplate(enabled.spacings)}
${typographyTemplate(enabled.typography)}


${({ clickable }) =>
clickable &&
css`
Expand Down Expand Up @@ -124,16 +127,30 @@ const StyledChips = styled.div.attrs(({ clickable, deletable }) => ({
padding-right: 4px;
`}

${({ onlyChild }) =>
onlyChild &&
${({ children }) =>
typeof children === 'string' &&
css`
padding-left: 8px;
`}

`

export const Chip = forwardRef(function EdsChips(
{ children, onDelete, disabled, onClick, variant, ...rest },
type Props = {
/** Disabled */
disabled?: boolean
/** Delete callback */
onDelete?: (Event) => void
/** Variant */
variant?: 'active' | 'error' | 'default'
} & React.HTMLAttributes<HTMLDivElement>

export const Chip = forwardRef<HTMLDivElement, Props>(function EdsChips(
{
children,
onDelete,
disabled = false,
onClick,
variant = 'default',
...other
},
ref,
) {
const handleDelete = disabled ? undefined : onDelete
Expand All @@ -143,8 +160,8 @@ export const Chip = forwardRef(function EdsChips(
const clickable = handleClick !== undefined
const onlyChild = typeof children === 'string'

const props = {
...rest,
const chipProps = {
...other,
ref,
disabled,
deletable,
Expand All @@ -159,27 +176,37 @@ export const Chip = forwardRef(function EdsChips(
if (deletable) {
handleDelete(event)
}
// Delete takes presidens, else click action is activated
// Delete takes precedence, else click action is activated
if (clickable && !deletable) {
handleClick(event)
}
}
}

const resizedChildren = React.Children.map(children, (child) => {
// We force size on Icon & Avatar component
if (child.props && child.props.size) {
return React.cloneElement(child, {
size: 16,
disabled,
})
const resizedChildren = React.Children.map(
children,
(child: React.ReactElement) => {
// We force size on Icon & Avatar component
if (child.props && child.props.size) {
return React.cloneElement(child, {
size: 16,
disabled,
})
}
return child
},
)

const onDeleteClick = (event) => {
event.stopPropagation()
if (deletable) {
handleDelete(event)
}
return child
})
}

return (
<StyledChips
{...props}
{...chipProps}
onClick={(event) => clickable && handleClick(event)}
onKeyPress={handleKeyPress}
>
Expand All @@ -190,12 +217,7 @@ export const Chip = forwardRef(function EdsChips(
title="close"
disabled={disabled}
variant={variant}
onClick={(event) => {
event.stopPropagation()
if (deletable) {
handleDelete(event)
}
}}
onClick={onDeleteClick}
size={16}
/>
)}
Expand All @@ -204,27 +226,3 @@ export const Chip = forwardRef(function EdsChips(
})

Chip.displayName = 'eds-chip'

Chip.propTypes = {
/** @ignore */
className: PropTypes.string,
/** @ignore */
children: PropTypes.node,
/** Disabled */
disabled: PropTypes.bool,
/** Delete callback */
onDelete: PropTypes.func,
/** Click callback */
onClick: PropTypes.func,
/** Variant */
variant: PropTypes.oneOf(['active', 'error', 'default']),
}

Chip.defaultProps = {
className: '',
children: [],
disabled: false,
onDelete: undefined,
onClick: undefined,
variant: 'default',
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-nocheck
import styled, { css } from 'styled-components'
import { close } from '@equinor/eds-icons'
import { Icon as Icon_ } from '..'
Expand All @@ -8,7 +7,12 @@ Icon_.add({ close })

const { enabled, hover, error } = tokens

export const Icon = styled(Icon_)`
type IconProps = {
variant: 'active' | 'error' | 'default'
disabled: boolean
}

export const Icon = styled(Icon_)<IconProps>`
cursor: pointer;
padding: 1px;
border-radius: ${enabled.icon.border.radius};
Expand Down
6 changes: 3 additions & 3 deletions libraries/core-react/src/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type SvgProps = {
rotation?: number
title?: string
role?: string
'aria-hidden'?: boolean
'aria-hidden'?: boolean | 'true' | 'false'
'aria-labelledby'?: string
}

Expand Down Expand Up @@ -63,7 +63,7 @@ type Props = {
name?: Name
/** Manually specify which icon data to use */
data?: IconData
}
} & React.HTMLAttributes<SVGSVGElement>

export const Icon = forwardRef<SVGSVGElement, Props>(function EdsIcon(
{
Expand Down Expand Up @@ -113,7 +113,7 @@ export const Icon = forwardRef<SVGSVGElement, Props>(function EdsIcon(
...svgProps,
title,
role: 'img',
'aria-hidden': null,
'aria-hidden': undefined,
'aria-labelledby': titleId,
}
}
Expand Down