@zzish/math-rich-input 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,771 @@
1
+ import React from 'react'
2
+
3
+ import './AccentBar.css';
4
+
5
+ const DEFAULT_TOP = -1
6
+ const DEFAULT_LEFT = -1
7
+ const TOP_MARGIN = 3
8
+
9
+ const ACCENTS_FOR_LETTER = {
10
+ a:["à","á","â","ä","æ","ã","å","ā"],
11
+ c:["ç","ć","č"],
12
+ e:["è","é","ê","ë","ē","ė","ę"],
13
+ i:["î","ï","í","ī","į","ì"],
14
+ l:["ł"],
15
+ n:["ñ","ń"],
16
+ o:["ô","ö","ò","ó","œ","ø","ō","õ"],
17
+ s:["ß","ś","š"],
18
+ u:["û","ü","ù","ú","ū"],
19
+ y:["ÿ"],
20
+ "?":["¿"],
21
+ "!":["¡"],
22
+ A:["À","Á","Â","Ä","Æ","Ã","Å","Ā"],
23
+ C:["ç","ć","č"],
24
+ E:["È","É","Ê","Ë","Ē","Ė","Ę"],
25
+ I:["Î","Ï","Í","Ī","Į","Ì"],
26
+ L:["Ł"],
27
+ N:["Ñ","Ń"],
28
+ O:["Ô","Ö","Ò","Ó","Œ","Ø","Ō","Õ"],
29
+ S:["Ś","Š"],
30
+ U:["Û","Ü","Ù","Ú","Ū"],
31
+ Y:["Ÿ"]
32
+ }
33
+
34
+
35
+ let GLOBAL_default_accents = []
36
+
37
+ function addCharactersFromString(characters, string) {
38
+ for (let i = 0; i < string.length; i++) {
39
+ characters.push(string.charAt(i))
40
+ }
41
+ return characters
42
+ }
43
+
44
+ function addCharacters(characters, start, end) {
45
+ for (let c = start; c <= end; c++) {
46
+ characters.push(String.fromCharCode(c))
47
+ }
48
+ return characters
49
+ }
50
+
51
+ function buildGreekLowerCaseLetters() {
52
+ let characters = []
53
+ addCharacters(characters, 0x03B1, 0x03C9)
54
+ return characters
55
+ }
56
+
57
+ function buildGreekCapitaLetters() {
58
+ let characters = []
59
+ addCharactersFromString(characters, "ΓΔΘΛΞΠΣΦΨψΩ∇")
60
+ return characters
61
+ }
62
+
63
+ function buildCommonMathSymbols() {
64
+ let characters = []
65
+ const common = ["+","-","×","÷","=","▢","±","⋅","≠","≈","→","<",">","≤","≥","√","∛","∜","²","³","⁴","∞","π","°","∠"]
66
+ const brackets = ["〈","〉","⌈","⌉","⌊","⌋"]
67
+
68
+ characters.push(...common)
69
+ characters.push(...brackets)
70
+ return characters
71
+ }
72
+
73
+ function buildLetterMathSymbols() {
74
+ let characters = []
75
+ addCharactersFromString(characters, "ℑℜℂℕℙℚℝℤ")
76
+ return characters
77
+ }
78
+
79
+ function buildFractionMathSymbols() {
80
+ let characters = []
81
+ const fractions = ["½","⅓","⅔","¼","¾","⅕","⅖","⅗","⅘","⅙","⅚","⅐","⅛","⅜","⅝","⅞","⅑","⅒"]
82
+ characters.push(...fractions)
83
+ return characters
84
+ }
85
+
86
+ function buildArrowSymbols() {
87
+ let characters = []
88
+ addCharacters(characters, 0x2190, 0x21FF)
89
+ return characters
90
+ }
91
+
92
+ function buildAdvancedMathSymbols() {
93
+ let characters = []
94
+ addCharacters(characters, 0x2200, 0x22FF)
95
+ return characters
96
+ }
97
+
98
+ function buildCurrencySymbols() {
99
+ let characters = []
100
+ addCharactersFromString(characters, "$¢£€¥₹₤฿₴₭₺₪₦₱₽₩")
101
+ return characters
102
+ }
103
+
104
+ function buildLatinSymbols() {
105
+ let characters = []
106
+ addCharactersFromString(characters, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
107
+ return characters
108
+ }
109
+
110
+ function buildNumbers() {
111
+ let characters = []
112
+ addCharactersFromString(characters, "0123456789\u20dd\u20de")
113
+ return characters
114
+ }
115
+
116
+ // function buildRomanNumerals() {
117
+ // let characters = []
118
+ // addCharacters(characters, 0x2160, 0x217F)
119
+ // return characters
120
+ // }
121
+
122
+ function buildSymbols() {
123
+ let characters = []
124
+ addCharactersFromString(characters, "!@#%^&*|")
125
+ return characters
126
+ }
127
+
128
+ function buildEmoticonsSmileys() {
129
+ let characters = []
130
+ characters.push(...["😀","😀","😁","😆","😅","😂","🤣","😊","😇","🙂","🙃","😉","😍","🥰","😘","😜",
131
+ "🤪","🤨","🧐","🤓","😎","🤩","🥳","🙁","🥺","😢","😭","😤","🤯","😳","🥶","😱",
132
+ "🤗","🤔","🤭","🤫","🤥","😶","😐","😴","🤐","🥴","🤠","😈","👹","👺","🤡","💩",
133
+ "👻","💀","☠️","👽","👾","🤖","🎃","😺","😸","😹","😻","😼","😽","🙀","😿","😾"])
134
+ return characters
135
+ }
136
+
137
+ function buildEmoticonsPeople() {
138
+ let characters = []
139
+ characters.push(...["✍️","👏","🤝","👍","👎","🤞","👆","👇","✋","💪","🙏"])
140
+ characters.push(...["👂","👃","🧠","👁","👶","👧","👦","👩","👨","👳‍♂️","🧕","🙋‍♀️","🙋‍♂️","🙎‍♀️","🙎‍♂️","👩‍🎓","👨‍🎓","👩‍💻","👨‍💻","👩‍🏫","👨‍🏫"])
141
+ return characters
142
+ }
143
+
144
+ function buildEmoticonsAnimals() {
145
+ let characters = []
146
+ characters.push(...["🐶","🐱","🐭","🐹","🐰","🦊","🐻","🐼","🐨","🐯","🦁","🐮","🐷","🐽","🐸","🐵",
147
+ "🙈","🙉","🙊","🐔","🐧","🐦","🐤","🐣","🐥","🦆","🦅","🦉","🦇","🐺","🐗","🐴",
148
+ "🦄","🐝","🐛","🦋","🐌","🐞","🐜","🦟","🦗","🕷","🕸","🦂","🐢","🐍","🦎","🦖",
149
+ "🦕","🐙","🦑","🦐","🦞","🦀","🐡","🐠","🐟","🐬","🐳","🐋","🦈","🐊","🦍","🐘",
150
+ "🐅","🐆","🦓","🦛","🦏","🐪","🦒","🦘"])
151
+ return characters
152
+ }
153
+
154
+ function buildEmoticonsFood() {
155
+ let characters = []
156
+ characters.push(...["🍄","🌹","🌸","🌼","🌻","🌞","🌙","🌎","⭐️","🌟","✨","🍏","🍎","🍐","🍊","🍋",
157
+ "🍌","🍉","🍇","🍓","🍈","🍒","🍑","🥭","🍍","🥥","🥝","🍅","🥚","🧀","🥖","🥐",
158
+ "🍔","🍟","🍕","🥪","🍦","🥧","🧁","🍰","🍭","🍬","🍫","🍿","🍩","🍪","🥤","🥛"])
159
+ return characters
160
+ }
161
+
162
+ function buildEmoticonsGames() {
163
+ let characters = []
164
+ characters.push(...["⚽️","🏀","🏈","⚾️","🥎","🎾","🏐","🏉","🥏","🎱","🏏","🏆","🥇","🥈","🥉","🏅",
165
+ "🎖","🎲","🎭","🎨","🎬","🎤","🎹","🎷"])
166
+ return characters
167
+ }
168
+
169
+ function buildEmoticonsTransport() {
170
+ let characters = []
171
+ characters.push(...["🚗","🚕","🚙","🚌","🏎","🚓","🚑","🚒","🚐","🚚","🚜","🛴","🚲","🛵","🏍","🚂",
172
+ "🚋","✈️","🚀","🛸","🚁","🛶","⛵️","🚤"])
173
+ return characters
174
+ }
175
+
176
+ function buildEmoticonsMisc() {
177
+ let characters = []
178
+ characters.push(...["💰","💎","💣","🧨","⚗️","🔭","🔬","💉","🧬","🦠","🧫","🧪","🌡","🔑","🗝","🎁",
179
+ "🎈","📒","📕","📗","📘","📙","📚","📖","📊","📈","🧮","❤️","🧡","💛","💚","💙",
180
+ "💜","🖤","⚪️","⚫️","🔴","🔵","🔺","🔻","🔸","🔹","🔶","🔷","♠️","♣️","♥️","♦️"])
181
+ return characters
182
+ }
183
+
184
+ const GREEK_CAPITAL_LETTERS = buildGreekCapitaLetters()
185
+ const GREEK_LOWER_CASE_LETTERS = buildGreekLowerCaseLetters()
186
+
187
+ const COMMON_MATH_SYMBOLS = buildCommonMathSymbols()
188
+ const LETTER_MATH_SYMBOLS = buildLetterMathSymbols()
189
+ const FRACTION_MATH_SYMBOLS = buildFractionMathSymbols()
190
+ const ADVANCE_MATH_SYMBOLS = buildAdvancedMathSymbols()
191
+ const ARROW_SYBOLS = buildArrowSymbols()
192
+
193
+ const CURRENCY_SYMBOLS = buildCurrencySymbols()
194
+ const LATIN_LETTERS = buildLatinSymbols()
195
+ const NUMBER_SYMBOLS = buildNumbers()
196
+ const COMMON_SYMBOLS = buildSymbols()
197
+ // const ROMAN_NUMERALS = buildRomanNumerals()
198
+
199
+ const EMOTICONS_SMILEYS = buildEmoticonsSmileys()
200
+ const EMOTICONS_PEOPLE = buildEmoticonsPeople()
201
+ const EMOTICONS_ANIMALS = buildEmoticonsAnimals()
202
+ const EMOTICONS_FOOD = buildEmoticonsFood()
203
+ const EMOTICONS_GAMES = buildEmoticonsGames()
204
+ const EMOTICONS_TRANSPORT = buildEmoticonsTransport()
205
+ const EMOTICONS_MISC = buildEmoticonsMisc()
206
+
207
+ const TAB_NAMES = ["Accents", "Greek", "Math", "Emoticons", "More"]
208
+ let GLOBAL_last_selected_tab = TAB_NAMES[0]
209
+
210
+
211
+ export default class AccentBar extends React.Component {
212
+ constructor(props) {
213
+ super(props);
214
+ this.state = {
215
+ selectedTab: GLOBAL_last_selected_tab,
216
+ top:DEFAULT_TOP,
217
+ left:DEFAULT_LEFT,
218
+ }
219
+ this.suppliedClickHandler = null
220
+ this.handleButtonClick = this.handleButtonClick.bind(this)
221
+ this.letterForAccents = null
222
+ this.shouldUpdatePosition = true
223
+ this.shouldUpdateReplaceCharacters = true
224
+ this.isFullyMounted = false
225
+
226
+ if (GLOBAL_default_accents.length === 0)
227
+ for (let key in ACCENTS_FOR_LETTER) {
228
+ GLOBAL_default_accents.push(...ACCENTS_FOR_LETTER[key])
229
+ }
230
+ }
231
+
232
+ handleButtonClick = (e, character, insert=false) => {
233
+ // console.log("handleButtonClick")
234
+ // console.log(character)
235
+ // console.log(this.letterForAccents)
236
+ // console.log(insert)
237
+ if (insert)
238
+ this.suppliedClickHandler(e, null, character)
239
+ else
240
+ this.suppliedClickHandler(e, this.letterForAccents, character)
241
+ }
242
+
243
+ componentDidMount() {
244
+
245
+ // We render once to find out the component's preferred size and then render again to update it
246
+
247
+ if (this.shouldUpdatePosition) {
248
+ // Lets position the accent bar below the input field and left (compact mode) or right aligned
249
+ let thisBar = this.accentBar
250
+ let node = thisBar.parentNode
251
+ while(node !== null && !node.classList.contains("MathRichInput-Container"))
252
+ node = node.parentNode
253
+
254
+ if (node === null) {
255
+ console.error("Could not find ancestor MathRichInput-Container find parent")
256
+ return
257
+ }
258
+
259
+ let inputBounds = node.getBoundingClientRect()
260
+ let thisBounds = thisBar.getBoundingClientRect()
261
+
262
+ this.shouldUpdatePosition = false
263
+
264
+ // Vertically align below input field
265
+ let top = inputBounds.bottom + TOP_MARGIN
266
+
267
+ // Horizontally align to left or right of input field
268
+ let left = inputBounds.right - thisBounds.width // right align
269
+ if (this.props.compactMode)
270
+ left = inputBounds.left // left align
271
+
272
+ // Make sure it is on screen horizontally
273
+ if (thisBounds.width > inputBounds.width)
274
+ left = inputBounds.left - (thisBounds.width - inputBounds.width)/2
275
+
276
+ if (left + thisBounds.width > window.innerWidth)
277
+ left = window.innerWidth - thisBounds.width - 2
278
+
279
+ if (left < 0)
280
+ left = 0
281
+
282
+ this.setState({left, top})
283
+ } else {
284
+ this.shouldUpdatePosition = true
285
+ }
286
+ }
287
+
288
+ handleSelectTab = (tab) => {
289
+ GLOBAL_last_selected_tab = tab
290
+ this.setState({selectedTab:tab})
291
+ }
292
+
293
+ componentDidUpdate =(prevProps) => {
294
+ // console.log("componentDidUpdate")
295
+ let accentKey = this.props.keyPressed
296
+ if (accentKey === "Backspace" || accentKey === "ArrowLeft" || accentKey === "ArrowRight") {
297
+ if (this.shouldUpdateReplaceCharacters) {
298
+ this.shouldUpdateReplaceCharacters = false
299
+ let thisState = this.state
300
+ setTimeout(() => {
301
+ // console.log("Focing update")
302
+ this.setState(thisState)
303
+ },
304
+ 100)
305
+ } else {
306
+ this.shouldUpdateReplaceCharacters = true
307
+ }
308
+ }
309
+ }
310
+
311
+ render() {
312
+ // console.log("Rendering accent bar")
313
+ this.suppliedClickHandler = this.props.onButtonClick
314
+
315
+ let compactMode = false
316
+ if (this.props.compactMode !== null && this.props.compactMode !== undefined)
317
+ compactMode = this.props.compactMode
318
+
319
+ // Get the right accent letter for the replace functionality
320
+ let allAccents = GLOBAL_default_accents
321
+ let accentKey = this.props.keyPressed
322
+ if (!this.isFullyMounted)
323
+ accentKey = this.props.fetchAccentLetter()
324
+ else if ((accentKey === "Backspace" || accentKey === "ArrowLeft" || accentKey === "ArrowRight") &&
325
+ !this.shouldUpdateReplaceCharacters) // Yes, this should indeed be a NOT
326
+ accentKey = this.props.fetchAccentLetter()
327
+
328
+ // console.log("Accent key:"+accentKey)
329
+
330
+ let quickAccents = ACCENTS_FOR_LETTER[accentKey]
331
+ this.letterForAccents = accentKey
332
+ if (quickAccents === null || quickAccents === undefined)
333
+ quickAccents = []
334
+
335
+ // Set className
336
+ let className= compactMode ? 'AccentBar-compact' : 'AccentBar'
337
+ if (this.props.className)
338
+ className = className + " " + this.props.className
339
+
340
+ // Set up the tranlation to place the accent bar where we want it
341
+ let style = {...this.props.style}
342
+ if (this.state.left !== DEFAULT_LEFT || this.state.top !== DEFAULT_TOP) {
343
+ style.left = this.state.left + "px"
344
+ style.top = this.state.top + "px"
345
+ }
346
+
347
+ return (
348
+ <div
349
+ className={className}
350
+ style={style}
351
+ ref={(r) => this.accentBar = r}
352
+ onMouseDown={(e) => e.preventDefault()}
353
+ onMouseUp={(e) => e.preventDefault()}
354
+ onClick={(e) => e.preventDefault()}
355
+ >
356
+
357
+ { /* Compact mode */}
358
+ {compactMode &&
359
+ <div>
360
+ { quickAccents.map((character, index) => {
361
+ return (
362
+ <button
363
+ className="AccentBar-button AB-narrow AB-compact"
364
+ key={"accent-button-"+index}
365
+ onMouseDown={(e) => e.preventDefault()}
366
+ onMouseUp={(e) => this.handleButtonClick(e,character)}
367
+ onClick={(e) => e.preventDefault()}
368
+ >
369
+ {character}
370
+ </button>
371
+ )
372
+ })
373
+ }
374
+ </div>
375
+ }
376
+
377
+ { /* Normal mode */}
378
+ {!compactMode &&
379
+ <div>
380
+
381
+ <div className="tabBar">
382
+ { TAB_NAMES.map((tab, index) => {
383
+ return (
384
+ <span key={"tabBar-"+tab}>
385
+ { this.state.selectedTab === tab
386
+ ? <span className="tab-selected" selected={true}>{tab}</span>
387
+ : <span className="tab"
388
+ onMouseDown={(e) => e.preventDefault()}
389
+ onMouseUp={(e) => e.preventDefault()}
390
+ onClick={(e) => this.handleSelectTab(tab)}
391
+ >{tab}</span>
392
+ } </span>
393
+ )})
394
+ }
395
+ </div>
396
+
397
+ <div className="AccentBar-outerContainer">
398
+ <div className="AccentBar-innerContainer">
399
+
400
+ { /* Accents tab */}
401
+ {this.state.selectedTab === "Accents" &&
402
+ <div className="tabArea">
403
+ {quickAccents.length > -1 &&
404
+ <div className="replace-section">
405
+ <div className="section-label">
406
+ Replace
407
+ </div>
408
+ {quickAccents.length === 0 &&
409
+ <div className="type-a-letter">Type a vowel to show replacements</div>
410
+
411
+ }
412
+ { quickAccents.map((character, index) => {
413
+ return (
414
+ <button
415
+ className="AccentBar-button AB-narrow"
416
+ key={"accent-button-"+index}
417
+ onMouseDown={(e) => e.preventDefault()}
418
+ onMouseUp={(e) => this.handleButtonClick(e,character)}
419
+ onClick={(e) => e.preventDefault()}
420
+ >
421
+ {character}
422
+ </button>
423
+ )
424
+ })
425
+ }
426
+ </div>
427
+ }
428
+
429
+ <div className="section-label">
430
+ Insert
431
+ </div>
432
+ { allAccents.map((character, index) => {
433
+ return (
434
+ <button
435
+ className="AccentBar-button AB-narrow"
436
+ key={"accent-button-"+index}
437
+ onMouseDown={(e) => e.preventDefault()}
438
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
439
+ onClick={(e) => e.preventDefault()}
440
+ >
441
+ {character}
442
+ </button>
443
+ )})
444
+ }
445
+ </div>
446
+ }
447
+
448
+ { /* Greek tab */}
449
+ { this.state.selectedTab === "Greek" &&
450
+ <div className="tabArea">
451
+ <div className="section-label">
452
+ Lower case
453
+ </div>
454
+ { GREEK_LOWER_CASE_LETTERS.map((character, index) => {
455
+ return (
456
+ <button
457
+ className="AccentBar-button AB-narrow"
458
+ key={"accent-button-"+index}
459
+ onMouseDown={(e) => e.preventDefault()}
460
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
461
+ onClick={(e) => e.preventDefault()}
462
+ >
463
+ {character}
464
+ </button>
465
+ )})
466
+ }
467
+ <div className="section-label">
468
+ Capitals
469
+ </div>
470
+ { GREEK_CAPITAL_LETTERS.map((character, index) => {
471
+ return (
472
+ <button
473
+ className="AccentBar-button AB-narrow"
474
+ key={"accent-button-"+index}
475
+ onMouseDown={(e) => e.preventDefault()}
476
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
477
+ onClick={(e) => e.preventDefault()}
478
+ >
479
+ {character}
480
+ </button>
481
+ )})
482
+ }
483
+ </div>
484
+ }
485
+
486
+ { /* Math tab */}
487
+ { this.state.selectedTab === "Math" &&
488
+ <div className="tabArea">
489
+ <div className="section-label">
490
+ Common
491
+ </div>
492
+ { COMMON_MATH_SYMBOLS.map((character, index) => {
493
+ return (
494
+ <button
495
+ className="AccentBar-button AB-narrow"
496
+ key={"accent-button-"+index}
497
+ onMouseDown={(e) => e.preventDefault()}
498
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
499
+ onClick={(e) => e.preventDefault()}
500
+ >
501
+ {character}
502
+ </button>
503
+ )
504
+ })}
505
+ <div className="section-label">
506
+ Fractions
507
+ </div>
508
+ { FRACTION_MATH_SYMBOLS.map((character, index) => {
509
+ return (
510
+ <button
511
+ className="AccentBar-button AB-narrow"
512
+ key={"accent-button-"+index}
513
+ onMouseDown={(e) => e.preventDefault()}
514
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
515
+ onClick={(e) => e.preventDefault()}
516
+ >
517
+ {character}
518
+ </button>
519
+ )
520
+ })}
521
+ <div className="section-label">
522
+ Letters
523
+ </div>
524
+ { LETTER_MATH_SYMBOLS.map((character, index) => {
525
+ return (
526
+ <button
527
+ className="AccentBar-button AB-narrow"
528
+ key={"accent-button-"+index}
529
+ onMouseDown={(e) => e.preventDefault()}
530
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
531
+ onClick={(e) => e.preventDefault()}
532
+ >
533
+ {character}
534
+ </button>
535
+ )
536
+ })}
537
+ <div className="section-label">
538
+ Advanced
539
+ </div>
540
+ { ADVANCE_MATH_SYMBOLS.map((character, index) => {
541
+ return (
542
+ <button
543
+ className="AccentBar-button AB-narrow"
544
+ key={"accent-button-"+index}
545
+ onMouseDown={(e) => e.preventDefault()}
546
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
547
+ onClick={(e) => e.preventDefault()}
548
+ >
549
+ {character}
550
+ </button>
551
+ )
552
+ })}
553
+ <div className="section-label">
554
+ Arrows
555
+ </div>
556
+ { ARROW_SYBOLS.map((character, index) => {
557
+ return (
558
+ <button
559
+ className="AccentBar-button AB-narrow"
560
+ key={"accent-button-"+index}
561
+ onMouseDown={(e) => e.preventDefault()}
562
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
563
+ onClick={(e) => e.preventDefault()}
564
+ >
565
+ {character}
566
+ </button>
567
+ )
568
+ })}
569
+ </div>
570
+ }
571
+
572
+ { /* Emoticons tab */}
573
+ { this.state.selectedTab === "Emoticons" &&
574
+ <div className="tabArea">
575
+ <div className="section-label">
576
+ Smileys
577
+ </div>
578
+ { EMOTICONS_SMILEYS.map((character, index) => {
579
+ return (
580
+ <button
581
+ className="AccentBar-button AB-narrow"
582
+ key={"accent-button-"+index}
583
+ onMouseDown={(e) => e.preventDefault()}
584
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
585
+ onClick={(e) => e.preventDefault()}
586
+ >
587
+ {character}
588
+ </button>
589
+ )
590
+ })}
591
+ <div className="section-label">
592
+ People
593
+ </div>
594
+ { EMOTICONS_PEOPLE.map((character, index) => {
595
+ return (
596
+ <button
597
+ className="AccentBar-button AB-narrow"
598
+ key={"accent-button-"+index}
599
+ onMouseDown={(e) => e.preventDefault()}
600
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
601
+ onClick={(e) => e.preventDefault()}
602
+ >
603
+ {character}
604
+ </button>
605
+ )
606
+ })}
607
+ <div className="section-label">
608
+ Animals
609
+ </div>
610
+ { EMOTICONS_ANIMALS.map((character, index) => {
611
+ return (
612
+ <button
613
+ className="AccentBar-button AB-narrow"
614
+ key={"accent-button-"+index}
615
+ onMouseDown={(e) => e.preventDefault()}
616
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
617
+ onClick={(e) => e.preventDefault()}
618
+ >
619
+ {character}
620
+ </button>
621
+ )
622
+ })}
623
+ <div className="section-label">
624
+ Flowers and food
625
+ </div>
626
+ { EMOTICONS_FOOD.map((character, index) => {
627
+ return (
628
+ <button
629
+ className="AccentBar-button AB-narrow"
630
+ key={"accent-button-"+index}
631
+ onMouseDown={(e) => e.preventDefault()}
632
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
633
+ onClick={(e) => e.preventDefault()}
634
+ >
635
+ {character}
636
+ </button>
637
+ )
638
+ })}
639
+ <div className="section-label">
640
+ Fun
641
+ </div>
642
+ { EMOTICONS_GAMES.map((character, index) => {
643
+ return (
644
+ <button
645
+ className="AccentBar-button AB-narrow"
646
+ key={"accent-button-"+index}
647
+ onMouseDown={(e) => e.preventDefault()}
648
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
649
+ onClick={(e) => e.preventDefault()}
650
+ >
651
+ {character}
652
+ </button>
653
+ )
654
+ })}
655
+ <div className="section-label">
656
+ Transport
657
+ </div>
658
+ { EMOTICONS_TRANSPORT.map((character, index) => {
659
+ return (
660
+ <button
661
+ className="AccentBar-button AB-narrow"
662
+ key={"accent-button-"+index}
663
+ onMouseDown={(e) => e.preventDefault()}
664
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
665
+ onClick={(e) => e.preventDefault()}
666
+ >
667
+ {character}
668
+ </button>
669
+ )
670
+ })}
671
+ <div className="section-label">
672
+ Miscellaneous
673
+ </div>
674
+ { EMOTICONS_MISC.map((character, index) => {
675
+ return (
676
+ <button
677
+ className="AccentBar-button AB-narrow"
678
+ key={"accent-button-"+index}
679
+ onMouseDown={(e) => e.preventDefault()}
680
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
681
+ onClick={(e) => e.preventDefault()}
682
+ >
683
+ {character}
684
+ </button>
685
+ )
686
+ })}
687
+
688
+ </div>
689
+ }
690
+
691
+ { /* More tab */}
692
+ { this.state.selectedTab === "More" &&
693
+ <div className="tabArea">
694
+ <div className="section-label">
695
+ Symbols
696
+ </div>
697
+ { COMMON_SYMBOLS.map((character, index) => {
698
+ return (
699
+ <button
700
+ className="AccentBar-button AB-narrow"
701
+ key={"accent-button-"+index}
702
+ onMouseDown={(e) => e.preventDefault()}
703
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
704
+ onClick={(e) => e.preventDefault()}
705
+ >
706
+ {character}
707
+ </button>
708
+ )
709
+ })}
710
+ <div className="section-label">
711
+ Currency
712
+ </div>
713
+ { CURRENCY_SYMBOLS.map((character, index) => {
714
+ return (
715
+ <button
716
+ className="AccentBar-button AB-narrow"
717
+ key={"accent-button-"+index}
718
+ onMouseDown={(e) => e.preventDefault()}
719
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
720
+ onClick={(e) => e.preventDefault()}
721
+ >
722
+ {character}
723
+ </button>
724
+ )
725
+ })}
726
+ <div className="section-label">
727
+ Numbers
728
+ </div>
729
+ { NUMBER_SYMBOLS.map((character, index) => {
730
+ return (
731
+ <button
732
+ className="AccentBar-button AB-narrow"
733
+ key={"accent-button-"+index}
734
+ onMouseDown={(e) => e.preventDefault()}
735
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
736
+ onClick={(e) => e.preventDefault()}
737
+ >
738
+ {character}
739
+ </button>
740
+ )
741
+ })}
742
+ <div className="section-label">
743
+ Letters
744
+ </div>
745
+ { LATIN_LETTERS.map((character, index) => {
746
+ return (
747
+ <button
748
+ className="AccentBar-button AB-narrow"
749
+ key={"accent-button-"+index}
750
+ onMouseDown={(e) => e.preventDefault()}
751
+ onMouseUp={(e) => this.handleButtonClick(e, character, true)}
752
+ onClick={(e) => e.preventDefault()}
753
+ >
754
+ {character}
755
+ </button>
756
+ )
757
+ })}
758
+
759
+ </div>
760
+ }
761
+
762
+ </div>
763
+ </div>
764
+
765
+ </div>
766
+ }
767
+
768
+ </div>
769
+ )
770
+ }
771
+ }