aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/ui/pointer.tsx
blob: c97b1e70004346d73b23a99c81d3f9801f1e8b4c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { colors } from '@0x/react-shared';
import * as React from 'react';
import { styled } from 'ts/style/theme';

export enum PointerDirection {
    Top = 'top',
    Right = 'right',
    Bottom = 'bottom',
    Left = 'left',
}

export interface PointerProps {
    className?: string;
    color?: string;
    size?: number;
    direction: PointerDirection;
}

const PlainPointer: React.StatelessComponent<PointerProps> = props => <div {...props} />;

const positionToCss = (props: PointerProps) => {
    const position = {
        top: `bottom: 100%; left: 50%;`,
        right: `left: 100%; top: 50%;`,
        bottom: `top: 100%; left: 50%;`,
        left: `right: 100%; top: 50%;`,
    }[props.direction];

    const borderColorSide = {
        top: 'border-bottom-color',
        right: 'border-left-color',
        bottom: 'border-top-color',
        left: 'border-right-color',
    }[props.direction];
    const border = `${borderColorSide}: ${props.color};`;
    const marginSide = {
        top: 'margin-left',
        right: 'margin-top',
        bottom: 'margin-left',
        left: 'margin-top',
    }[props.direction];
    const margin = `${marginSide}: -${props.size}px`;
    return {
        position,
        border,
        margin,
    };
};

export const Pointer = styled(PlainPointer)`
    position: relative;
    &:after {
        border: solid transparent;
        content: " ";
        height: 0;
        width: 0;
        position: absolute;
        pointer-events: none;
        border-color: rgba(136, 183, 213, 0);
        border-width: ${props => `${props.size}px`};
        ${props => positionToCss(props).position}
        ${props => positionToCss(props).border}
        ${props => positionToCss(props).margin}
    }
`;

Pointer.defaultProps = {
    color: colors.white,
    size: 16,
};

Pointer.displayName = 'Pointer';