diff --git a/src/components/SkillEdge.tsx b/src/components/SkillEdge.tsx
index 493b2ef..38a88dc 100644
--- a/src/components/SkillEdge.tsx
+++ b/src/components/SkillEdge.tsx
@@ -1,14 +1,14 @@
import React from 'react';
-import { NodeState } from '../models';
+import { NodeState, Direction } from '../models';
import Line from './ui/Line';
import UpperAngledLine from './ui/UpperAngledLine';
import MiddleAngledLine from './ui/MiddleAngledLine';
import LowerAngledLine from './ui/LowerAngledLine';
-interface Props {
+export interface Props {
parentHasMultipleChildren: boolean;
state: NodeState;
- direction: 'left' | 'right';
+ direction: Direction;
parentCenterPosition: number;
childCenterPosition: number;
}
@@ -25,7 +25,7 @@ function SkillEdge(props: Props) {
if (!parentHasMultipleChildren) return ;
return (
- <>
+
);
}
diff --git a/src/components/SkillNode.tsx b/src/components/SkillNode.tsx
index f66b5cf..81b33c2 100644
--- a/src/components/SkillNode.tsx
+++ b/src/components/SkillNode.tsx
@@ -40,7 +40,6 @@ function SkillNode({
const { direction = 'top', content } = tooltip;
const { isMobile } = React.useContext(MobileContext);
const [parentPosition, setParentPosition] = React.useState({
- bottom: 0,
center: 0,
});
@@ -48,17 +47,11 @@ function SkillNode({
const childWidth: React.MutableRefObject = React.useRef(0);
function calculatePosition() {
- const {
- bottom,
- left,
- right,
- } = skillNodeRef.current!.getBoundingClientRect();
+ const { left, right } = skillNodeRef.current!.getBoundingClientRect();
const scrollX = window.scrollX;
- const scrollY = window.scrollY;
setParentPosition({
- bottom: bottom + scrollY,
center: (right - left) / 2 + left + scrollX,
});
}
diff --git a/src/components/SkillTree.tsx b/src/components/SkillTree.tsx
index 64eba08..c3e3b59 100644
--- a/src/components/SkillTree.tsx
+++ b/src/components/SkillTree.tsx
@@ -21,7 +21,6 @@ interface Props {
}
const defaultParentPosition = {
- bottom: 0,
center: 0,
};
diff --git a/src/components/__tests__/SkillEdge.test.tsx b/src/components/__tests__/SkillEdge.test.tsx
index c4ca174..1a97640 100644
--- a/src/components/__tests__/SkillEdge.test.tsx
+++ b/src/components/__tests__/SkillEdge.test.tsx
@@ -1,23 +1,21 @@
import React from 'react';
import { render } from '@testing-library/react';
-import SkillEdge from '../SkillEdge';
-import { NodeState } from 'models';
+import SkillEdge, { Props } from '../SkillEdge';
import { ThemeProvider } from 'styled-components';
import defaultTheme from '../../theme';
-const defaultPosition = {
- topX: 0,
- topY: 0,
- bottomX: 0,
+const defaultProps: Props = {
+ parentHasMultipleChildren: false,
+ state: 'unlocked',
+ direction: 'right',
+ parentCenterPosition: 0,
+ childCenterPosition: 0,
};
-function renderComponent(startingState: NodeState, position = defaultPosition) {
- let state = startingState;
- const { topX, topY, bottomX } = position;
-
+function renderComponent(props = defaultProps) {
return render(
-
+
);
}
@@ -25,9 +23,7 @@ function renderComponent(startingState: NodeState, position = defaultPosition) {
describe('SkillEdge', () => {
describe('straight lines', () => {
it('should be inactive if the next node is unlocked', async () => {
- const startingState = 'unlocked';
-
- const { getByTestId } = renderComponent(startingState);
+ const { getByTestId } = renderComponent();
const skillEdge = getByTestId('straight-line');
@@ -39,9 +35,7 @@ describe('SkillEdge', () => {
});
it('should be inactive if the next node is locked', () => {
- const startingState = 'unlocked';
-
- const { getByTestId } = renderComponent(startingState);
+ const { getByTestId } = renderComponent();
const skillEdge = getByTestId('straight-line');
@@ -53,9 +47,9 @@ describe('SkillEdge', () => {
});
it('should be active if the next node is selected', () => {
- const startingState = 'selected';
+ const props: Props = { ...defaultProps, state: 'selected' };
- const { getByTestId } = renderComponent(startingState);
+ const { getByTestId } = renderComponent(props);
const skillEdge = getByTestId('straight-line');
@@ -66,28 +60,27 @@ describe('SkillEdge', () => {
describe('angled lines', () => {
const leftAngledLinePosition = {
- topX: 100,
- topY: 100,
- bottomX: 50,
+ parentCenterPosition: 100,
+ childCenterPosition: 100,
};
const rightAngledLinePosition = {
- topX: 100,
- topY: 100,
- bottomX: 150,
+ parentCenterPosition: 100,
+ childCenterPosition: 150,
};
it('should be inactive if the next node is unlocked', async () => {
- const startingState = 'unlocked';
+ const props = {
+ ...defaultProps,
+ ...leftAngledLinePosition,
+ parentHasMultipleChildren: true,
+ };
- const { getByTestId } = renderComponent(
- startingState,
- leftAngledLinePosition
- );
+ const { getByTestId } = renderComponent(props);
- const skillEdgeOne = getByTestId('angled-line-one');
- const skillEdgeTwo = getByTestId('angled-line-two');
- const skillEdgeThree = getByTestId('angled-line-three');
+ const skillEdgeOne = getByTestId('upper-angled-line');
+ const skillEdgeTwo = getByTestId('middle-angled-line');
+ const skillEdgeThree = getByTestId('lower-angled-line');
expect(skillEdgeOne).toHaveStyleRule('opacity', '1');
expect(skillEdgeOne).not.toHaveStyleRule(
@@ -109,16 +102,17 @@ describe('SkillEdge', () => {
});
it('should be inactive if the next node is locked', () => {
- const startingState = 'unlocked';
+ const props = {
+ ...defaultProps,
+ ...leftAngledLinePosition,
+ parentHasMultipleChildren: true,
+ };
- const { getByTestId } = renderComponent(
- startingState,
- leftAngledLinePosition
- );
+ const { getByTestId } = renderComponent(props);
- const skillEdgeOne = getByTestId('angled-line-one');
- const skillEdgeTwo = getByTestId('angled-line-two');
- const skillEdgeThree = getByTestId('angled-line-three');
+ const skillEdgeOne = getByTestId('upper-angled-line');
+ const skillEdgeTwo = getByTestId('middle-angled-line');
+ const skillEdgeThree = getByTestId('lower-angled-line');
expect(skillEdgeOne).not.toHaveStyleRule(
'background-position',
@@ -135,28 +129,23 @@ describe('SkillEdge', () => {
});
it('should be active if the next node is selected', () => {
- const startingState = 'selected';
+ const props = {
+ ...defaultProps,
+ ...rightAngledLinePosition,
+ parentHasMultipleChildren: true,
+ };
- const { getByTestId } = renderComponent(
- startingState,
- rightAngledLinePosition
- );
+ const { getByTestId } = renderComponent(props);
- const skillEdgeOne = getByTestId('angled-line-one');
- const skillEdgeTwo = getByTestId('angled-line-two');
- const skillEdgeThree = getByTestId('angled-line-three');
+ const skillEdgeOne = getByTestId('upper-angled-line');
+ const skillEdgeTwo = getByTestId('middle-angled-line');
+ const skillEdgeThree = getByTestId('lower-angled-line');
- expect(skillEdgeOne).toHaveStyleRule(
- 'background-position',
- 'left bottom'
- );
- expect(skillEdgeTwo).toHaveStyleRule(
- 'background-position',
- 'left bottom'
- );
+ expect(skillEdgeOne).toHaveStyleRule('background-position', 'right top');
+ expect(skillEdgeTwo).toHaveStyleRule('background-position', 'right top');
expect(skillEdgeThree).toHaveStyleRule(
'background-position',
- 'left bottom'
+ 'right top'
);
});
});
diff --git a/src/components/ui/AngledLine.tsx b/src/components/ui/AngledLine.tsx
index 8b315e5..049027e 100644
--- a/src/components/ui/AngledLine.tsx
+++ b/src/components/ui/AngledLine.tsx
@@ -1,78 +1,21 @@
-import React from 'react';
-import styled, { BaseThemedCssFunction } from 'styled-components';
-import { NodeState } from '../../models';
-import { SELECTED_STATE, LOCKED_STATE } from '../../components/constants';
+import styled from 'styled-components';
+import { Direction } from '../../models';
-const keyframes = require('styled-components').keyframes;
-const css: BaseThemedCssFunction = require('styled-components').css;
-
-type direction = 'left' | 'right';
-
-interface Props {
- topX: number;
- topY: number;
- bottomX: number;
- direction: 'left' | 'right';
- state: NodeState;
-}
-
-interface AngledLineProps {
+export interface AngledLineProps {
unlocked: boolean;
selected: boolean;
}
-interface AngledLineVerticalProps {
- top: number;
- left: number;
- direction: direction;
+export interface AngledLineVerticalProps {
+ direction: Direction;
}
-interface AngledLineHoriztonalProps {
- direction: direction;
- top: number;
- left: number;
+export interface AngledLineHoriztonalProps {
+ direction: Direction;
width: number;
}
-function AngledLine({ topX, topY, bottomX, direction, state }: Props) {
- return (
-
-
-
-
-
- );
-}
-
-export default AngledLine;
-
-const AngledLineContainer = styled.div`
- height: 56px;
-`;
-
-const StyledAngledLine = styled.div`
+export const StyledAngledLine = styled.div`
background: linear-gradient(
to right,
rgba(255, 255, 255, 1) 0%,
@@ -94,119 +37,3 @@ const StyledAngledLine = styled.div`
opacity: 1;
`}
`;
-
-const AngledLineVertical = styled(StyledAngledLine)`
- transform: rotate(90deg);
- transform-origin: 0 0;
-`;
-
-const slideDownAngledLineTop = keyframes`
- from,
- 33% {
- background-position: right top;
- }
-
- to {
- background-position: left bottom;
- }
-`;
-
-const AngledLineVerticalTop = styled(AngledLineVertical)<
- AngledLineVerticalProps
->`
- left: ${props => props.left}px;
- top: ${props => props.top}px;
- width: 29px;
-
- ${props =>
- props.direction === 'right' &&
- `
- border-bottom-right-radius: 8px;
- `}
-
- ${props =>
- props.direction === 'left' &&
- `
- border-top-right-radius: 8px;
- `}
-
- ${props =>
- props.selected &&
- css`
- animation: ${slideDownAngledLineTop} 0.3s 1 ease-in;
- background-position: left bottom;
- `}
-`;
-
-const slideDownAngledLineMiddle = keyframes`
- from,
- 30% {
- background-position: right top;
- }
-
- to {
- background-position: left bottom;
- }
-`;
-
-const AngledLineHoriztonal = styled(StyledAngledLine)<
- AngledLineHoriztonalProps
->`
- border-left: none;
- border-right: none;
- left: ${props => props.left}px;
- top: ${props => props.top}px;
- width: ${props => props.width}px;
-
- ${props =>
- props.direction === 'left' &&
- `
- transform: scaleX(-1);
- transform-origin: 0 0;
- `}
-
- ${props =>
- props.selected &&
- css`
- animation: ${slideDownAngledLineMiddle} 1s 1;
- background-position: left bottom;
- `}
-`;
-
-const slideDownAngledLineBottom = keyframes`
- from,
- 70% {
- background-position: right top;
- }
-
- to {
- background-position: left bottom;
- }
-`;
-
-const AngledLineVerticalBottom = styled(AngledLineVertical)<
- AngledLineVerticalProps
->`
- left: ${props => props.left}px;
- top: ${props => props.top}px;
- width: 31px;
-
- ${props =>
- props.direction === 'right' &&
- `
- border-top-left-radius: 8px;
- `}
-
- ${props =>
- props.direction === 'left' &&
- `
- border-bottom-left-radius: 8px;
- `}
-
- ${props =>
- props.selected &&
- css`
- animation: ${slideDownAngledLineBottom} 1.2s 1 ease-out;
- background-position: left bottom;
- `}
-`;
diff --git a/src/components/ui/LowerAngledLine.tsx b/src/components/ui/LowerAngledLine.tsx
index dba89f7..4e2df87 100644
--- a/src/components/ui/LowerAngledLine.tsx
+++ b/src/components/ui/LowerAngledLine.tsx
@@ -1,27 +1,17 @@
import React from 'react';
-import { NodeState } from '../../models';
+import { NodeState, Direction } from '../../models';
import { LOCKED_STATE, SELECTED_STATE } from '../../components/constants';
import styled, { BaseThemedCssFunction } from 'styled-components';
+import { StyledAngledLine, AngledLineVerticalProps } from './AngledLine';
const keyframes = require('styled-components').keyframes;
const css: BaseThemedCssFunction = require('styled-components').css;
-type Direction = 'left' | 'right';
-
interface Props {
direction: Direction;
state: NodeState;
}
-interface AngledLineProps {
- unlocked: boolean;
- selected: boolean;
-}
-
-interface AngledLineVerticalProps {
- direction: Direction;
-}
-
function LowerAngledLine(props: Props) {
const { state, direction } = props;
@@ -29,7 +19,7 @@ function LowerAngledLine(props: Props) {
);
@@ -37,39 +27,13 @@ function LowerAngledLine(props: Props) {
export default LowerAngledLine;
-const StyledAngledLine = styled.div`
- background: linear-gradient(
- to right,
- rgba(255, 255, 255, 1) 0%,
- rgba(255, 255, 255, 1) 50%,
- rgba(255, 255, 255, 0) 51%,
- rgba(255, 255, 255, 0) 100%
- );
- background-size: 210% 100%;
- background-position: right top;
- border: ${({ theme }) => theme.edgeBorder};
- height: 4px;
- position: absolute;
- opacity: 0.5;
- transition: opacity 0.6s;
-
- ${props =>
- props.unlocked &&
- `
- opacity: 1;
- `}
-`;
-
-const AngledLineVertical = styled(StyledAngledLine)`
- transform: rotate(90deg) translateY(-50%);
- transform-origin: 0 0;
-`;
-
-const AngledLineVerticalBottom = styled(AngledLineVertical)<
+const AngledLineVerticalBottom = styled(StyledAngledLine)<
AngledLineVerticalProps
>`
+ transform: rotate(90deg) translateY(-50%);
+ transform-origin: 0 0;
left: 50%;
- top: -32px;
+ top: 24px;
width: 31px;
${props =>
diff --git a/src/components/ui/MiddleAngledLine.tsx b/src/components/ui/MiddleAngledLine.tsx
index baec538..641847c 100644
--- a/src/components/ui/MiddleAngledLine.tsx
+++ b/src/components/ui/MiddleAngledLine.tsx
@@ -1,13 +1,12 @@
import React from 'react';
import styled, { BaseThemedCssFunction } from 'styled-components';
-import { NodeState } from '../../models';
+import { NodeState, Direction } from '../../models';
import { SELECTED_STATE, LOCKED_STATE } from '../../components/constants';
+import { StyledAngledLine, AngledLineHoriztonalProps } from './AngledLine';
const keyframes = require('styled-components').keyframes;
const css: BaseThemedCssFunction = require('styled-components').css;
-type Direction = 'left' | 'right';
-
interface Props {
parentCenterPosition: number;
childCenterPosition: number;
@@ -15,16 +14,6 @@ interface Props {
state: NodeState;
}
-interface AngledLineProps {
- unlocked: boolean;
- selected: boolean;
-}
-
-interface AngledLineHoriztonalProps {
- direction: Direction;
- width: number;
-}
-
function MiddleAngledLine(props: Props) {
const { direction, parentCenterPosition, childCenterPosition, state } = props;
@@ -35,7 +24,7 @@ function MiddleAngledLine(props: Props) {
return (
`
- background: linear-gradient(
- to right,
- rgba(255, 255, 255, 1) 0%,
- rgba(255, 255, 255, 1) 50%,
- rgba(255, 255, 255, 0) 51%,
- rgba(255, 255, 255, 0) 100%
- );
- background-size: 210% 100%;
- background-position: right top;
- border: ${({ theme }) => theme.edgeBorder};
- height: 4px;
- position: absolute;
- opacity: 0.5;
- transition: opacity 0.6s;
-
- ${props =>
- props.unlocked &&
- `
- opacity: 1;
- `}
-`;
-
const AngledLineHoriztonal = styled(StyledAngledLine)<
AngledLineHoriztonalProps
>`
border-left: none;
border-right: none;
- top: -32px;
+ top: 24px;
left: 50%;
width: ${props => props.width}px;
diff --git a/src/components/ui/UpperAngledLine.tsx b/src/components/ui/UpperAngledLine.tsx
index 39886a6..7c16546 100644
--- a/src/components/ui/UpperAngledLine.tsx
+++ b/src/components/ui/UpperAngledLine.tsx
@@ -1,75 +1,35 @@
import React from 'react';
import styled, { BaseThemedCssFunction } from 'styled-components';
-import { NodeState } from '../../models';
+import { NodeState, Direction } from '../../models';
import { SELECTED_STATE, LOCKED_STATE } from '../../components/constants';
+import { StyledAngledLine, AngledLineVerticalProps } from './AngledLine';
const keyframes = require('styled-components').keyframes;
const css: BaseThemedCssFunction = require('styled-components').css;
-type Direction = 'left' | 'right';
-
interface Props {
direction: Direction;
state: NodeState;
}
-interface AngledLineProps {
- unlocked: boolean;
- selected: boolean;
-}
-
-interface AngledLineVerticalProps {
- direction: Direction;
-}
-
function UpperAngledLine(props: Props) {
const { direction, state } = props;
return (
-
+
);
}
export default UpperAngledLine;
-const StyledAngledLine = styled.div`
- background: linear-gradient(
- to right,
- rgba(255, 255, 255, 1) 0%,
- rgba(255, 255, 255, 1) 50%,
- rgba(255, 255, 255, 0) 51%,
- rgba(255, 255, 255, 0) 100%
- );
- background-size: 210% 100%;
- background-position: right top;
- border: ${({ theme }) => theme.edgeBorder};
- height: 4px;
- position: absolute;
- opacity: 0.5;
- transition: opacity 0.6s;
-
- ${props =>
- props.unlocked &&
- `
- opacity: 1;
- `}
-`;
-
-const AngledLineVertical = styled(StyledAngledLine)`
+const AngledLineVerticalTop = styled(StyledAngledLine)`
transform: rotate(90deg) translateY(-50%);
transform-origin: 0 0;
-`;
-
-const AngledLineVerticalTop = styled(AngledLineVertical)<
- AngledLineVerticalProps
->`
left: 50%;
top: -1px;
width: 29px;
diff --git a/src/models/index.ts b/src/models/index.ts
index b663651..7e19a09 100644
--- a/src/models/index.ts
+++ b/src/models/index.ts
@@ -52,8 +52,9 @@ interface MajorSkill extends BaseSkill {
icon: string;
}
+export type Direction = 'left' | 'right';
+
export type ParentPosition = {
- bottom: number;
center: number;
};