Skip to content

Commit

Permalink
feat(icons): migrate icons to ts and update icon set
Browse files Browse the repository at this point in the history
* refactor(icons): migrate icons to typescript
* build(icons): configure svggr to create ts icon components
* fix(Theme): type theme with DefaultTheme to be compatible with overrides
* style: restore header rule override and remove duplicated headers
* feat(icons): update icons set

refs: CDS-73 (#135) CDS-95 (#139)
  • Loading branch information
beawar authored Nov 10, 2022
1 parent 83a4a8b commit b7660e9
Show file tree
Hide file tree
Showing 1,532 changed files with 11,634 additions and 16,793 deletions.
5 changes: 3 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ module.exports = {
},
overrides: [
{
files: ['src/icons/**/*.jsx'],
files: ['src/icons/**/*.[jt]sx'],
rules: {
'notice/notice': 0
}
Expand All @@ -71,5 +71,6 @@ module.exports = {
'testing-library/prefer-user-event': 'warn'
}
}
]
],
ignorePatterns: ['**/tsTemplate.js']
};
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
/coverage
/types
/.idea
tsTemplate.js
3 changes: 0 additions & 3 deletions .svgrrc

This file was deleted.

8 changes: 4 additions & 4 deletions docs/components/ThemePrinter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { useContext } from 'react';
import styled from 'styled-components';
import { ThemeObj } from '../../src/theme/theme';
import { ThemeContext } from '../../src/theme/theme-context-provider';

import styled, { ThemeContext } from 'styled-components';

const Pre = styled.pre`
color: ${({ theme }): string => theme.palette.text.regular};
`;

export default function ThemePrinter(): JSX.Element {
const { windowObj, ...theme } = useContext<ThemeObj>(ThemeContext);
// eslint-disable-next-line unused-imports/no-unused-vars
const { windowObj, ...theme } = useContext(ThemeContext);

return <Pre>{JSON.stringify(theme, null, 2)}</Pre>;
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
"start": "npm run styleguide",
"release": "standard-version",
"lint": "eslint --ext .js,.jsx,.ts,.tsx --resolve-plugins-relative-to node_modules/@zextras/carbonio-ui-configs src",
"lint:icons": "eslint --ext .ts,.tsx --resolve-plugins-relative-to node_modules/@zextras/carbonio-ui-configs src/icons --fix",
"styleguide": "styleguidist server",
"styleguide:build": "styleguidist build",
"test": "(is-ci && jest --runInBand) || jest --maxWorkers=50%",
"icons:build": "npx @svgr/cli -d src/icons svg && npx create-index -ri ./src/icons --extensions js jsx --outputFile index.jsx",
"icons:build": "tsc ./src/icons/tsTemplate.ts && npx @svgr/cli svg && npm run lint:icons",
"build": "npx rollup -c rollup.config.js && npm run build:types",
"build:types": "tsc -p tsconfig.types.json && npx @microsoft/api-extractor run --local --verbose",
"clean": "rm -rf dist/* types/*",
Expand Down
13 changes: 6 additions & 7 deletions src/components/basic/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@

import React, { HTMLAttributes, useMemo } from 'react';

import styled from 'styled-components';
import styled, { DefaultTheme } from 'styled-components';

import type { ThemeObj } from '../../theme/theme';
import { getColor } from '../../theme/theme-utils';
import { Icon } from './Icon';

type ShapeType = 'round' | 'square';

type AvatarContainerProps = {
size: keyof ThemeObj['sizes']['avatar'];
size: keyof DefaultTheme['sizes']['avatar'];
background?: string;
color: keyof ThemeObj['avatarColors'];
color: keyof DefaultTheme['avatarColors'];
picture?: string;
selecting?: boolean;
selected?: boolean;
Expand Down Expand Up @@ -51,7 +50,7 @@ const AvatarContainer = styled.div<AvatarContainerProps>`
`;

type CapitalsPropsType = {
$size: keyof ThemeObj['sizes']['avatar'];
$size: keyof DefaultTheme['sizes']['avatar'];
color?: string;
};

Expand Down Expand Up @@ -99,7 +98,7 @@ function calcCapitals(label: string): string | null {
return label[0] + label[label.length - 1];
}

function calcColor(label: string): keyof ThemeObj['avatarColors'] {
function calcColor(label: string): keyof DefaultTheme['avatarColors'] {
let sum = 0;
// eslint-disable-next-line no-plusplus
for (let i = 0; i < label.length; i++) {
Expand Down Expand Up @@ -176,7 +175,7 @@ const Avatar = React.forwardRef<HTMLDivElement, AvatarPropTypes>(function Avatar

interface AvatarPropTypes extends HTMLAttributes<HTMLDivElement> {
/** size of the Avatar circle */
size?: keyof ThemeObj['sizes']['avatar'];
size?: keyof DefaultTheme['sizes']['avatar'];

/** url to the profile picture */
picture?: string;
Expand Down
11 changes: 5 additions & 6 deletions src/components/basic/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@

import React, { ButtonHTMLAttributes, useCallback, useMemo } from 'react';

import styled, { css, SimpleInterpolation } from 'styled-components';
import styled, { css, DefaultTheme, SimpleInterpolation } from 'styled-components';

import { useCombinedRefs } from '../../hooks/useCombinedRefs';
import { getKeyboardPreset, useKeyboard } from '../../hooks/useKeyboard';
import type { ThemeObj } from '../../theme/theme';
import { getColor, pseudoClasses } from '../../theme/theme-utils';
import { Icon, IconProps } from './Icon';
import { Spinner } from './Spinner';
Expand All @@ -26,19 +25,19 @@ type ButtonColorsByType =
} & (
| {
/** Main color */
color?: string | keyof ThemeObj['palette'];
color?: string | keyof DefaultTheme['palette'];
}
| {
/** Background color of the button (only for 'default' and 'outlined' types, to use instead of color for more specificity) */
backgroundColor?: string | keyof ThemeObj['palette'];
backgroundColor?: string | keyof DefaultTheme['palette'];
/** Specific color of the content (only for 'default' and 'outlined' types, to use instead of color for more specificity) */
labelColor?: string | keyof ThemeObj['palette'];
labelColor?: string | keyof DefaultTheme['palette'];
}
))
| {
type: 'ghost';
/** Main color */
color?: string | keyof ThemeObj['palette'];
color?: string | keyof DefaultTheme['palette'];
};
type ButtonType = NonNullable<ButtonColorsByType['type']>;

Expand Down
10 changes: 5 additions & 5 deletions src/components/basic/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

import React, { SVGAttributes, useContext, useMemo } from 'react';

import styled, { css, SimpleInterpolation, ThemeContext } from 'styled-components';
import styled, { css, DefaultTheme, SimpleInterpolation, ThemeContext } from 'styled-components';

import { IconComponent, ThemeObj } from '../../theme/theme';
import { IconComponent } from '../../theme/theme';
import { getColor } from '../../theme/theme-utils';

interface IconComponentProps extends SVGAttributes<SVGSVGElement> {
/** Icon to show. It can be a string key for the theme icons or a custom icon component */
icon: keyof ThemeObj['icons'] | IconComponent;
icon: keyof DefaultTheme['icons'] | IconComponent;
/** whether the icon is in a disabled element */
disabled?: boolean;
/** action to perform on Icon Click
Expand All @@ -24,13 +24,13 @@ interface IconComponentProps extends SVGAttributes<SVGSVGElement> {

interface IconProps extends IconComponentProps {
/** Icon Color */
color?: string | keyof ThemeObj['palette'];
color?: string | keyof DefaultTheme['palette'];
/** Custom color, css syntax
* @deprecated use color instead
*/
customColor?: string;
/** Icon size */
size?: keyof ThemeObj['sizes']['icon'];
size?: keyof DefaultTheme['sizes']['icon'];
}

const IconBase = React.forwardRef<SVGSVGElement, IconComponentProps>(function IconFn(
Expand Down
5 changes: 2 additions & 3 deletions src/components/basic/Spinner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
*/
import React, { HTMLAttributes } from 'react';

import styled, { keyframes } from 'styled-components';
import styled, { DefaultTheme, keyframes } from 'styled-components';

import type { ThemeObj } from '../../theme/theme';
import { getColor } from '../../theme/theme-utils';

interface SpinnerProps extends HTMLAttributes<HTMLDivElement> {
color: string | keyof ThemeObj['palette'];
color: string | keyof DefaultTheme['palette'];
}

const rotateKeyframes = keyframes`
Expand Down
13 changes: 6 additions & 7 deletions src/components/basic/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@

import React, { HTMLAttributes } from 'react';

import styled, { css, SimpleInterpolation } from 'styled-components';
import styled, { css, DefaultTheme, SimpleInterpolation } from 'styled-components';

import type { ThemeObj } from '../../theme/theme';
import { getColor } from '../../theme/theme-utils';

type TextOverflow = 'ellipsis' | 'break-word';

interface TextProps extends HTMLAttributes<HTMLDivElement> {
/** Text color */
color?: string | keyof ThemeObj['palette'];
color?: string | keyof DefaultTheme['palette'];
/** Text size */
size?: keyof ThemeObj['sizes']['font'];
size?: keyof DefaultTheme['sizes']['font'];
/** Text weight */
weight?: keyof ThemeObj['fonts']['weight'];
weight?: keyof DefaultTheme['fonts']['weight'];
/** Overflow handling */
overflow?: TextOverflow;
/** Disabled status */
Expand All @@ -30,8 +29,8 @@ interface TextProps extends HTMLAttributes<HTMLDivElement> {

const Comp = styled.div<{
disabled: boolean;
size: keyof ThemeObj['sizes']['font'];
weight: keyof ThemeObj['fonts']['weight'];
size: keyof DefaultTheme['sizes']['font'];
weight: keyof DefaultTheme['fonts']['weight'];
overflow: string;
}>`
color: ${({ theme, color, disabled }): string =>
Expand Down
25 changes: 12 additions & 13 deletions src/components/display/Chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
import React, { useCallback, useMemo, useRef, useState } from 'react';

import { map } from 'lodash';
import styled, { css, SimpleInterpolation } from 'styled-components';
import styled, { css, DefaultTheme, SimpleInterpolation } from 'styled-components';

import { useCombinedRefs } from '../../hooks/useCombinedRefs';
import type { ThemeObj } from '../../theme/theme';
import { useTheme, pseudoClasses } from '../../theme/theme-utils';
import { Avatar } from '../basic/Avatar';
import { Icon } from '../basic/Icon';
Expand All @@ -22,11 +21,11 @@ import { Tooltip } from './Tooltip';

type ChipAction = {
/** Chip action icon color */
color?: keyof ThemeObj['palette'];
color?: keyof DefaultTheme['palette'];
/** Chip action disabled status */
disabled?: boolean;
/** Chip action icon */
icon: keyof ThemeObj['icons'];
icon: keyof DefaultTheme['icons'];
/** Chip action id (required for key attribute) */
id: string;
/** Chip action label value. It is shown in a tooltip. To not render the tooltip, just don't value the prop.
Expand All @@ -39,7 +38,7 @@ type ChipAction = {
/** Chip action click callback (button type only). NB: onClick event IS propagated. It's up to the dev to eventually stop the propagation */
onClick: IconButtonProps['onClick'];
/** Chip action background (button type only) */
background?: keyof ThemeObj['palette'];
background?: keyof DefaultTheme['palette'];
}
| {
/** Chip action type */
Expand All @@ -51,24 +50,24 @@ interface ChipProps extends RowProps {
/** Chip actions (buttons or icons) */
actions?: ChipAction[];
/** Chip Avatar Icon */
avatarIcon?: keyof ThemeObj['icons'];
avatarIcon?: keyof DefaultTheme['icons'];
/** Chip Avatar Background Color */
avatarBackground?: keyof ThemeObj['palette'];
avatarBackground?: keyof DefaultTheme['palette'];
/** Chip avatar color (icon color or capitals color) */
avatarColor?: keyof ThemeObj['palette'];
avatarColor?: keyof DefaultTheme['palette'];
/** Chip avatar label. It allows to override the capitals for the avatar.
* If the main label is not a string, you have to fill this prop to show capitals in the avatar */
avatarLabel?: string;
/** Chip avatar picture */
avatarPicture?: string;
/** Chip background color */
background?: keyof ThemeObj['palette'];
background?: keyof DefaultTheme['palette'];
/** Chip shape */
shape?: 'regular' | 'round';
/** If an onClose callback is provided, this prop defines if the close action should be active or disabled */
closable?: boolean;
/** Chip text color */
color?: keyof ThemeObj['palette'];
color?: keyof DefaultTheme['palette'];
/** Chip disabled status. If a string is provided it is shown in a tooltip */
disabled?: boolean | string;
/** Chip error. If a string is provided it is shown in a tooltip */
Expand Down Expand Up @@ -117,7 +116,7 @@ const ContentContainer = styled(Container)<{ gap: ContainerProps['gap'] }>`
`;

const ChipContainer = styled(Container)<{
background: keyof ThemeObj['palette'];
background: keyof DefaultTheme['palette'];
disabled: boolean;
onClick?: React.ReactEventHandler;
onDoubleClick?: React.ReactEventHandler;
Expand Down Expand Up @@ -147,8 +146,8 @@ const ChipContainer = styled(Container)<{
const SIZES: Record<
NonNullable<ChipProps['size']>,
{
avatar: keyof ThemeObj['sizes']['avatar'];
font: keyof ThemeObj['sizes']['font'];
avatar: keyof DefaultTheme['sizes']['avatar'];
font: keyof DefaultTheme['sizes']['font'];
icon: React.ComponentPropsWithoutRef<typeof Icon>['size'];
spacing: string;
}
Expand Down
14 changes: 6 additions & 8 deletions src/components/display/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ import {
VirtualElement
} from '@popperjs/core';
import { find, some } from 'lodash';
import styled, { css, SimpleInterpolation } from 'styled-components';
import styled, { css, DefaultTheme, SimpleInterpolation, ThemeContext } from 'styled-components';

import { useCombinedRefs } from '../../hooks/useCombinedRefs';
import { useKeyboard, getKeyboardPreset, KeyboardPreset } from '../../hooks/useKeyboard';
import type { ThemeObj } from '../../theme/theme';
import { ThemeContext } from '../../theme/theme-context-provider';
import { pseudoClasses } from '../../theme/theme-utils';
import { Icon } from '../basic/Icon';
import { Text } from '../basic/Text';
Expand All @@ -41,7 +39,7 @@ import { Portal } from '../utilities/Portal';
import { Tooltip } from './Tooltip';

const ContainerEl = styled(Container)<{
$selectedBackgroundColor?: keyof ThemeObj['palette'];
$selectedBackgroundColor?: keyof DefaultTheme['palette'];
$disabled: boolean;
}>`
user-select: none;
Expand All @@ -57,7 +55,7 @@ interface ListItemContentProps {
disabled?: boolean;
itemIconSize: React.ComponentPropsWithRef<typeof Icon>['size'];
itemTextSize: React.ComponentProps<typeof Text>['size'];
itemPaddingBetween: keyof ThemeObj['sizes']['padding'];
itemPaddingBetween: keyof DefaultTheme['sizes']['padding'];
tooltipLabel?: string;
}

Expand Down Expand Up @@ -100,7 +98,7 @@ function ListItemContent({
interface PopperListItemProps extends ListItemContentProps, HTMLAttributes<HTMLDivElement> {
click?: (e: React.SyntheticEvent<HTMLElement> | KeyboardEvent) => void;
customComponent?: React.ReactNode;
selectedBackgroundColor?: keyof ThemeObj['palette'];
selectedBackgroundColor?: keyof DefaultTheme['palette'];
keepOpen?: boolean;
}

Expand Down Expand Up @@ -371,13 +369,13 @@ interface DropdownProps extends Omit<HTMLAttributes<HTMLDivElement>, 'contextMen
/** Whether to preventDefault on Dropdown click */
preventDefault?: boolean;
/** Customize selected background color */
selectedBackgroundColor?: keyof ThemeObj['palette'];
selectedBackgroundColor?: keyof DefaultTheme['palette'];
/** Item Icon size */
itemIconSize?: React.ComponentPropsWithRef<typeof Icon>['size'];
/** Item Text size */
itemTextSize?: React.ComponentPropsWithRef<typeof Text>['size'];
/** Item Padding Between */
itemPaddingBetween?: keyof ThemeObj['sizes']['padding'];
itemPaddingBetween?: keyof DefaultTheme['sizes']['padding'];
/** Ref assign to the dropdown list popper container */
dropdownListRef?: React.RefObject<HTMLDivElement>;
}
Expand Down
Loading

0 comments on commit b7660e9

Please sign in to comment.