import * as React from 'react' ; import { ICommand , TextState , TextAreaTextApi } from './' ; import { selectWord , getBreaksNeededForEmptyLineBefore , getBreaksNeededForEmptyLineAfter , } from '../utils/markdownUtils' ; export type AlterLineFunction = ( line : string , index : number ) => string ; /**
 * Inserts insertionString before each line
 */ export function insertBeforeEachLine ( selectedText , insertBefore ) { const lines = selectedText . split ( /\n/ ) ; let insertionLength = 0 ; const modifiedText = lines . map ( ( item , index ) => { if ( typeof insertBefore === 'string' ) { insertionLength += insertBefore . length ; return insertBefore + item ; } else if ( typeof insertBefore === 'function' ) { const insertionResult = insertBefore ( item , index ) ; insertionLength += insertionResult . length ; return insertBefore ( item , index ) + item ; } throw Error ( 'insertion is expected to be either a string or a function' ) ; } ) . join ( '\n' ) ; return { modifiedText , insertionLength } ; } export const makeList = ( state , api , insertBefore ) => { const newSelectionRange = selectWord ( { text : state . text , selection : state . selection } ) ; const state1 = api . setSelectionRange ( newSelectionRange ) ; const breaksBeforeCount = getBreaksNeededForEmptyLineBefore ( state1 . text , state1 . selection . start ) ; const breaksBefore = Array ( breaksBeforeCount + 1 ) . join ( '\n' ) ; const breaksAfterCount = getBreaksNeededForEmptyLineAfter ( state1 . text , state1 . selection . end ) ; const breaksAfter = Array ( breaksAfterCount + 1 ) . join ( '\n' ) ; const modifiedText = insertBeforeEachLine ( state1 . selectedText , insertBefore ) ; api . replaceSelection ( `${ breaksBefore }${ modifiedText . modifiedText }${ breaksAfter }` ) ; const oneLinerOffset = state1 . selectedText . indexOf ( '\n' ) === - 1 ? modifiedText . insertionLength : 0 ; const selectionStart = state1 . selection . start + breaksBeforeCount + oneLinerOffset ; const selectionEnd = selectionStart + modifiedText . modifiedText . length - oneLinerOffset ; api . setSelectionRange ( { start : selectionStart , end : selectionEnd , } ) ; } ; export const unorderedListCommand = { name : 'unordered-list' , keyCommand : 'list' , shortcuts : 'ctrl+shift+l' , buttonProps : { 'aria-label' : 'Add unordered list' , title : 'Add unordered list' } , icon : ( < svg data - name = "unordered-list" width = "12" height = "12" viewBox = "0 0 512 512" > < path fill = "currentColor" d = "M96 96c0 26.51-21.49 48-48 48S0 122.51 0 96s21.49-48 48-48 48 21.49 48 48zM48 208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm0 160c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm96-236h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" / > < /svg>), execute : ( state , api ) => { makeList ( state , api , '- ' ) ; } , } ; export const orderedListCommand = { name : 'ordered-list' , keyCommand : 'list' , shortcuts : 'ctrl+shift+o' , buttonProps : { 'aria-label' : 'Add ordered list' , title : 'Add ordered list' } , icon : ( < svg data - name = "ordered-list" width = "12" height = "12" role = "img" viewBox = "0 0 512 512" > < path fill = "currentColor" d = "M3.263 139.527c0-7.477 3.917-11.572 11.573-11.572h15.131V88.078c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.938C32.815 33.602 36.732 32 42.785 32H54.89c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572H14.836c-7.656 0-11.573-4.095-11.573-11.572v-8.902zM2.211 304.591c0-47.278 50.955-56.383 50.955-69.165 0-7.18-5.954-8.755-9.28-8.755-3.153 0-6.479 1.051-9.455 3.852-5.079 4.903-10.507 7.004-16.111 2.451l-8.579-6.829c-5.779-4.553-7.18-9.805-2.803-15.409C13.592 201.981 26.025 192 47.387 192c19.437 0 44.476 10.506 44.476 39.573 0 38.347-46.753 46.402-48.679 56.909h39.049c7.529 0 11.557 4.027 11.557 11.382v8.755c0 7.354-4.028 11.382-11.557 11.382h-67.94c-7.005 0-12.083-4.028-12.083-11.382v-4.028zM5.654 454.61l5.603-9.28c3.853-6.654 9.105-7.004 15.584-3.152 4.903 2.101 9.63 3.152 14.359 3.152 10.155 0 14.358-3.502 14.358-8.23 0-6.654-5.604-9.106-15.934-9.106h-4.728c-5.954 0-9.28-2.101-12.258-7.88l-1.05-1.926c-2.451-4.728-1.226-9.806 2.801-14.884l5.604-7.004c6.829-8.405 12.257-13.483 12.257-13.483v-.35s-4.203 1.051-12.608 1.051H16.685c-7.53 0-11.383-4.028-11.383-11.382v-8.755c0-7.53 3.853-11.382 11.383-11.382h58.484c7.529 0 11.382 4.027 11.382 11.382v3.327c0 5.778-1.401 9.806-5.079 14.183l-17.509 20.137c19.611 5.078 28.716 20.487 28.716 34.845 0 21.363-14.358 44.126-48.503 44.126-16.636 0-28.192-4.728-35.896-9.455-5.779-4.202-6.304-9.805-2.626-15.934zM144 132h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" / > < /svg>), execute : ( state , api ) => { makeList ( state , api , ( item , index ) => `${ index + 1 }. ` ) ; } , } ; export const checkedListCommand = { name : 'checked-list' , keyCommand : 'list' , shortcuts : 'ctrl+shift+c' , buttonProps : { 'aria-label' : 'Add checked list' , title : 'Add checked list' } , icon : ( < svg data - name = "checked-list" width = "12" height = "12" role = "img" viewBox = "0 0 512 512" > < path fill = "currentColor" d = "M208 132h288c8.8 0 16-7.2 16-16V76c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zM64 368c-26.5 0-48.6 21.5-48.6 48s22.1 48 48.6 48 48-21.5 48-48-21.5-48-48-48zm92.5-299l-72.2 72.2-15.6 15.6c-4.7 4.7-12.9 4.7-17.6 0L3.5 109.4c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.3c4.7-4.7 12.3-4.7 17 0l17 16.5c4.6 4.7 4.6 12.3-.1 17zm0 159.6l-72.2 72.2-15.7 15.7c-4.7 4.7-12.9 4.7-17.6 0L3.5 269c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.7c4.7-4.7 12.3-4.7 17 0l17 17c4.6 4.6 4.6 12.2-.1 16.9z" / > < /svg>), execute : ( state , api ) => { makeList ( state , api , ( item , index ) => `- [ ] ` ) ; } , } ;