Argument.tsx 3.7 KB
Newer Older
P
Peter Pan 已提交
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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
import {Argument as ArgumentType, Property as PropertyType} from '~/resource/graphs/types';
import React, {FunctionComponent, useMemo, useState} from 'react';
import {borderColor, em, sameBorder, textLightColor, textLighterColor} from '~/utils/style';

import Icon from '~/components/Icon';
import styled from 'styled-components';

const Wrapper = styled.div`
    ${sameBorder({radius: true})}

    & + & {
        margin-top: ${em(10)};
    }

    > .argument-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: ${em(8)} ${em(10)};
        line-height: 1.5;

        > .argument-text {
            flex: auto;
            overflow: hidden;
            word-break: break-all;
        }

        > .argument-raw {
            overflow: auto;
            width: 100%;

            pre {
                margin: 0;
            }
        }

        > .argument-operation {
            flex: none;
            cursor: pointer;
            font-size: ${em(14)};
            margin-left: ${em(10)};
            color: ${textLighterColor};

            &:hover,
            &:active {
                color: ${textLightColor};
            }
        }

        &:not(:first-child) {
            border-top: 1px solid ${borderColor};
        }
    }
`;

type ArgumentProps = {
    value: ArgumentType | PropertyType;
    expand?: boolean;
    showNodeDodumentation?: () => unknown;
};

const Argument: FunctionComponent<ArgumentProps> = ({value, expand, showNodeDodumentation}) => {
    const [expanded, setExpanded] = useState(expand ?? false);

    const expandable = useMemo(() => {
        const argument = value as ArgumentType;
        return !!(argument.children && argument.children.length);
    }, [value]);

    return (
        <Wrapper>
            <div className="argument-row">
                <span className="argument-text">
                    {value.name ? (
                        <>
                            {value.name}: <b>{value.value}</b>
                        </>
                    ) : (
                        value.value.split('\n').map((line, index) => (
                            <React.Fragment key={index}>
                                {index !== 0 && <br />}
                                {line}
                            </React.Fragment>
                        ))
                    )}
                </span>
                {(value as PropertyType).documentation && (
                    <a className="argument-operation" onClick={() => showNodeDodumentation?.()}>
                        <Icon type="question-circle" />
                    </a>
                )}
                {expandable && (
                    <a className="argument-operation" onClick={() => setExpanded(e => !e)}>
                        <Icon type={expanded ? 'minus' : 'plus'} />
                    </a>
                )}
            </div>
            {expandable &&
                expanded &&
                (value as ArgumentType)?.children?.map((item, index) => (
                    <div className="argument-row" key={index}>
                        {item.type === 'raw' ? (
                            <span className="argument-raw">
                                <pre>{item.value}</pre>
                            </span>
                        ) : (
                            <span className="argument-text">
                                {item.name ? `${item.name}: ` : ''}
                                <b>{item.type === 'code' ? <code>{item.value}</code> : item.value}</b>
                            </span>
                        )}
                    </div>
                ))}
        </Wrapper>
    );
};

export default Argument;