import prop from 'ramda/es/prop' ; import groupBy from 'ramda/es/groupBy' ; import { StyleProp , TextStyle , ViewStyle } from 'react-native' ; import invariant from 'invariant' ; import { TextOp } from '@delta/operations' ; import { Attributes } from '@delta/attributes' ; const attributeNameGetter = prop ( 'attributeName' ) as ( t : Transforms . GenericSpec < Attributes . GenericValue , Transforms . TargetType > ) => string ; export function textTransformListToDict < A extends Attributes . GenericValue , T extends Transforms . TargetType > ( list ) { return groupBy ( attributeNameGetter ) ( list ) as Transforms . Dict < A , T > ; } public declare namespace Transforms { /**
     * The target type of a transform.
     */ export type TargetType = 'block' | 'text' ; /**
     * A  {@link (Transforms:namespace).GenericSpec} which `attributeActiveValue` is `true`.
     *
     *  public export type BoolSpec < T extends TargetType = 'block' > = GenericSpec < true , T > ; internal export interface Dict < A extends Attributes . GenericValue , T extends TargetType > { [ attributeName ] : GenericSpec < A , T > [ ] ; } public export type TextAttributeName = 'bold' | 'italic' | 'textDecoration' ; public export interface GenericSpec < A extends Attributes . GenericValue , T extends TargetType > { remarks Multiple  {@link (Transforms:namespace).GenericSpec} can share the same `attributeName`.
          attributeName : string ; /**
         * The value of the attribute when this transform is active.
         */ activeAttributeValue : A ; /**
         * The style applied to the target block when this transform is active.
         */ activeStyle : T extends 'block' ? ViewStyle : TextStyle ; } export type Specs < T extends 'text' | 'block' = 'text' > = GenericSpec < Attributes . TextValue , T > [ ] ; } public class Transforms { private textTransformsDict : Transforms . Dict < Attributes . TextValue , 'text' > ; public constructor ( textTransformSpecs ) { this . textTransformsDict = textTransformListToDict ( textTransformSpecs ) ; } param op internal public getStylesFromOp ( op ) { const styles = [ ] ; if ( op . attributes ) { for ( const attributeName of Object . keys ( op . attributes ) ) { if ( op . attributes != null && attributeName !== '$type' ) { const attributeValue = op . attributes [ attributeName ] ; let match = false ; if ( attributeValue !== null ) { for ( const candidate of this . textTransformsDict [ attributeName ] || [ ] ) { if ( candidate . activeAttributeValue === attributeValue ) { styles . push ( candidate . activeStyle ) ; match = true ; } } invariant ( match , `A Text Transform must be specified for attribute "${ attributeName }" with value ${ JSON . stringify ( attributeValue ) }` ) ; } } } } return styles ; } } export { Transforms } ; export const booleanTransformBase = { activeAttributeValue : true as true , } ; export const boldTransform = { ... booleanTransformBase , attributeName : 'bold' , activeStyle : { fontWeight : 'bold' , } , } ; export const italicTransform = { ... booleanTransformBase , attributeName : 'italic' , activeStyle : { fontStyle : 'italic' , } , } ; export const underlineTransform = { activeAttributeValue : 'underline' , attributeName : 'textDecoration' , activeStyle : { textDecorationStyle : 'solid' , textDecorationLine : 'underline' , } , } ; export const strikethroughTransform = { activeAttributeValue : 'strikethrough' , attributeName : 'textDecoration' , activeStyle : { textDecorationStyle : 'solid' , textDecorationLine : 'line-through' , } , } ; public export const defaultTextTransforms = [ boldTransform , italicTransform , underlineTransform , strikethroughTransform , ] ;