Skip to content

Commit

Permalink
feat(common): convert to TypeScript and export types
Browse files Browse the repository at this point in the history
  • Loading branch information
WesSouza authored and arturbien committed Jul 25, 2022
1 parent 334cf5e commit b41b51e
Show file tree
Hide file tree
Showing 70 changed files with 265 additions and 132 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
/* eslint-disable react/require-default-props */
/* eslint-disable react/forbid-prop-types */
import React from 'react';
import { render } from '@testing-library/react';
import propTypes from 'prop-types';
import React from 'react';

import useForkRef from './useForkRef';

Expand All @@ -18,10 +15,10 @@ afterEach(() => {

describe('useForkRef', () => {
it('returns a single ref-setter function that forks the ref to its inputs', () => {
function Component(props) {
function Component(props: { innerRef: React.RefObject<HTMLDivElement> }) {
const { innerRef } = props;
const ownRef = React.useRef(null);
const [, forceUpdate] = React.useState(0);
const ownRef = React.useRef<HTMLDivElement>();
const [, forceUpdate] = React.useState(true);
React.useEffect(() => forceUpdate(n => !n), []);

const handleRef = useForkRef(innerRef, ownRef);
Expand All @@ -31,19 +28,18 @@ describe('useForkRef', () => {
);
}

Component.propTypes = {
innerRef: propTypes.any
};

const outerRef = React.createRef();
const outerRef = React.createRef<HTMLDivElement>();
render(<Component innerRef={outerRef} />);

expect(outerRef.current.textContent).toBe('has a ref');
expect(outerRef.current?.textContent).toBe('has a ref');
expect(console.error).not.toHaveBeenCalled();
});

it('forks if only one of the branches requires a ref', () => {
const Component = React.forwardRef(function Component(props, ref) {
const Component = React.forwardRef<HTMLDivElement>(function Component(
_,
ref
) {
const [hasRef, setHasRef] = React.useState(false);
const handleOwnRef = React.useCallback(() => setHasRef(true), []);
const handleRef = useForkRef(handleOwnRef, ref);
Expand All @@ -58,16 +54,26 @@ describe('useForkRef', () => {
});

it('does nothing if none of the forked branches requires a ref', () => {
const Outer = React.forwardRef(function Outer(props, ref) {
const setRef = jest.fn();

type OuterProps = {
children: React.ReactElement;
};

const Outer = React.forwardRef<null, OuterProps>(function Outer(
props,
ref
) {
const { children } = props;
const handleRef = useForkRef(children.ref, ref);

return React.cloneElement(children, { ref: handleRef });
});
// TODO: Fix this test as reading ref from children is not allowed so not available on React types
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const handleRef = useForkRef(children?.ref, ref);
setRef(handleRef);

// TODO: Figure out how to make react/no-unused-prop-types happy with the children
// eslint-disable-next-line react/no-unused-prop-types
Outer.propTypes = { children: propTypes.element.isRequired };
return children ? React.cloneElement(children, { ref: handleRef }) : null;
});

function Inner() {
return <div />;
Expand All @@ -79,55 +85,56 @@ describe('useForkRef', () => {
</Outer>
);
expect(console.error).not.toHaveBeenCalled();
expect(setRef).toHaveBeenCalledWith(null);
});

describe('changing refs', () => {
function Div(props) {
const { leftRef, rightRef, ...other } = props;
function Div(
props: {
leftRef?: React.Ref<HTMLDivElement>;
rightRef?: React.Ref<HTMLDivElement>;
} & React.HTMLAttributes<HTMLDivElement>
) {
const { leftRef = null, rightRef = null, ...other } = props;
const handleRef = useForkRef(leftRef, rightRef);

return <div {...other} ref={handleRef} />;
}

Div.propTypes = {
leftRef: propTypes.oneOfType([propTypes.func, propTypes.object]),
rightRef: propTypes.oneOfType([propTypes.func, propTypes.object])
};

it('handles changing from no ref to some ref', () => {
const { rerender } = render(<Div id='test' />);

expect(console.error).not.toHaveBeenCalled();

const ref = React.createRef();
const ref = React.createRef<HTMLDivElement>();
rerender(<Div id='test' leftRef={ref} />);

expect(ref.current.id).toBe('test');
expect(ref.current?.id).toBe('test');
expect(console.error).not.toHaveBeenCalled();
});

it('cleans up detached refs', () => {
const firstLeftRef = React.createRef();
const firstRightRef = React.createRef();
const secondRightRef = React.createRef();
const firstLeftRef = React.createRef<HTMLDivElement>();
const firstRightRef = React.createRef<HTMLDivElement>();
const secondRightRef = React.createRef<HTMLDivElement>();

const { rerender } = render(
<Div leftRef={firstLeftRef} rightRef={firstRightRef} id='test' />
);

expect(console.error).not.toHaveBeenCalled();

expect(firstLeftRef.current.id).toBe('test');
expect(firstRightRef.current.id).toBe('test');
expect(firstLeftRef.current?.id).toBe('test');
expect(firstRightRef.current?.id).toBe('test');
expect(secondRightRef.current).toBe(null);

rerender(
<Div leftRef={firstLeftRef} rightRef={secondRightRef} id='test' />
);

expect(firstLeftRef.current.id).toBe('test');
expect(firstLeftRef.current?.id).toBe('test');
expect(firstRightRef.current).toBe(null);
expect(secondRightRef.current.id).toBe('test');
expect(secondRightRef.current?.id).toBe('test');
});
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Straight out copied from https://github.com/mui-org/material-ui 😂
import * as React from 'react';

function setRef(ref, value) {
function setRef<T>(
ref: React.RefCallback<T> | React.MutableRefObject<T> | null,
value: T
) {
if (typeof ref === 'function') {
ref(value);
} else if (ref) {
Expand All @@ -10,7 +13,10 @@ function setRef(ref, value) {
}
}

export default function useForkRef(refA, refB) {
export default function useForkRef<T>(
refA: React.RefCallback<T> | React.MutableRefObject<T> | null,
refB: React.RefCallback<T> | React.MutableRefObject<T> | null
): React.RefCallback<T> | null {
/**
* This will create a new function if the ref props change and are defined.
* This means react will call the old forkRef with `null` and the new forkRef
Expand Down
File renamed without changes.
24 changes: 16 additions & 8 deletions src/common/index.js → src/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { css } from 'styled-components';
import { css, ThemedStyledProps } from 'styled-components';
import { Color, CommonThemeProps, Theme } from '../types';

type CSSProps = ThemedStyledProps<CommonThemeProps, Theme>;

export const shadow = '4px 4px 10px 0 rgba(0, 0, 0, 0.35)';
export const insetShadow = 'inset 2px 2px 3px rgba(0,0,0,0.2)';
Expand All @@ -9,12 +12,14 @@ export const createDisabledTextStyles = () => css`
text-shadow: 1px 1px ${({ theme }) => theme.materialTextDisabledShadow};
/* filter: grayscale(100%); */
`;

export const createBoxStyles = () => css`
box-sizing: border-box;
display: inline-block;
background: ${({ theme }) => theme.material};
color: ${({ theme }) => theme.materialText};
`;

// TODO for flat box styles add checkered background when disabled (not solid color)
export const createHatchedBackground = ({
mainColor = 'black',
Expand All @@ -41,17 +46,19 @@ export const createHatchedBackground = ({
background-size: ${`${pixelSize * 2}px ${pixelSize * 2}px`};
background-position: 0 0, ${`${pixelSize}px ${pixelSize}px`};
`;

export const createFlatBoxStyles = () => css`
position: relative;
box-sizing: border-box;
display: inline-block;
color: ${({ theme }) => theme.materialText};
background: ${({ theme, isDisabled }) =>
background: ${({ theme, isDisabled }: CSSProps) =>
isDisabled ? theme.flatLight : theme.canvas};
border: 2px solid ${({ theme }) => theme.canvas};
outline: 2px solid ${({ theme }) => theme.flatDark};
outline-offset: -4px;
`;

export const createBorderStyles = ({
invert = false,
windowBorders = false
Expand All @@ -64,8 +71,8 @@ export const createBorderStyles = ({
border-top-color: ${({ theme }) => theme.borderDarkest};
border-right-color: ${({ theme }) => theme.borderLightest};
border-bottom-color: ${({ theme }) => theme.borderLightest};
box-shadow: ${props => props.shadow && `${shadow}, `} inset 1px 1px 0px
1px ${({ theme }) => theme.borderDark},
box-shadow: ${(props: CSSProps) => props.shadow && `${shadow}, `} inset
1px 1px 0px 1px ${({ theme }) => theme.borderDark},
inset -1px -1px 0 1px ${({ theme }) => theme.borderLight};
`
: css`
Expand All @@ -77,12 +84,13 @@ export const createBorderStyles = ({
windowBorders ? theme.borderLight : theme.borderLightest};
border-right-color: ${({ theme }) => theme.borderDarkest};
border-bottom-color: ${({ theme }) => theme.borderDarkest};
box-shadow: ${props => props.shadow && `${shadow}, `} inset 1px 1px 0px
1px
box-shadow: ${(props: CSSProps) => props.shadow && `${shadow}, `} inset
1px 1px 0px 1px
${({ theme }) =>
windowBorders ? theme.borderLightest : theme.borderLight},
inset -1px -1px 0 1px ${({ theme }) => theme.borderDark};
`;

export const createWellBorderStyles = (invert = false) =>
invert
? css`
Expand All @@ -106,10 +114,10 @@ export const focusOutline = () => css`
outline: 2px dotted ${({ theme }) => theme.materialText};
`;

const nodeBtoa = b => Buffer.from(b).toString('base64');
const nodeBtoa = (string: string) => Buffer.from(string).toString('base64');
const base64encode = typeof btoa !== 'undefined' ? btoa : nodeBtoa;

const createTriangleSVG = (color, angle = 0) => {
const createTriangleSVG = (color: Color, angle = 0) => {
const svg = `<svg height="26" width="26" viewBox="0 0 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="rotate(${angle} 13 13)">
<polygon fill="${color}" points="6,10 20,10 13,17"/>
Expand Down
File renamed without changes.
8 changes: 0 additions & 8 deletions src/common/system.js

This file was deleted.

9 changes: 9 additions & 0 deletions src/common/system.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// TODO - implement styled-system

import { Sizes } from '../types';

export const blockSizes: Record<Sizes, string> = {
sm: '28px',
md: '36px',
lg: '44px'
};
4 changes: 3 additions & 1 deletion src/common/themes/aiee.js → src/common/themes/aiee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* https://www.deviantart.com/tpenguinltg/art/Aiee-668092636
*/

import { Theme } from '../../types';

export default {
name: 'aiee',
anchor: 'rgb(0,0,128)',
Expand Down Expand Up @@ -36,4 +38,4 @@ export default {
materialTextInvert: 'rgb(0,62,109)',
progress: 'rgb(251,211,61)',
tooltip: 'rgb(255,243,185)'
};
} as Theme;
4 changes: 3 additions & 1 deletion src/common/themes/ash.js → src/common/themes/ash.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* "Ash" by tPenguinLTG
* https://www.deviantart.com/tpenguinltg/art/Ash-575566643
*/
import { Theme } from '../../types';

export default {
name: 'ash',
anchor: 'rgb(192, 192, 192)',
Expand Down Expand Up @@ -34,4 +36,4 @@ export default {
materialTextInvert: 'rgb(255, 255, 255)',
progress: 'rgb(0, 0, 0)',
tooltip: 'rgb(0, 0, 0)'
};
} as Theme;
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Theme } from '../../types';

export default {
name: 'azureOrange',

Expand Down Expand Up @@ -31,4 +33,4 @@ export default {
materialTextInvert: '#000000',
progress: '#F46036',
tooltip: '#fefbcc'
};
} as Theme;
4 changes: 3 additions & 1 deletion src/common/themes/bee.js → src/common/themes/bee.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Theme } from '../../types';

export default {
name: 'bee',

Expand Down Expand Up @@ -31,4 +33,4 @@ export default {
materialTextInvert: '#ffffff',
progress: '#0C1618',
tooltip: '#fefbcc'
};
} as Theme;
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Theme } from '../../types';

export default {
name: 'blackAndWhite',

Expand Down Expand Up @@ -31,4 +33,4 @@ export default {
materialTextInvert: '#ffffff',
progress: '#000000',
tooltip: '#fefbcc'
};
} as Theme;
4 changes: 3 additions & 1 deletion src/common/themes/blue.js → src/common/themes/blue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* https://www.deviantart.com/tpenguinltg/art/Blue-525167751
*/

import { Theme } from '../../types';

export default {
name: 'blue',
anchor: 'rgb(0, 0, 128)',
Expand Down Expand Up @@ -36,4 +38,4 @@ export default {
materialTextInvert: 'rgb(255, 255, 255)',
progress: 'rgb(51, 153, 255)',
tooltip: 'rgb(225, 225, 255)'
};
} as Theme;
4 changes: 3 additions & 1 deletion src/common/themes/brick.js → src/common/themes/brick.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Theme } from '../../types';

export default {
name: 'brick',

Expand Down Expand Up @@ -31,4 +33,4 @@ export default {
materialTextInvert: '#ffffff',
progress: '#8e0101',
tooltip: '#fefbcc'
};
} as Theme;
4 changes: 3 additions & 1 deletion src/common/themes/candy.js → src/common/themes/candy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Theme } from '../../types';

export default {
name: 'candy',

Expand Down Expand Up @@ -31,4 +33,4 @@ export default {
materialTextInvert: '#EFF1F3',
progress: '#256EFF',
tooltip: '#fefbcc'
};
} as Theme;
Loading

0 comments on commit b41b51e

Please sign in to comment.