import {IconType, DocumentedType, UMLClassMemberVisibility, UMLClassMemberLifetime} from "../../common/types"; import {Icon} from "./icon"; /** * This maps into the iconTypes.svg [x,y] * * (0,0)-------x * | * | * y * */ const iconLocations = { [IconType.Global]: { x: 10, y: 0 }, [IconType.Namespace]: { x: 0, y: 6 }, [IconType.Variable]: { x: 0, y: 1 }, [IconType.Function]: { x: 8, y: 4 }, [IconType.FunctionGeneric]: { x: 8, y: 5 }, [IconType.Enum]: { x: 0, y: 7 }, [IconType.EnumMember]: { x: 0, y: 8 }, [IconType.Interface]: { x: 0, y: 4 }, [IconType.InterfaceGeneric]: { x: 0, y: 5 }, [IconType.InterfaceConstructor]: { x: 12, y: 6 }, [IconType.InterfaceProperty]: { x: 12, y: 0 }, [IconType.InterfaceMethod]: { x: 12, y: 4 }, [IconType.InterfaceMethodGeneric]: { x: 12, y: 5 }, [IconType.InterfaceIndexSignature]: { x: 12, y: 7 }, [IconType.Class]: { x: 0, y: 2 }, [IconType.ClassGeneric]: { x: 0, y: 3 }, [IconType.ClassConstructor]: { x: 3, y: 6 }, [IconType.ClassProperty]: { x: 3, y: 0 }, [IconType.ClassMethod]: { x: 3, y: 4 }, [IconType.ClassMethodGeneric]: { x: 3, y: 5 }, [IconType.ClassIndexSignature]: { x: 3, y: 7 }, } const _typeIconLocations: { [key: number]: { x: number, y: number } } = iconLocations; import * as ui from "../ui"; import * as React from "react"; import * as pure from "../../common/pure"; import * as csx from '../base/csx'; import * as styles from "../styles/styles"; interface Props { iconType: IconType } interface State { } namespace TypeIconStyles { export const spriteSize = 17; // px /** We want to eat a bit of the icon otherwise we get neighbours at certain scales */ export const iconClipWidth = 1; export const root = { width: `${spriteSize - iconClipWidth}px`, height: `${spriteSize}px`, display: 'inline-block', } } /** * Draws the icon for a type */ export class TypeIcon extends ui.BaseComponent{ shouldComponentUpdate() { return pure.shouldComponentUpdate.apply(this, arguments); } render() { const imageLocation = iconLocations[this.props.iconType]; const left = imageLocation.x * -TypeIconStyles.spriteSize - TypeIconStyles.iconClipWidth; const top = imageLocation.y * -TypeIconStyles.spriteSize; const backgroundImage = 'url(assets/typeIcons.svg)'; const backgroundPosition = `${left}px ${top}px`; const style = csx.extend(TypeIconStyles.root, { backgroundImage, backgroundPosition }); return
; } } /** * Draws an icon for `private` visibility indication */ class VisibilityIndicator extends ui.BaseComponent<{ visibility: UMLClassMemberVisibility }, State>{ shouldComponentUpdate() { return pure.shouldComponentUpdate.apply(this, arguments); } render() { // Maybe add others if needed. I doubt it though. const classIconColorTheme = "#4DA6FF"; if (this.props.visibility === UMLClassMemberVisibility.Public) return ; if (this.props.visibility === UMLClassMemberVisibility.Private) return ; else return ; } } /** * Draws an icon for `override` visibility indication */ class OverrideIndicator extends ui.BaseComponent<{}, State>{ shouldComponentUpdate() { return pure.shouldComponentUpdate.apply(this, arguments); } render() { // Maybe add others if needed. I doubt it though. const classIconColorTheme = "#4DA6FF"; return ; } } /** * Draws an icon for `static` indication */ class LifetimeIndicator extends React.PureComponent<{ lifetime: UMLClassMemberLifetime }, State>{ render() { // Maybe add others if needed. I doubt it though. const classIconColorTheme = "#4DA6FF"; if (this.props.lifetime === UMLClassMemberLifetime.Instance) return ; else return ; } } /** * Draws the icon followed by name */ namespace DocumentedTypeHeaderStyles { export const root = csx.extend( { fontWeight: 'bold', fontSize: '.6rem', color: styles.textColor, // Center display: 'flex', alignItems: 'center', whiteSpace: 'pre' }); } interface DocumentedTypeHeaderProps { name: string, icon: IconType, visibility?: UMLClassMemberVisibility, lifetime?: UMLClassMemberLifetime, override?: boolean, } export class DocumentedTypeHeader extends React.PureComponent{ render() { const hasLifetime = (this.props.lifetime != null) && this.props.lifetime !== UMLClassMemberLifetime.Instance; const hasVisibility = (this.props.visibility != null) && this.props.visibility !== UMLClassMemberVisibility.Public; return
{hasLifetime && } {hasLifetime && "\u00a0"} {hasVisibility && } {hasVisibility && "\u00a0"} {" " + this.props.name} {this.props.override && "\u00a0"} {this.props.override && }
; } } export const SectionHeader = (props:{text:string}) => { return
{props.text}
} /** * Draws the legend */ namespace TypeIconLegendStyles { export const root = csx.extend( { fontWeight: 'bold', fontSize: '.6rem', color: styles.textColor, }); export const legendColumnContainer = csx.horizontal; export const legendColumn = csx.extend( csx.vertical, { padding: '10px' }); } export class TypeIconLegend extends React.PureComponent<{}, {}>{ render() { return (
); } } export class TypeIconClassDiagramLegend extends React.PureComponent<{}, {}>{ render() { return (
  Private
  Protected
  Static
  Override
); } }