import * as _ from 'lodash'; import * as React from 'react'; import { DocsInfo } from '../docs_info'; import { Parameter, Type as TypeDef, TypeDefinitionByName, TypeParameter } from '../types'; import { Type } from './type'; export interface SignatureProps { name: string; returnType: TypeDef; parameters: Parameter[]; sectionName: string; shouldHideMethodName?: boolean; shouldUseArrowSyntax?: boolean; typeDefinitionByName?: TypeDefinitionByName; typeParameter?: TypeParameter; callPath?: string; docsInfo: DocsInfo; isInPopover: boolean; } const defaultProps = { shouldHideMethodName: false, shouldUseArrowSyntax: false, callPath: '', }; export const Signature: React.SFC = (props: SignatureProps) => { const sectionName = props.sectionName; const parameters = renderParameters( props.parameters, props.docsInfo, sectionName, props.isInPopover, props.typeDefinitionByName, ); const paramStringArray: any[] = []; // HACK: For now we don't put params on newlines if there are less then 2 of them. // Ideally we would check the character length of the resulting method signature and // if it exceeds the available space, put params on their own lines. const hasMoreThenTwoParams = parameters.length > 2; _.each(parameters, (param: React.ReactNode, i: number) => { const finalParam = hasMoreThenTwoParams ? ( {param} ) : ( param ); paramStringArray.push(finalParam); const comma = hasMoreThenTwoParams ? ( ,
) : ( ', ' ); paramStringArray.push(comma); }); if (!hasMoreThenTwoParams) { paramStringArray.pop(); } const methodName = props.shouldHideMethodName ? '' : props.name; const typeParameterIfExists = _.isUndefined(props.typeParameter) ? undefined : renderTypeParameter( props.typeParameter, props.docsInfo, sectionName, props.isInPopover, props.typeDefinitionByName, ); return ( {props.callPath} {methodName} {typeParameterIfExists}({hasMoreThenTwoParams &&
} {paramStringArray}) {props.returnType && ( {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '} )}
); }; Signature.defaultProps = defaultProps; function renderParameters( parameters: Parameter[], docsInfo: DocsInfo, sectionName: string, isInPopover: boolean, typeDefinitionByName?: TypeDefinitionByName, ): React.ReactNode[] { const params = _.map(parameters, (p: Parameter) => { const isOptional = p.isOptional; const hasDefaultValue = !_.isUndefined(p.defaultValue); const type = ( ); return ( {p.name} {isOptional && '?'}: {type} {hasDefaultValue && ` = ${p.defaultValue}`} ); }); return params; } function renderTypeParameter( typeParameter: TypeParameter, docsInfo: DocsInfo, sectionName: string, isInPopover: boolean, typeDefinitionByName?: TypeDefinitionByName, ): React.ReactNode { const typeParam = ( {`<${typeParameter.name}`} {!_.isUndefined(typeParameter.type) && ( {' extends '} )} {`>`} ); return typeParam; }