diff --git a/.gitignore b/.gitignore index 578619a88d..27cf482fa7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ yarn.lock public # local docz testing docz-fresh +.idea diff --git a/libraries/core-react/src/Chip/Chip.test.jsx b/libraries/core-react/src/Chip/Chip.test.tsx similarity index 90% rename from libraries/core-react/src/Chip/Chip.test.jsx rename to libraries/core-react/src/Chip/Chip.test.tsx index b9f1b9b4af..2ad2c9e25a 100644 --- a/libraries/core-react/src/Chip/Chip.test.jsx +++ b/libraries/core-react/src/Chip/Chip.test.tsx @@ -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' @@ -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) @@ -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) => { + callbackId = (x.target as HTMLElement).parentElement.id }) const { queryAllByTitle } = render( @@ -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) => { + callbackId = (x.target as HTMLElement).id }) const { container } = render( @@ -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) => { + callbackId = (x.target as HTMLElement).id }) const { container } = render( diff --git a/libraries/core-react/src/Chip/Chip.tokens.js b/libraries/core-react/src/Chip/Chip.tokens.ts similarity index 98% rename from libraries/core-react/src/Chip/Chip.tokens.js rename to libraries/core-react/src/Chip/Chip.tokens.ts index afc3c3293d..bd8181c06e 100644 --- a/libraries/core-react/src/Chip/Chip.tokens.js +++ b/libraries/core-react/src/Chip/Chip.tokens.ts @@ -1,4 +1,3 @@ -/* eslint-disable camelcase */ import { tokens } from '@equinor/eds-tokens' const { diff --git a/libraries/core-react/src/Chip/Chip.jsx b/libraries/core-react/src/Chip/Chip.tsx similarity index 71% rename from libraries/core-react/src/Chip/Chip.jsx rename to libraries/core-react/src/Chip/Chip.tsx index 732ac46409..04fef432f6 100644 --- a/libraries/core-react/src/Chip/Chip.jsx +++ b/libraries/core-react/src/Chip/Chip.tsx @@ -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 { @@ -11,8 +8,6 @@ import { typographyTemplate, } from '../_common/templates' -Icon.add({ close }) - const { enabled, disabled: disabledToken, @@ -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( + ({ clickable, deletable }) => ({ + tabIndex: clickable || deletable ? 0 : null, + role: clickable ? 'button' : null, + }), +)` background: ${enabled.background}; height: ${enabled.height}; width: fit-content; @@ -61,7 +65,6 @@ const StyledChips = styled.div.attrs(({ clickable, deletable }) => ({ ${spacingsTemplate(enabled.spacings)} ${typographyTemplate(enabled.typography)} - ${({ clickable }) => clickable && css` @@ -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 + +export const Chip = forwardRef(function EdsChips( + { + children, + onDelete, + disabled = false, + onClick, + variant = 'default', + ...other + }, ref, ) { const handleDelete = disabled ? undefined : onDelete @@ -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, @@ -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 ( clickable && handleClick(event)} onKeyPress={handleKeyPress} > @@ -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} /> )} @@ -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', -} diff --git a/libraries/core-react/src/Chip/Icon.jsx b/libraries/core-react/src/Chip/Icon.tsx similarity index 87% rename from libraries/core-react/src/Chip/Icon.jsx rename to libraries/core-react/src/Chip/Icon.tsx index 0098dde4c6..1961b2420d 100644 --- a/libraries/core-react/src/Chip/Icon.jsx +++ b/libraries/core-react/src/Chip/Icon.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import styled, { css } from 'styled-components' import { close } from '@equinor/eds-icons' import { Icon as Icon_ } from '..' @@ -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_)` cursor: pointer; padding: 1px; border-radius: ${enabled.icon.border.radius}; diff --git a/libraries/core-react/src/Chip/index.js b/libraries/core-react/src/Chip/index.ts similarity index 100% rename from libraries/core-react/src/Chip/index.js rename to libraries/core-react/src/Chip/index.ts diff --git a/libraries/core-react/src/Icon/Icon.tsx b/libraries/core-react/src/Icon/Icon.tsx index cb1a9fd0e9..a6220145c2 100644 --- a/libraries/core-react/src/Icon/Icon.tsx +++ b/libraries/core-react/src/Icon/Icon.tsx @@ -19,7 +19,7 @@ type SvgProps = { rotation?: number title?: string role?: string - 'aria-hidden'?: boolean + 'aria-hidden'?: boolean | 'true' | 'false' 'aria-labelledby'?: string } @@ -63,7 +63,7 @@ type Props = { name?: Name /** Manually specify which icon data to use */ data?: IconData -} +} & React.HTMLAttributes export const Icon = forwardRef(function EdsIcon( { @@ -113,7 +113,7 @@ export const Icon = forwardRef(function EdsIcon( ...svgProps, title, role: 'img', - 'aria-hidden': null, + 'aria-hidden': undefined, 'aria-labelledby': titleId, } }