Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/components/icon.tsx
1503 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
declare var DEBUG: boolean; // comes from static webpack; not defined in other contexts.
7
8
import React from "react";
9
10
import { CSS } from "@cocalc/frontend/app-framework";
11
import useOnFrontend from "./use-on-frontend";
12
13
import {
14
AimOutlined,
15
AlignCenterOutlined,
16
AlignLeftOutlined,
17
AlignRightOutlined,
18
ApiOutlined,
19
AppstoreOutlined,
20
AreaChartOutlined,
21
ArrowDownOutlined,
22
ArrowLeftOutlined,
23
ArrowRightOutlined,
24
ArrowUpOutlined,
25
ArrowsAltOutlined,
26
AudioOutlined,
27
BackwardOutlined,
28
BankOutlined,
29
BellFilled,
30
BellOutlined,
31
BoldOutlined,
32
BookOutlined,
33
BorderOutlined,
34
BugOutlined,
35
BulbOutlined,
36
CalculatorOutlined,
37
CalendarOutlined,
38
CameraOutlined,
39
CaretDownFilled,
40
CaretLeftFilled,
41
CaretRightFilled,
42
CaretUpFilled,
43
CheckCircleOutlined,
44
CheckOutlined,
45
CheckSquareOutlined,
46
ClearOutlined,
47
ClockCircleOutlined,
48
CloseCircleFilled,
49
CloseCircleOutlined,
50
CloseCircleTwoTone,
51
CloseOutlined,
52
CloudDownloadOutlined,
53
CloudFilled,
54
CloudServerOutlined,
55
CloudUploadOutlined,
56
ClusterOutlined,
57
CodeOutlined,
58
CoffeeOutlined,
59
ColumnHeightOutlined,
60
ColumnWidthOutlined,
61
CommentOutlined,
62
CompassOutlined,
63
ContainerOutlined,
64
ControlOutlined,
65
CopyOutlined,
66
CreditCardOutlined,
67
DashboardOutlined,
68
DatabaseFilled,
69
DatabaseOutlined,
70
DeleteOutlined,
71
DeliveredProcedureOutlined,
72
DeploymentUnitOutlined,
73
DesktopOutlined,
74
DoubleLeftOutlined,
75
DoubleRightOutlined,
76
DownCircleOutlined,
77
DownOutlined,
78
DownSquareOutlined,
79
DownloadOutlined,
80
EditFilled,
81
EditOutlined,
82
EllipsisOutlined,
83
ExclamationCircleFilled,
84
ExpandOutlined,
85
ExperimentOutlined,
86
ExportOutlined,
87
EyeInvisibleOutlined,
88
EyeOutlined,
89
FacebookFilled,
90
FacebookOutlined,
91
FieldTimeOutlined,
92
FileImageOutlined,
93
FileOutlined,
94
FilePdfOutlined,
95
FileTextOutlined,
96
FileZipOutlined,
97
FireOutlined,
98
FolderOpenOutlined,
99
FolderOutlined,
100
FontSizeOutlined,
101
ForkOutlined,
102
ForwardOutlined,
103
FrownOutlined,
104
FunctionOutlined,
105
FundProjectionScreenOutlined,
106
GatewayOutlined,
107
GiftOutlined,
108
GiftTwoTone,
109
GithubFilled,
110
GithubOutlined,
111
GlobalOutlined,
112
GoogleOutlined,
113
GroupOutlined,
114
HddOutlined,
115
HighlightOutlined,
116
HistoryOutlined,
117
HomeOutlined,
118
HourglassOutlined,
119
Html5Outlined,
120
IdcardOutlined,
121
InfoCircleOutlined,
122
InfoOutlined,
123
InstagramFilled,
124
InstagramOutlined,
125
ItalicOutlined,
126
KeyOutlined,
127
LaptopOutlined,
128
LayoutOutlined,
129
LeftCircleOutlined,
130
LeftOutlined,
131
LeftSquareFilled,
132
LineChartOutlined,
133
LineHeightOutlined,
134
LinkOutlined,
135
LinkedinFilled,
136
LinkedinOutlined,
137
LoadingOutlined,
138
LockFilled,
139
LockOutlined,
140
LoginOutlined,
141
MailOutlined,
142
MedicineBoxOutlined,
143
MehOutlined,
144
MenuOutlined,
145
MergeCellsOutlined,
146
MinusCircleOutlined,
147
MinusOutlined,
148
MinusSquareOutlined,
149
OrderedListOutlined,
150
PauseCircleOutlined,
151
PercentageOutlined,
152
PicCenterOutlined,
153
PlayCircleFilled,
154
PlayCircleOutlined,
155
PlaySquareOutlined,
156
PlusCircleFilled,
157
PlusCircleOutlined,
158
PlusOutlined,
159
PlusSquareOutlined,
160
PoweroffOutlined,
161
PrinterOutlined,
162
ProjectOutlined,
163
QuestionCircleOutlined,
164
RedoOutlined,
165
ReloadOutlined,
166
RetweetOutlined,
167
RightCircleFilled,
168
RightCircleOutlined,
169
RightOutlined,
170
RightSquareFilled,
171
RiseOutlined,
172
RobotOutlined,
173
RocketOutlined,
174
SaveOutlined,
175
ScissorOutlined,
176
SearchOutlined,
177
SelectOutlined,
178
SendOutlined,
179
SettingOutlined,
180
ShareAltOutlined,
181
ShoppingCartOutlined,
182
ShrinkOutlined,
183
SignatureOutlined,
184
SlidersOutlined,
185
SmileOutlined,
186
SolutionOutlined,
187
SoundOutlined,
188
StarFilled,
189
StarOutlined,
190
StepBackwardOutlined,
191
StepForwardOutlined,
192
StopFilled,
193
StopOutlined,
194
StrikethroughOutlined,
195
SwapOutlined,
196
SyncOutlined,
197
TableOutlined,
198
TagFilled,
199
TagOutlined,
200
TagTwoTone,
201
TagsFilled,
202
TagsOutlined,
203
TagsTwoTone,
204
TeamOutlined,
205
ThunderboltOutlined,
206
ToTopOutlined,
207
ToolOutlined,
208
TranslationOutlined,
209
UnderlineOutlined,
210
UndoOutlined,
211
UnlockFilled,
212
UnorderedListOutlined,
213
UpCircleOutlined,
214
UpOutlined,
215
UpSquareOutlined,
216
UploadOutlined,
217
UserAddOutlined,
218
UserDeleteOutlined,
219
UserOutlined,
220
UsergroupAddOutlined,
221
VerticalAlignBottomOutlined,
222
VerticalAlignMiddleOutlined,
223
VerticalLeftOutlined,
224
VerticalRightOutlined,
225
VideoCameraOutlined,
226
WalletOutlined,
227
WarningOutlined,
228
WifiOutlined,
229
XOutlined,
230
YoutubeFilled,
231
YoutubeOutlined,
232
} from "@ant-design/icons";
233
234
// Unfortunately -- "error TS7056: The inferred type of this node exceeds the maximum length the
235
// compiler will serialize. An explicit type annotation is needed."
236
const IconSpec = {
237
"address-card": IdcardOutlined,
238
aim: AimOutlined,
239
"align-left": AlignLeftOutlined,
240
"align-center": AlignCenterOutlined,
241
"align-justify": { IconFont: "align-justify" },
242
"align-right": AlignRightOutlined,
243
"angle-double-left": DoubleLeftOutlined,
244
"angle-double-right": DoubleRightOutlined,
245
"angle-down": DownOutlined,
246
"angle-right": RightOutlined,
247
"arrow-circle-o-left": { IconFont: "arrowcircleoleft" },
248
"arrow-circle-down": DownCircleOutlined,
249
"arrow-circle-up": UpCircleOutlined,
250
"arrow-down": ArrowDownOutlined,
251
"arrow-left": ArrowLeftOutlined,
252
"arrow-right": ArrowRightOutlined,
253
"arrow-up": ArrowUpOutlined,
254
atom: { IconFont: "Atom" },
255
api: ApiOutlined,
256
audio: AudioOutlined,
257
aws: { IconFont: "aws" },
258
backward: BackwardOutlined,
259
"battery-empty": { IconFont: "battery-empty" },
260
"battery-quarter": { IconFont: "battery-quarter" },
261
"battery-half": { IconFont: "battery-half" },
262
"battery-three-quarters": { IconFont: "battery-three-quarters" },
263
"battery-full": { IconFont: "battery-full" },
264
ban: StopOutlined,
265
bank: BankOutlined,
266
bars: { IconFont: "bars" },
267
bell: BellFilled,
268
"bell-o": BellOutlined,
269
blog: { IconFont: "blog" },
270
bold: BoldOutlined,
271
bolt: ThunderboltOutlined,
272
book: BookOutlined,
273
briefcase: { IconFont: "briefcase" },
274
brush: { IconFont: "brush" },
275
bullhorn: { IconFont: "bullhorn" },
276
bug: BugOutlined,
277
calculator: CalculatorOutlined,
278
calendar: CalendarOutlined,
279
"calendar-week": { IconFont: "calendar-week" },
280
"calendar-check": { IconFont: "calendar-check" },
281
"calendar-times": { IconFont: "calendar-times" },
282
camera: CameraOutlined,
283
"caret-down": CaretDownFilled,
284
"caret-left": CaretLeftFilled,
285
"caret-right": CaretRightFilled,
286
"caret-up": CaretUpFilled,
287
"caret-square-left": LeftSquareFilled,
288
"caret-square-right": RightSquareFilled,
289
"cc-discover": { IconFont: "cc-discover" },
290
"cc-mastercard": { IconFont: "cc-mastercard" },
291
"cc-visa": { IconFont: "cc-visa" },
292
"cc-stripe": { IconFont: "cc-stripe" },
293
areaChart: AreaChartOutlined,
294
check: CheckOutlined,
295
"check-circle": CheckCircleOutlined,
296
"check-square": CheckSquareOutlined,
297
"check-square-o": CheckSquareOutlined,
298
"chevron-down": DownOutlined,
299
"chevron-left": LeftOutlined,
300
"chevron-right": RightOutlined,
301
"chevron-circle-right": RightCircleFilled,
302
"chevron-up": UpOutlined,
303
circle: { IconFont: "circle" },
304
"circle-notch": LoadingOutlined,
305
clipboard: { IconFont: "clipboard" },
306
"clipboard-check": { IconFont: "clipboard-check" },
307
clock: ClockCircleOutlined,
308
"close-circle-two-tone": CloseCircleTwoTone,
309
"close-circle-filled": CloseCircleFilled,
310
clone: { IconFont: "clone" },
311
cloud: CloudFilled,
312
"cloud-dev": { IconFont: "cloud-dev" },
313
"cloud-download": CloudDownloadOutlined,
314
"cloud-download-alt": CloudDownloadOutlined,
315
"cloud-upload": CloudUploadOutlined,
316
"cocalc-ring": { IconFont: "cocalc-ring" },
317
code: { IconFont: "code" },
318
"code-outlined": CodeOutlined,
319
CodeOutlined,
320
coffee: CoffeeOutlined,
321
cog: ControlOutlined,
322
cogs: ControlOutlined,
323
colors: { IconFont: "colors" },
324
ColumnHeightOutlined,
325
ColumnWidthOutlined,
326
comment: CommentOutlined,
327
comments: CommentOutlined,
328
compass: CompassOutlined,
329
compress: ShrinkOutlined,
330
container: ContainerOutlined,
331
copy: CopyOutlined,
332
"credit-card": CreditCardOutlined,
333
csv: { IconFont: "csv" },
334
cube: { IconFont: "cube" },
335
cut: ScissorOutlined,
336
dashboard: DashboardOutlined,
337
database: DatabaseOutlined,
338
"database-filled": DatabaseFilled,
339
"deployment-unit": DeploymentUnitOutlined,
340
dedicated: DatabaseOutlined, // icon for "dedicated resources", looks like a server rack
341
desktop: DesktopOutlined,
342
"delivered-procedure-outlined": DeliveredProcedureOutlined,
343
digitalocean: { IconFont: "digitalocean" },
344
discord: { IconFont: "discord" },
345
"disk-drive": { IconFont: "disk-drive" },
346
"disk-round": { IconFont: "disk-round" },
347
"disk-snapshot": { IconFont: "disk-snapshot" },
348
dns: { IconFont: "dns" },
349
docker: { IconFont: "docker" },
350
download: DownloadOutlined,
351
"dot-circle": { IconFont: "dot-circle" },
352
edit: EditOutlined,
353
"edit-filled": EditFilled,
354
eraser: { IconFont: "Eraser-Tool" },
355
ellipsis: EllipsisOutlined,
356
envelope: { IconFont: "envelope" },
357
exchange: { IconFont: "exchange" },
358
"exclamation-circle": ExclamationCircleFilled,
359
"exclamation-triangle": WarningOutlined,
360
expand: ExpandOutlined,
361
"expand-arrows": ArrowsAltOutlined,
362
experiment: ExperimentOutlined,
363
"external-link": { IconFont: "external-link-alt" },
364
eye: EyeOutlined,
365
"eye-slash": EyeInvisibleOutlined,
366
"facebook-filled": FacebookFilled,
367
facebook: FacebookOutlined,
368
file: FileOutlined,
369
"file-archive": FileZipOutlined,
370
"file-alt": FileTextOutlined,
371
"file-code": FileTextOutlined,
372
"file-image": FileImageOutlined,
373
"file-pdf": FilePdfOutlined,
374
"file-zip": FileZipOutlined,
375
files: CopyOutlined,
376
"file-export": ExportOutlined,
377
fire: FireOutlined,
378
firefox: { IconFont: "firefox" },
379
flash: ThunderboltOutlined,
380
"flow-chart": { IconFont: "flow-chart" },
381
folder: FolderOutlined,
382
"folder-open": FolderOpenOutlined,
383
font: { IconFont: "font" },
384
"font-size": FontSizeOutlined,
385
forward: ForwardOutlined,
386
frame: { IconFont: "frame" },
387
frown: FrownOutlined,
388
fx: FunctionOutlined,
389
slides: FundProjectionScreenOutlined,
390
"project-outlined": ProjectOutlined,
391
"gateway-outlined": GatewayOutlined,
392
gavel: { IconFont: "gavel" },
393
gears: ControlOutlined,
394
gear: ControlOutlined,
395
gift: GiftOutlined,
396
gift2: GiftTwoTone,
397
"github-filled": GithubFilled,
398
github: GithubOutlined,
399
git: { IconFont: "git1" },
400
"git-square": { IconFont: "git-square" },
401
global: GlobalOutlined,
402
emacs: { IconFont: "gnuemacs" },
403
google: GoogleOutlined,
404
googlecloud: { IconFont: "googlecloud" },
405
"graduation-cap": { IconFont: "graduation" },
406
graph: { IconFont: "graph" },
407
grass: { IconFont: "grass" },
408
group: { IconFont: "group" },
409
"group-outlined": GroupOutlined,
410
gpu: { IconFont: "gpu" },
411
hand: { IconFont: "hand" },
412
"hand-stop": PoweroffOutlined,
413
header: { IconFont: "header" },
414
heart: { IconFont: "heart" },
415
hdd: HddOutlined,
416
highlighter: HighlightOutlined,
417
history: HistoryOutlined,
418
home: HomeOutlined,
419
"horizontal-split": { IconFont: "horizontal-split" },
420
"hourglass-half": HourglassOutlined,
421
html5: Html5Outlined,
422
image: { IconFont: "image" },
423
icons: { IconFont: "icons" },
424
"info-circle": InfoCircleOutlined,
425
indent: { IconFont: "indent" },
426
info: InfoOutlined,
427
inkscape: { IconFont: "inkscape" },
428
"instagram-filled": InstagramFilled,
429
instagram: InstagramOutlined,
430
ipynb: { IconFont: "ipynb" },
431
italic: ItalicOutlined,
432
"js-square": { IconFont: "js-square" },
433
julia: { IconFont: "julia" },
434
jupyter: { IconFont: "ipynb" },
435
key: KeyOutlined,
436
keyboard: { IconFont: "keyboard" },
437
laptop: LaptopOutlined,
438
layout: LayoutOutlined,
439
"skull-crossbones": { IconFont: "leave_conference" },
440
libreoffice: { IconFont: "libreoffice" },
441
"life-ring": { IconFont: "life-ring" },
442
"life-saver": { IconFont: "life-ring" },
443
lightbulb: BulbOutlined,
444
"line-chart": LineChartOutlined,
445
link: LinkOutlined,
446
"linkedin-filled": LinkedinFilled,
447
linkedin: LinkedinOutlined,
448
linux: { IconFont: "linux" },
449
list: UnorderedListOutlined,
450
"list-ul": UnorderedListOutlined,
451
"list-alt": UnorderedListOutlined,
452
"list-ol": OrderedListOutlined,
453
"lock-open": UnlockFilled,
454
lock: LockFilled,
455
"lock-outlined": LockOutlined,
456
magic: { IconFont: "magic" },
457
mail: MailOutlined,
458
map: { IconFont: "map" },
459
markdown: { IconFont: "markdown" },
460
mask: { IconFont: "mask" },
461
maple: { IconFont: "maple" },
462
mathematica: { IconFont: "mathematica" },
463
matlab: { IconFont: "matlab" },
464
medkit: MedicineBoxOutlined,
465
"menu-outlined": MenuOutlined,
466
meh: MehOutlined,
467
microchip: { IconFont: "microchip" },
468
microsoft: { IconFont: "microsoft" },
469
"minus-circle": MinusCircleOutlined,
470
"minus-square": MinusSquareOutlined,
471
money: CreditCardOutlined,
472
"money-check": { IconFont: "money-check" },
473
mousepointer: { IconFont: "mousepointer" },
474
move: { IconFont: "move" },
475
arrows: { IconFont: "move" }, // fa-arrows is used by the bqplot custom widget
476
network: { IconFont: "network" },
477
"network-server": { IconFont: "network-server" },
478
"network-wired": ClusterOutlined,
479
"node-js": { IconFont: "node-js" },
480
note: { IconFont: "note-text" },
481
nvidia: { IconFont: "nvidia" },
482
octave: { IconFont: "octave" },
483
overview: AppstoreOutlined,
484
outdent: { IconFont: "outdent" },
485
pause: PauseCircleOutlined,
486
"paper-plane": SendOutlined,
487
paste: { IconFont: "paste" },
488
"pic-centered": PicCenterOutlined,
489
pen: { IconFont: "pen" },
490
pencil: EditOutlined,
491
"pencil-alt": EditOutlined,
492
percentage: PercentageOutlined,
493
play: PlayCircleOutlined,
494
"play-circle": PlayCircleFilled,
495
"play-square": PlaySquareOutlined,
496
plus: PlusOutlined,
497
minus: MinusOutlined,
498
"plus-circle": PlusCircleOutlined,
499
"plus-circle-o": PlusCircleOutlined,
500
"plus-circle-filled": PlusCircleFilled,
501
"plus-one": { IconFont: "plus-one" },
502
"plus-square": PlusSquareOutlined,
503
"plus-square-o": PlusSquareOutlined,
504
PoweroffOutlined,
505
print: PrinterOutlined,
506
python: { IconFont: "python" },
507
pytorch: { IconFont: "pytorch" },
508
qgis: { IconFont: "qgis" },
509
"question-circle": QuestionCircleOutlined,
510
"quote-left": { IconFont: "quote-left" },
511
r: { IconFont: "r" },
512
racket: { IconFont: "racket" },
513
redo: RedoOutlined,
514
refresh: RedoOutlined,
515
reload: ReloadOutlined,
516
remove: CloseOutlined,
517
repeat: RedoOutlined,
518
replace: { IconFont: "find-replace" },
519
reply: { IconFont: "reply" },
520
retweet: RetweetOutlined,
521
robot: RobotOutlined,
522
rocket: RocketOutlined,
523
run: { IconFont: "run" },
524
sagemath: { IconFont: "sagemath" },
525
"sagemath-bold": { IconFont: "sagemath-bold" },
526
"sagemath-file": { IconFont: "sagemath-file" },
527
save: SaveOutlined,
528
scheme: { IconFont: "scheme" },
529
scissors: ScissorOutlined,
530
search: SearchOutlined,
531
"search-minus": MinusOutlined, // we actually use this for zoom
532
"search-plus": PlusOutlined,
533
"select-outlined": SelectOutlined,
534
settings: SettingOutlined,
535
server: CloudServerOutlined,
536
servers: { IconFont: "servers" },
537
"sign-in": LoginOutlined,
538
"sign-out-alt": LoginOutlined, // Yes, since the logout one breaks darkreader, weirdly! they both look reasonable.
539
sitemap: ClusterOutlined,
540
"share-square": ShareAltOutlined,
541
"shopping-cart": ShoppingCartOutlined,
542
sliders: SlidersOutlined,
543
smile: SmileOutlined,
544
"sort-amount-up": { IconFont: "sort-amount-up" },
545
spinner: { IconFont: "cocalc-ring" },
546
square: BorderOutlined,
547
solution: SolutionOutlined,
548
"square-o": BorderOutlined,
549
"square-root-alt": { IconFont: "square-root-alt" },
550
"star-filled": StarFilled,
551
star: StarOutlined,
552
"step-backward": StepBackwardOutlined,
553
"step-forward": StepForwardOutlined,
554
stop: { IconFont: "stop" }, // the ant-design "stop" looks weird.
555
"stop-filled": StopFilled,
556
stopwatch: FieldTimeOutlined,
557
store: { IconFont: "store" },
558
strikethrough: StrikethroughOutlined,
559
subscript: { IconFont: "subscript" },
560
sun: { IconFont: "sun" },
561
superscript: { IconFont: "superscript" },
562
support: { IconFont: "life-ring" },
563
sync: { IconFont: "sync" },
564
"sync-alt": SyncOutlined,
565
tab: { IconFont: "tab" },
566
table: TableOutlined,
567
"tachometer-alt": DashboardOutlined,
568
tasks: { IconFont: "tasks" },
569
"tag-outlined": TagOutlined,
570
"tags-outlined": TagsOutlined,
571
"tag-filled": TagFilled,
572
"tags-filled": TagsFilled,
573
"tag-two-tone": TagTwoTone,
574
"tags-two-tone": TagsTwoTone,
575
"team-outlined": TeamOutlined,
576
tensorflow: { IconFont: "tensorflow" },
577
terminal: CodeOutlined,
578
tex: { IconFont: "tex" },
579
text: { IconFont: "text" },
580
text1: { IconFont: "text1" },
581
"tex-file": { IconFont: "tex-file" },
582
"text-height": LineHeightOutlined,
583
times: CloseOutlined,
584
"times-circle": CloseCircleOutlined,
585
"times-rectangle": { IconFont: "times-rectangle" },
586
"thumbs-down": { IconFont: "thumbs-down" },
587
"thumbs-up": { IconFont: "thumbs-up" },
588
"toggle-off": { IconFont: "toggle-off" },
589
"toggle-on": { IconFont: "toggle-on" },
590
tool: ToolOutlined,
591
trash: DeleteOutlined,
592
"twitter-filled": XOutlined,
593
twitter: XOutlined,
594
ubuntu: { IconFont: "ubuntu" },
595
underline: UnderlineOutlined,
596
undo: UndoOutlined,
597
ungroup: { IconFont: "ungroup" },
598
"signature-outlined": SignatureOutlined,
599
swap: SwapOutlined,
600
unlink: { IconFont: "unlink" },
601
upload: UploadOutlined,
602
user: UserOutlined,
603
"user-secret": { IconFont: "user-secret" },
604
UserAddOutlined,
605
"user-check": { IconFont: "user-check" },
606
"user-plus": UsergroupAddOutlined,
607
"user-slash": { IconFont: "user-slash" },
608
"user-times": UserDeleteOutlined,
609
users: UsergroupAddOutlined,
610
"vertical-split": { IconFont: "vertical-split" },
611
"vertical-right-outlined": VerticalRightOutlined,
612
"video-camera": VideoCameraOutlined,
613
"vertical-align-middle": VerticalAlignMiddleOutlined,
614
"vertical-align-bottom": VerticalAlignBottomOutlined,
615
"vertical-left-outlined": VerticalLeftOutlined,
616
vim: { IconFont: "vim" },
617
vscode: { IconFont: "vscode" },
618
wallet: WalletOutlined,
619
warning: WarningOutlined,
620
wifi: WifiOutlined,
621
"window-maximize": { IconFont: "window-maximize" },
622
"window-restore": DesktopOutlined, // we only use for x11 and this has big X.
623
wrench: { IconFont: "wrench" },
624
youtube: YoutubeOutlined,
625
"youtube-filled": YoutubeFilled,
626
"left-circle-o": LeftCircleOutlined,
627
"right-circle-o": RightCircleOutlined,
628
"down-circle-o": DownCircleOutlined,
629
"translation-outlined": TranslationOutlined,
630
"clean-outlined": ClearOutlined,
631
"sound-outlined": SoundOutlined,
632
"rise-outlined": RiseOutlined,
633
"up-square-outlined": UpSquareOutlined,
634
"down-square-outlined": DownSquareOutlined,
635
"merge-cells-outlined": MergeCellsOutlined,
636
"fork-outlined": ForkOutlined,
637
"to-top-outlined": ToTopOutlined,
638
} as const;
639
640
// Icon Fonts coming from https://www.iconfont.cn/?lang=en-us
641
import { createFromIconfontCN } from "@ant-design/icons";
642
export let IconFont: any = undefined;
643
try {
644
if (typeof window != "undefined") {
645
// obviously won't work if window is undefined based on looking at the code...
646
// This loads a bunch of svg elements of the form <svg id="icon-<name>"... into the DOM.
647
// The antd Icon code then duplicates these via the <use> html tag
648
// (https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use)
649
require("./iconfont.cn");
650
// note -- we do NOT pass scriptUrl in, as in the docs! Why? Because
651
// we want everything bundled up into webpack, rather than having to pull
652
// from some random place, which just causes confusion with releases
653
// and caching. Fortunately, just evaluating the js from iconfont, then
654
// running createFromIconfontCN with no arguments does work, as I deduced
655
// by reading the code, then trying this.
656
// https://github.com/ant-design/ant-design-icons/blob/5be2afd296636ab4cfec5d3a2793d6cd41b1789b/packages/icons-vue/src/components/IconFont.tsx
657
658
IconFont = createFromIconfontCN();
659
660
// It would be easy to screw up and put an entry like
661
// "arrow-circle-o-left": { IconFont: "arrowcircleoleft" }
662
// in IconSpec, but forget to actually include "arrowcircleoleft" in
663
// iconfont.cn, or -- just as bad -- make a typo or put the wrong name in.
664
// So we double check that all iconfonts are actually defined here:
665
if (typeof DEBUG != "undefined" && DEBUG) {
666
setTimeout(() => {
667
// only do this during dev to save time.
668
for (const name in IconSpec) {
669
const spec = IconSpec[name];
670
const x = spec?.IconFont;
671
if (x != null) {
672
const id = `icon-${x}`;
673
if (document.getElementById(id) == null) {
674
console.error(
675
`ERROR -- the IconFont ${x} is not in components/iconfont.cn! Fix this or the icon ${name} will be broken.`,
676
);
677
}
678
}
679
}
680
}, 5000);
681
}
682
}
683
} catch (err) {
684
// Might as well have option for a graceful fallback, e.g., when
685
// used from node.js...
686
if (!process.env.COCALC_TEST_MODE) {
687
console.log(`IconFont not available -- ${err}`);
688
}
689
}
690
691
// This used to exceed TypeScript limits, but apparently it is ok now…
692
export type IconName = keyof typeof IconSpec;
693
export const IconName = undefined; // Javascript needs this, though we are only using IconName for the type
694
695
// Typeguard so can tell if a string is name of an icon and also
696
// make typescript happy.
697
export function isIconName(name?: unknown): name is IconName {
698
if (name == null) return false;
699
if (typeof name !== "string") return false;
700
return IconSpec[name] != null;
701
}
702
703
export const iconNames: IconName[] = Object.keys(IconSpec) as any;
704
705
export type IconRotation = "45" | "90" | "135" | "180" | "225" | "270" | "315";
706
707
interface Props {
708
name?: IconName;
709
unicode?: number; // (optional) set a hex 16 bit charcode to render a unicode char, e.g. 0x2620
710
className?: string;
711
size?: "lg" | "2x" | "3x" | "4x" | "5x";
712
rotate?: IconRotation;
713
flip?: "horizontal" | "vertical";
714
spin?: boolean;
715
pulse?: boolean;
716
stack?: "1x" | "2x";
717
inverse?: boolean;
718
style?: CSS;
719
onClick?: (event?: React.MouseEvent) => void; // https://fettblog.eu/typescript-react/events/
720
onMouseOver?: () => void;
721
onMouseOut?: () => void;
722
onMouseEnter?: () => void;
723
onMouseLeave?: () => void;
724
}
725
726
const UNICODE_STYLE = {
727
fontSize: "120%",
728
fontWeight: "bold",
729
lineHeight: "1",
730
verticalAlign: "middle",
731
} as React.CSSProperties;
732
733
const missing: any = {};
734
// Converted from https://github.com/andreypopp/react-fa
735
736
export const Icon: React.FC<Props> = (props: Props) => {
737
// IMPORTANT: This hook is needed for next.js to support server side rendering.
738
// Otherwise, at least with next 13, it crashes when rendering icons.
739
const onFrontend = useOnFrontend();
740
if (!onFrontend) return null;
741
742
if (props.unicode != null) {
743
return (
744
<span style={{ ...UNICODE_STYLE, ...props.style }}>
745
{String.fromCharCode(props.unicode!)}
746
</span>
747
);
748
}
749
750
let name: IconName = props.name ?? "square";
751
let C;
752
C = IconSpec[name];
753
if (C == null && name.endsWith("-o")) {
754
// should be impossible because of typescript...
755
// try without -o
756
C = IconSpec[name.slice(0, name.length - 2)];
757
}
758
if (C != null) {
759
if (typeof C.IconFont == "string") {
760
// @ts-ignore
761
if (IconFont == null) {
762
return <span>(IconFonts not available)</span>;
763
}
764
return <IconFont type={"icon-" + C.IconFont} {...props} alt={name} />;
765
}
766
return <C {...props} alt={name} />;
767
}
768
769
// this is when the icon is broken.
770
if (typeof DEBUG != "undefined" && DEBUG) {
771
if (missing[props.name ?? ""] == null) {
772
missing[props.name ?? ""] = true;
773
console.warn(
774
`Icon "${props.name}" is not defined -- fix this in components/icon.tsx.`,
775
);
776
}
777
// make it hopefully clear to devs that this icon is broken
778
return (
779
<span
780
style={{ background: "red", color: "white" }}
781
className="blink"
782
title={`Icon "${props.name}" is not defined -- fix this in components/icon.tsx.`}
783
>
784
{/* @ts-ignore */}
785
<BugOutlined {...props} alt={name} />
786
</span>
787
);
788
} else {
789
// In production, just show a very generic icon so the user
790
// doesn't realize we messed up.
791
// @ts-ignore
792
return <BorderOutlined {...props} alt={name} />;
793
}
794
};
795
796
// TOOD move this to a shared lib, which can import the IconName type
797
export const PAYASYOUGO_ICON: IconName = "compass";
798
799