@@ -2,24 +2,10 @@ import React, { useState, useEffect, useRef } from 'react'
22import Markdown from 'markdown-to-jsx'
33import noop from '../helpers/noop'
44import styles from '../scss/mdInput.module.scss'
5- import {
6- HeadingIcon ,
7- BoldIcon ,
8- ItalicIcon ,
9- QuoteIcon ,
10- CodeIcon ,
11- LinkIcon ,
12- ListUnorderedIcon ,
13- ListOrderedIcon ,
14- TasklistIcon ,
15- TypographyIcon ,
16- ChevronDownIcon ,
17- ChevronUpIcon
18- } from '@primer/octicons-react'
19-
20- import IconButton from './theme/IconButton'
215import { Nav } from 'react-bootstrap'
226import { useBreakpoint } from '../helpers/useBreakpoint'
7+ import MarkdownToolbar from './MarkdownToolbar'
8+
239type MdInputProps = {
2410 onChange ?: Function
2511 placeHolder ?: string
@@ -75,190 +61,16 @@ export const MdInput: React.FC<MdInputProps> = ({
7561 return ( ) => window . removeEventListener ( 'mouseup' , updateHeight , false )
7662 } , [ ] )
7763
78- const previewBtnColor = preview ? 'black' : 'lightgrey'
79- const writeBtnColor = preview ? 'lightgrey' : 'black'
80-
81- const onChangeWithAutoSize = e => {
82- if ( ! height && textareaRef . current ) autoSize ( textareaRef . current )
83- onChange ( e . target . value )
84- }
85-
86- // TODO: Export markdownToolbar and associated helpers to separate file
87- const markdownInputToggler = (
88- textareaRef ,
89- left : string ,
90- right : string = ''
91- ) : void => {
92- // TODO: add expand single select to word functionality and support for one sided and multiline operations
93- if ( ! textareaRef . current ) return
94- const { value, selectionStart, selectionEnd } = textareaRef . current
95-
96- const selection = value . slice ( selectionStart , selectionEnd )
97-
98- const hasLeft =
99- selectionStart >= left . length &&
100- value . slice ( selectionStart - left . length , selectionStart ) === left
101- const hasRight =
102- selectionEnd + right . length <= value . length &&
103- value . slice ( selectionEnd , selectionEnd + right . length ) === right
104- console . log ( {
105- selection,
106- value,
107- selectionEnd,
108- selectionStart,
109- left,
110- hasLeft,
111- right,
112- hasRight
113- } )
64+ // TODO: Convert tabs to old styles
65+ // const previewBtnColor = preview ? 'black' : 'lightgrey'
66+ // const writeBtnColor = preview ? 'lightgrey' : 'black'
11467
115- // const fakeEvent = { target: { value: 'remove!' } }
116- textareaRef . current . focus ( )
117- if ( hasLeft && hasRight ) {
118- // expand selection to include left and right
119- textareaRef . current . setSelectionRange (
120- selectionStart - left . length ,
121- selectionEnd + right . length
122- )
123- // Replace with old selection
124- document . execCommand ( 'insertText' , false , selection )
125-
126- // update selection
127- // expand selection to include left and right
128- textareaRef . current . setSelectionRange (
129- selectionStart - left . length ,
130- selectionEnd - left . length
131- )
132- } else {
133- document . execCommand ( 'insertText' , false , left + selection + right )
134- textareaRef . current . setSelectionRange (
135- selectionStart + left . length ,
136- selectionEnd + left . length
137- )
138- // onChangeWithAutoSize({ target: { value: 'add!' } })
68+ const onChangeWithAutoSize : React . ChangeEventHandler < HTMLTextAreaElement > =
69+ e => {
70+ if ( ! height && textareaRef . current ) autoSize ( textareaRef . current )
71+ onChange ( e . target . value )
13972 }
140- }
141-
142- const markdownToolbar = (
143- < div className = "ml-auto" >
144- { /* <IconButton
145- tabIndex="-1"
146- color="black"
147- aria-label="Toggle text tools"
148- aria-expanded="true"
149- onClick={e => console.log("I'm clicked")}
150- icon={
151- <>
152- <TypographyIcon size={'small'} />
153- <ChevronDownIcon size={'small'} />
154- </>
155- }
156- /> */ }
157- < IconButton
158- tabIndex = "-1"
159- color = "black"
160- delay = { { show : 250 } }
161- tooltipTitle = "Add header text"
162- aria-label = "Add header text"
163- role = "button"
164- placement = "bottom-end"
165- onClick = { ( ) => markdownInputToggler ( textareaRef , '### ' , '' ) }
166- icon = { < HeadingIcon size = { 'small' } /> }
167- />
168- < IconButton
169- tabIndex = "-1"
170- color = "black"
171- delay = { { show : 250 } }
172- tooltipTitle = "Add bold text <ctrl+b>"
173- aria-label = "Add bold text <ctrl+b>"
174- role = "button"
175- placement = "bottom-end"
176- onClick = { ( ) => markdownInputToggler ( textareaRef , '**' , '**' ) }
177- icon = { < BoldIcon size = { 'small' } /> }
178- />
179- < IconButton
180- tabIndex = "-1"
181- color = "black"
182- delay = { { show : 250 } }
183- tooltipTitle = "Add italic text <ctrl+i>"
184- aria-label = "Add italic text <ctrl+i>"
185- role = "button"
186- placement = "bottom-end"
187- onClick = { ( ) => {
188- markdownInputToggler ( textareaRef , '_' , '_' )
189- } }
190- icon = { < ItalicIcon size = { 'small' } /> }
191- />
192-
193- < IconButton
194- tabIndex = "-1"
195- color = "black"
196- delay = { { show : 250 } }
197- tooltipTitle = "Insert a quote"
198- aria-label = "Insert a quote"
199- role = "button"
200- placement = "bottom-end"
201- onClick = { ( ) => markdownInputToggler ( textareaRef , '\n> ' , '' ) }
202- icon = { < QuoteIcon size = { 'small' } /> }
203- />
204- < IconButton
205- tabIndex = "-1"
206- color = "black"
207- delay = { { show : 250 } }
208- tooltipTitle = "Insert code <ctrl+e>"
209- aria-label = "Insert code <ctrl+e>"
210- role = "button"
211- placement = "bottom-end"
212- onClick = { ( ) => markdownInputToggler ( textareaRef , '`' , '`' ) }
213- icon = { < CodeIcon size = { 'small' } /> }
214- />
215- < IconButton
216- tabIndex = "-1"
217- color = "black"
218- delay = { { show : 250 } }
219- tooltipTitle = "Add a link <ctrl+k>"
220- aria-label = "Add a link <ctrl+k>"
221- role = "button"
222- placement = "bottom-end"
223- onClick = { ( ) => markdownInputToggler ( textareaRef , '[' , '](URL)' ) }
224- icon = { < LinkIcon size = { 'small' } /> }
225- />
22673
227- < IconButton
228- tabIndex = "-1"
229- color = "black"
230- delay = { { show : 250 } }
231- tooltipTitle = "Add a bulleted list"
232- aria-label = "Add a bulleted list"
233- role = "button"
234- placement = "bottom-end"
235- onClick = { ( ) => markdownInputToggler ( textareaRef , '\n- ' , '' ) }
236- icon = { < ListUnorderedIcon size = { 'small' } /> }
237- />
238- < IconButton
239- tabIndex = "-1"
240- color = "black"
241- delay = { { show : 250 } }
242- tooltipTitle = "Add a numbered list"
243- aria-label = "Add a numbered list"
244- role = "button"
245- placement = "bottom-end"
246- onClick = { ( ) => markdownInputToggler ( textareaRef , '\n1. ' , '' ) }
247- icon = { < ListOrderedIcon size = { 'small' } /> }
248- />
249- < IconButton
250- tabIndex = "-1"
251- color = "black"
252- delay = { { show : 250 } }
253- tooltipTitle = "Add a task list"
254- aria-label = "Add a task list"
255- role = "button"
256- placement = "bottom-end"
257- onClick = { ( ) => markdownInputToggler ( textareaRef , '\n- [] ' , '' ) }
258- icon = { < TasklistIcon size = { 'small' } /> }
259- />
260- </ div >
261- )
26274 return (
26375 < div style = { { backgroundColor : bgColor } } >
26476 < Nav
@@ -273,9 +85,11 @@ export const MdInput: React.FC<MdInputProps> = ({
27385 < Nav . Item >
27486 < Nav . Link eventKey = "Preview" > Preview</ Nav . Link >
27587 </ Nav . Item >
276- { ! lessThanMd && ! preview && markdownToolbar }
88+ { ! lessThanMd && ! preview && (
89+ < MarkdownToolbar inputRef = { textareaRef } className = "ml-auto" />
90+ ) }
27791 </ Nav >
278- { lessThanMd && ! preview && markdownToolbar }
92+ { lessThanMd && ! preview && < MarkdownToolbar inputRef = { textareaRef } /> }
27993 { preview && (
28094 < >
28195 < Markdown
0 commit comments