@swiftbrowser/web 0.1.0 → 0.3.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.
- package/README.md +141 -63
- package/app/index.html +21 -10
- package/node/dist/node/apps.d.ts +16 -0
- package/node/dist/node/apps.d.ts.map +1 -1
- package/node/dist/node/apps.js +9 -0
- package/node/dist/node/apps.js.map +1 -1
- package/node/dist/node/config.d.ts +14 -1
- package/node/dist/node/config.d.ts.map +1 -1
- package/node/dist/node/config.js +20 -3
- package/node/dist/node/config.js.map +1 -1
- package/node/dist/node/examples.d.ts +2 -1
- package/node/dist/node/examples.d.ts.map +1 -1
- package/node/dist/node/examples.js +12 -2
- package/node/dist/node/examples.js.map +1 -1
- package/node/dist/plugins/app-manifests.d.ts +4 -1
- package/node/dist/plugins/app-manifests.d.ts.map +1 -1
- package/node/dist/plugins/app-manifests.js +3 -2
- package/node/dist/plugins/app-manifests.js.map +1 -1
- package/node/dist/plugins/asset-catalogs.d.ts +15 -3
- package/node/dist/plugins/asset-catalogs.d.ts.map +1 -1
- package/node/dist/plugins/asset-catalogs.js +111 -13
- package/node/dist/plugins/asset-catalogs.js.map +1 -1
- package/node/dist/plugins/included-sites.d.ts +26 -0
- package/node/dist/plugins/included-sites.d.ts.map +1 -0
- package/node/dist/plugins/included-sites.js +70 -0
- package/node/dist/plugins/included-sites.js.map +1 -0
- package/node/dist/plugins/pdfImages.d.ts +27 -0
- package/node/dist/plugins/pdfImages.d.ts.map +1 -0
- package/node/dist/plugins/pdfImages.js +145 -0
- package/node/dist/plugins/pdfImages.js.map +1 -0
- package/node/dist/plugins/swift-wasm.d.ts +19 -1
- package/node/dist/plugins/swift-wasm.d.ts.map +1 -1
- package/node/dist/plugins/swift-wasm.js +45 -7
- package/node/dist/plugins/swift-wasm.js.map +1 -1
- package/node/dist/plugins/symbolTemplates.d.ts +22 -0
- package/node/dist/plugins/symbolTemplates.d.ts.map +1 -0
- package/node/dist/plugins/symbolTemplates.js +83 -0
- package/node/dist/plugins/symbolTemplates.js.map +1 -0
- package/package.json +4 -2
- package/plugins/app-manifests.ts +3 -2
- package/plugins/asset-catalogs.ts +119 -14
- package/plugins/included-sites.ts +74 -0
- package/plugins/pdfImages.ts +163 -0
- package/plugins/swift-wasm.ts +52 -6
- package/plugins/symbolTemplates.ts +88 -0
- package/public/_headers +7 -0
- package/public/app/oauth-callback.html +62 -0
- package/src/animation.ts +235 -8
- package/src/appFiles.ts +201 -0
- package/src/base64.ts +43 -0
- package/src/bitmapPlan.ts +143 -0
- package/src/bitmapStore.ts +206 -0
- package/src/bitmapWorker.ts +41 -0
- package/src/bitmapWorkerProtocol.ts +15 -0
- package/src/bitmaps.ts +283 -0
- package/src/blockedHosts.ts +29 -0
- package/src/canvasDrawing.ts +361 -0
- package/src/chartDom.ts +2 -2
- package/src/chromeColor.ts +179 -0
- package/src/clipboard.ts +78 -0
- package/src/colorMultiply.ts +93 -0
- package/src/colorPicker.ts +44 -0
- package/src/corsProxy.ts +45 -0
- package/src/gaugeRing.ts +74 -0
- package/src/gif.ts +297 -0
- package/src/hostRequests.ts +426 -0
- package/src/imageOps.ts +592 -0
- package/src/interaction.ts +68 -3
- package/src/landing.ts +2 -2
- package/src/largeTitle.ts +79 -0
- package/src/layout/chart.ts +9 -3
- package/src/layout/engine.ts +681 -174
- package/src/layout/index.ts +3 -1
- package/src/layout/text.ts +217 -1
- package/src/layout/types.ts +31 -0
- package/src/layout/typography.ts +24 -7
- package/src/layout/video.ts +24 -0
- package/src/layoutDom.ts +66 -6
- package/src/main.ts +127 -4
- package/src/media.ts +132 -0
- package/src/mock.ts +4 -3
- package/src/notifications.ts +109 -0
- package/src/pathShape.ts +156 -0
- package/src/protocol.ts +782 -13
- package/src/renderer.ts +603 -44
- package/src/richText.ts +65 -0
- package/src/scanner.ts +234 -0
- package/src/scrollTo.ts +123 -0
- package/src/styles.css +521 -100
- package/src/styles.ts +61 -0
- package/src/swiftData.ts +128 -0
- package/src/symbols.ts +658 -28
- package/src/translation.ts +126 -0
- package/src/video.ts +299 -0
- package/src/vite-env.d.ts +6 -0
- package/src/wasm.ts +227 -32
- package/src/webAuth.ts +267 -0
- package/src/webSocket.ts +148 -0
- package/src/zoneinfo.ts +269 -0
package/src/symbols.ts
CHANGED
|
@@ -14,9 +14,18 @@
|
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
16
|
Accessibility,
|
|
17
|
+
Activity,
|
|
18
|
+
Airplay,
|
|
19
|
+
ALargeSmall,
|
|
17
20
|
AlarmClock,
|
|
18
21
|
Archive,
|
|
22
|
+
ArrowBigDown,
|
|
23
|
+
ArrowBigLeft,
|
|
24
|
+
ArrowBigRight,
|
|
25
|
+
ArrowBigUp,
|
|
19
26
|
ArrowDown,
|
|
27
|
+
ArrowDownLeft,
|
|
28
|
+
ArrowDownRight,
|
|
20
29
|
ArrowDownToLine,
|
|
21
30
|
ArrowLeft,
|
|
22
31
|
ArrowLeftRight,
|
|
@@ -24,35 +33,64 @@ import {
|
|
|
24
33
|
ArrowUp,
|
|
25
34
|
ArrowUpDown,
|
|
26
35
|
ArrowUpFromLine,
|
|
36
|
+
ArrowUpLeft,
|
|
27
37
|
ArrowUpRight,
|
|
28
38
|
AtSign,
|
|
39
|
+
AudioWaveform,
|
|
40
|
+
Award,
|
|
41
|
+
BadgeCheck,
|
|
42
|
+
BadgeQuestionMark,
|
|
43
|
+
Ban,
|
|
44
|
+
Bandage,
|
|
45
|
+
Banknote,
|
|
46
|
+
Barcode,
|
|
29
47
|
Battery,
|
|
48
|
+
BatteryFull,
|
|
49
|
+
BatteryLow,
|
|
50
|
+
BatteryMedium,
|
|
51
|
+
BatteryWarning,
|
|
52
|
+
BedDouble,
|
|
30
53
|
Bell,
|
|
54
|
+
BellDot,
|
|
55
|
+
BellOff,
|
|
31
56
|
Bike,
|
|
57
|
+
Bird,
|
|
58
|
+
Bitcoin,
|
|
32
59
|
Bluetooth,
|
|
60
|
+
Bold,
|
|
61
|
+
CaseSensitive,
|
|
33
62
|
Book,
|
|
34
|
-
BookOpen,
|
|
35
63
|
Bookmark,
|
|
64
|
+
BookOpen,
|
|
65
|
+
Brain,
|
|
36
66
|
Briefcase,
|
|
67
|
+
BriefcaseMedical,
|
|
37
68
|
Bug,
|
|
38
69
|
Building,
|
|
39
70
|
Bus,
|
|
71
|
+
Cake,
|
|
40
72
|
Calendar,
|
|
73
|
+
CalendarClock,
|
|
74
|
+
CalendarPlus,
|
|
75
|
+
CalendarX,
|
|
41
76
|
Camera,
|
|
42
77
|
Car,
|
|
78
|
+
Carrot,
|
|
79
|
+
Cat,
|
|
43
80
|
ChartBar,
|
|
81
|
+
ChartColumn,
|
|
44
82
|
ChartLine,
|
|
45
83
|
ChartPie,
|
|
46
84
|
Check,
|
|
47
85
|
ChevronDown,
|
|
48
86
|
ChevronLeft,
|
|
49
87
|
ChevronRight,
|
|
50
|
-
ChevronUp,
|
|
51
88
|
ChevronsDown,
|
|
52
89
|
ChevronsLeft,
|
|
53
90
|
ChevronsRight,
|
|
54
91
|
ChevronsUp,
|
|
55
92
|
ChevronsUpDown,
|
|
93
|
+
ChevronUp,
|
|
56
94
|
Circle,
|
|
57
95
|
CircleAlert,
|
|
58
96
|
CircleArrowDown,
|
|
@@ -60,152 +98,326 @@ import {
|
|
|
60
98
|
CircleArrowRight,
|
|
61
99
|
CircleArrowUp,
|
|
62
100
|
CircleCheck,
|
|
101
|
+
CircleDollarSign,
|
|
63
102
|
CircleDot,
|
|
64
103
|
CircleEllipsis,
|
|
65
104
|
CircleMinus,
|
|
66
105
|
CirclePause,
|
|
67
106
|
CirclePlay,
|
|
68
107
|
CirclePlus,
|
|
69
|
-
CircleStop,
|
|
70
108
|
CircleQuestionMark,
|
|
109
|
+
CircleStop,
|
|
71
110
|
CircleUser,
|
|
72
111
|
CircleX,
|
|
112
|
+
Clapperboard,
|
|
73
113
|
Clipboard,
|
|
114
|
+
ClipboardList,
|
|
74
115
|
Clock,
|
|
116
|
+
ClockCheck,
|
|
75
117
|
Cloud,
|
|
118
|
+
CloudDownload,
|
|
119
|
+
CloudDrizzle,
|
|
120
|
+
CloudFog,
|
|
121
|
+
CloudHail,
|
|
76
122
|
CloudLightning,
|
|
77
123
|
CloudMoon,
|
|
78
124
|
CloudRain,
|
|
125
|
+
CloudRainWind,
|
|
79
126
|
CloudSnow,
|
|
80
127
|
CloudSun,
|
|
128
|
+
CloudUpload,
|
|
81
129
|
Code,
|
|
130
|
+
Coffee,
|
|
82
131
|
Cog,
|
|
132
|
+
Columns2,
|
|
133
|
+
Command,
|
|
83
134
|
Compass,
|
|
135
|
+
Contact,
|
|
84
136
|
Copy,
|
|
137
|
+
CornerDownLeft,
|
|
85
138
|
CreditCard,
|
|
139
|
+
Crop,
|
|
140
|
+
Cross,
|
|
86
141
|
Crown,
|
|
142
|
+
Database,
|
|
143
|
+
Delete,
|
|
144
|
+
Diamond,
|
|
145
|
+
Dices,
|
|
146
|
+
Dog,
|
|
147
|
+
DollarSign,
|
|
87
148
|
Download,
|
|
88
149
|
Droplet,
|
|
150
|
+
Droplets,
|
|
151
|
+
Dumbbell,
|
|
152
|
+
Earth,
|
|
89
153
|
Ellipsis,
|
|
154
|
+
Euro,
|
|
90
155
|
Eye,
|
|
91
156
|
EyeOff,
|
|
92
157
|
FaceSlightlySmiling,
|
|
93
158
|
File,
|
|
159
|
+
FilePlus,
|
|
94
160
|
FileText,
|
|
161
|
+
Film,
|
|
162
|
+
Fingerprint,
|
|
163
|
+
Fish,
|
|
95
164
|
Flag,
|
|
96
165
|
Flame,
|
|
97
166
|
Folder,
|
|
167
|
+
FolderMinus,
|
|
168
|
+
FolderPlus,
|
|
169
|
+
Forward,
|
|
170
|
+
Fuel,
|
|
98
171
|
Funnel,
|
|
172
|
+
GalleryVerticalEnd,
|
|
99
173
|
Gamepad2,
|
|
174
|
+
Gauge,
|
|
100
175
|
Gift,
|
|
176
|
+
GitBranch,
|
|
177
|
+
GitMerge,
|
|
178
|
+
Glasses,
|
|
101
179
|
Globe,
|
|
102
180
|
GraduationCap,
|
|
181
|
+
Grid3x3,
|
|
182
|
+
Hammer,
|
|
103
183
|
Hand,
|
|
104
|
-
|
|
184
|
+
HardDrive,
|
|
185
|
+
Hash,
|
|
105
186
|
Headphones,
|
|
106
187
|
Heart,
|
|
188
|
+
HeartOff,
|
|
189
|
+
Hexagon,
|
|
190
|
+
Highlighter,
|
|
191
|
+
History,
|
|
192
|
+
Hourglass,
|
|
107
193
|
House,
|
|
194
|
+
IdCard,
|
|
108
195
|
Image,
|
|
196
|
+
Images,
|
|
109
197
|
Inbox,
|
|
198
|
+
Infinity,
|
|
110
199
|
Info,
|
|
200
|
+
Italic,
|
|
201
|
+
JapaneseYen,
|
|
111
202
|
Key,
|
|
112
203
|
Keyboard,
|
|
204
|
+
Landmark,
|
|
113
205
|
Laptop,
|
|
206
|
+
Lasso,
|
|
207
|
+
Layers,
|
|
208
|
+
Layers3,
|
|
209
|
+
LayoutGrid,
|
|
210
|
+
LayoutList,
|
|
114
211
|
Leaf,
|
|
212
|
+
Library,
|
|
115
213
|
Lightbulb,
|
|
116
214
|
Link,
|
|
215
|
+
Link2,
|
|
117
216
|
List,
|
|
118
217
|
ListChecks,
|
|
218
|
+
ListIndentIncrease,
|
|
219
|
+
ListMusic,
|
|
119
220
|
ListOrdered,
|
|
120
221
|
LoaderCircle,
|
|
222
|
+
LocateFixed,
|
|
121
223
|
Lock,
|
|
122
224
|
LockOpen,
|
|
123
225
|
LogIn,
|
|
124
226
|
LogOut,
|
|
125
227
|
Mail,
|
|
228
|
+
MailOpen,
|
|
229
|
+
MailWarning,
|
|
126
230
|
Map,
|
|
127
231
|
MapPin,
|
|
232
|
+
MapPinOff,
|
|
233
|
+
Maximize2,
|
|
234
|
+
Medal,
|
|
128
235
|
Menu,
|
|
129
236
|
MessageCircle,
|
|
130
237
|
MessageSquare,
|
|
238
|
+
MessageSquareMore,
|
|
239
|
+
MessageSquarePlus,
|
|
240
|
+
MessageSquareQuote,
|
|
241
|
+
MessageSquareText,
|
|
242
|
+
MessageSquareWarning,
|
|
243
|
+
MessagesSquare,
|
|
131
244
|
Mic,
|
|
132
245
|
MicOff,
|
|
246
|
+
MicVocal,
|
|
247
|
+
Minimize2,
|
|
133
248
|
Minus,
|
|
134
249
|
Monitor,
|
|
250
|
+
MonitorPlay,
|
|
135
251
|
Moon,
|
|
252
|
+
Mountain,
|
|
136
253
|
Music,
|
|
254
|
+
Navigation2,
|
|
255
|
+
Network,
|
|
256
|
+
Newspaper,
|
|
257
|
+
Octagon,
|
|
258
|
+
OctagonAlert,
|
|
259
|
+
OctagonX,
|
|
260
|
+
Option,
|
|
137
261
|
Package,
|
|
262
|
+
Paintbrush,
|
|
263
|
+
Palette,
|
|
264
|
+
PanelLeft,
|
|
265
|
+
PanelRight,
|
|
138
266
|
Paperclip,
|
|
139
267
|
Pause,
|
|
268
|
+
PawPrint,
|
|
140
269
|
Pencil,
|
|
270
|
+
PencilOff,
|
|
271
|
+
PenTool,
|
|
272
|
+
Percent,
|
|
273
|
+
PersonStanding,
|
|
141
274
|
Phone,
|
|
275
|
+
PhoneIncoming,
|
|
276
|
+
PhoneOff,
|
|
277
|
+
PhoneOutgoing,
|
|
278
|
+
Pill,
|
|
142
279
|
Pin,
|
|
280
|
+
Pipette,
|
|
143
281
|
Plane,
|
|
144
282
|
Play,
|
|
145
283
|
Plus,
|
|
284
|
+
Pointer,
|
|
285
|
+
PoundSterling,
|
|
146
286
|
Power,
|
|
147
287
|
Printer,
|
|
288
|
+
Puzzle,
|
|
148
289
|
QrCode,
|
|
290
|
+
Rabbit,
|
|
291
|
+
Radio,
|
|
292
|
+
RectangleHorizontal,
|
|
293
|
+
RectangleVertical,
|
|
294
|
+
Redo2,
|
|
149
295
|
RefreshCw,
|
|
150
296
|
Repeat,
|
|
297
|
+
Reply,
|
|
298
|
+
ReplyAll,
|
|
151
299
|
RotateCcw,
|
|
152
300
|
RotateCw,
|
|
301
|
+
Rows2,
|
|
302
|
+
Ruler,
|
|
303
|
+
Sailboat,
|
|
304
|
+
Scan,
|
|
305
|
+
ScanBarcode,
|
|
306
|
+
ScanFace,
|
|
307
|
+
ScanQrCode,
|
|
308
|
+
School,
|
|
309
|
+
Scissors,
|
|
153
310
|
Search,
|
|
154
311
|
Send,
|
|
312
|
+
Server,
|
|
155
313
|
Settings,
|
|
314
|
+
Shapes,
|
|
156
315
|
Share,
|
|
316
|
+
Share2,
|
|
157
317
|
Shield,
|
|
158
318
|
ShieldCheck,
|
|
319
|
+
Ship,
|
|
159
320
|
ShoppingBag,
|
|
321
|
+
ShoppingBasket,
|
|
160
322
|
ShoppingCart,
|
|
161
323
|
Shuffle,
|
|
324
|
+
Sigma,
|
|
325
|
+
Signal,
|
|
326
|
+
Signpost,
|
|
162
327
|
SkipBack,
|
|
163
328
|
SkipForward,
|
|
164
329
|
SlidersHorizontal,
|
|
165
330
|
Smartphone,
|
|
331
|
+
Snowflake,
|
|
332
|
+
Sparkle,
|
|
166
333
|
Sparkles,
|
|
167
334
|
Speaker,
|
|
168
335
|
Square,
|
|
336
|
+
SquareArrowDown,
|
|
337
|
+
SquareArrowLeft,
|
|
338
|
+
SquareArrowOutUpRight,
|
|
339
|
+
SquareArrowRight,
|
|
340
|
+
SquareArrowUp,
|
|
169
341
|
SquareCheck,
|
|
342
|
+
SquareMinus,
|
|
343
|
+
SquareParking,
|
|
170
344
|
SquarePen,
|
|
345
|
+
SquarePlay,
|
|
346
|
+
SquarePlus,
|
|
347
|
+
SquareUser,
|
|
348
|
+
SquareX,
|
|
171
349
|
Star,
|
|
350
|
+
StarHalf,
|
|
351
|
+
StarOff,
|
|
352
|
+
Stethoscope,
|
|
353
|
+
StickyNote,
|
|
354
|
+
Store,
|
|
355
|
+
Strikethrough,
|
|
172
356
|
Sun,
|
|
357
|
+
SunDim,
|
|
358
|
+
Sunrise,
|
|
359
|
+
Sunset,
|
|
360
|
+
SwitchCamera,
|
|
173
361
|
Tag,
|
|
174
362
|
Target,
|
|
363
|
+
Tent,
|
|
175
364
|
Terminal,
|
|
176
|
-
|
|
365
|
+
TextAlignCenter,
|
|
366
|
+
TextAlignEnd,
|
|
367
|
+
TextAlignJustify,
|
|
368
|
+
TextAlignStart,
|
|
369
|
+
Thermometer,
|
|
370
|
+
ThumbsDown,
|
|
177
371
|
ThumbsUp,
|
|
372
|
+
Ticket,
|
|
373
|
+
Timer,
|
|
374
|
+
Tornado,
|
|
375
|
+
TrainFront,
|
|
376
|
+
TramFront,
|
|
178
377
|
Trash,
|
|
179
|
-
|
|
378
|
+
Trash2,
|
|
379
|
+
TreeDeciduous,
|
|
380
|
+
TrendingDown,
|
|
180
381
|
TrendingUp,
|
|
382
|
+
Triangle,
|
|
383
|
+
TriangleAlert,
|
|
181
384
|
Trophy,
|
|
385
|
+
Truck,
|
|
386
|
+
Turtle,
|
|
182
387
|
Tv,
|
|
183
388
|
Type,
|
|
389
|
+
Umbrella,
|
|
390
|
+
Underline,
|
|
391
|
+
Undo2,
|
|
184
392
|
Upload,
|
|
185
393
|
User,
|
|
394
|
+
UserCheck,
|
|
395
|
+
UserMinus,
|
|
396
|
+
UserPlus,
|
|
186
397
|
Users,
|
|
398
|
+
UserX,
|
|
399
|
+
Utensils,
|
|
400
|
+
Video,
|
|
401
|
+
VideoOff,
|
|
187
402
|
Volume,
|
|
188
403
|
Volume1,
|
|
189
404
|
Volume2,
|
|
190
405
|
VolumeX,
|
|
191
406
|
Wallet,
|
|
407
|
+
WandSparkles,
|
|
192
408
|
Watch,
|
|
193
409
|
Wifi,
|
|
410
|
+
WifiOff,
|
|
194
411
|
Wind,
|
|
412
|
+
Wine,
|
|
195
413
|
Wrench,
|
|
196
414
|
X,
|
|
197
415
|
Zap,
|
|
416
|
+
ZapOff,
|
|
198
417
|
ZoomIn,
|
|
199
418
|
ZoomOut,
|
|
200
419
|
createElement,
|
|
201
420
|
type IconNode,
|
|
202
|
-
Grid3x3,
|
|
203
|
-
LayoutGrid,
|
|
204
|
-
LayoutList,
|
|
205
|
-
MessageSquarePlus,
|
|
206
|
-
MessageSquareText,
|
|
207
|
-
Truck,
|
|
208
|
-
Utensils,
|
|
209
421
|
} from 'lucide';
|
|
210
422
|
|
|
211
423
|
/** How a glyph is painted; see the file comment. */
|
|
@@ -216,6 +428,41 @@ export interface SymbolGlyph {
|
|
|
216
428
|
fill: GlyphFill;
|
|
217
429
|
}
|
|
218
430
|
|
|
431
|
+
/**
|
|
432
|
+
* The activity indicator (an indeterminate `ProgressView`), as iOS draws it:
|
|
433
|
+
* eight rounded spokes filling the glyph, the leading one (at the top) at full
|
|
434
|
+
* strength and the three behind it fading out to the rest's 0.31. styles.css
|
|
435
|
+
* steps that ramp around the spokes clockwise (the glyph itself stays still),
|
|
436
|
+
* so the fade trails the leading spoke.
|
|
437
|
+
*/
|
|
438
|
+
const ACTIVITY_INDICATOR: IconNode = [
|
|
439
|
+
['line', { x1: '12', y1: '6.21', x2: '12', y2: '1.52', 'stroke-width': '3.05', 'stroke-opacity': '1' }],
|
|
440
|
+
['line', { x1: '16.09', y1: '7.91', x2: '19.41', y2: '4.59', 'stroke-width': '3.05', 'stroke-opacity': '0.31' }],
|
|
441
|
+
['line', { x1: '17.79', y1: '12', x2: '22.48', y2: '12', 'stroke-width': '3.05', 'stroke-opacity': '0.31' }],
|
|
442
|
+
['line', { x1: '16.09', y1: '16.09', x2: '19.41', y2: '19.41', 'stroke-width': '3.05', 'stroke-opacity': '0.31' }],
|
|
443
|
+
['line', { x1: '12', y1: '17.79', x2: '12', y2: '22.48', 'stroke-width': '3.05', 'stroke-opacity': '0.31' }],
|
|
444
|
+
['line', { x1: '7.91', y1: '16.09', x2: '4.59', y2: '19.41', 'stroke-width': '3.05', 'stroke-opacity': '0.49' }],
|
|
445
|
+
['line', { x1: '6.21', y1: '12', x2: '1.52', y2: '12', 'stroke-width': '3.05', 'stroke-opacity': '0.66' }],
|
|
446
|
+
['line', { x1: '7.91', y1: '7.91', x2: '4.59', y2: '4.59', 'stroke-width': '3.05', 'stroke-opacity': '0.83' }],
|
|
447
|
+
];
|
|
448
|
+
|
|
449
|
+
/** `books.vertical.fill`: three upright books and a leaning one, as solid shapes. */
|
|
450
|
+
const BOOKS_VERTICAL_FILL: IconNode = [
|
|
451
|
+
['rect', { x: '1.5', y: '3', width: '5', height: '18', rx: '1.2', stroke: 'none' }],
|
|
452
|
+
['rect', { x: '7.5', y: '3', width: '5', height: '18', rx: '1.2', stroke: 'none' }],
|
|
453
|
+
['rect', { x: '13.5', y: '5', width: '4', height: '16', rx: '1.2', stroke: 'none' }],
|
|
454
|
+
['rect', { x: '17.8', y: '4.5', width: '4', height: '16', rx: '1.2', stroke: 'none', transform: 'rotate(-14 19.8 12.5)' }],
|
|
455
|
+
];
|
|
456
|
+
|
|
457
|
+
/** Color used for inner marks of `knockout` glyphs; styles.css sets the variable. */
|
|
458
|
+
const KNOCKOUT_COLOR = 'var(--sb-icon-knockout, var(--sb-color-system-background, #fff))';
|
|
459
|
+
|
|
460
|
+
/** `square.on.circle.fill`: a solid square over a solid circle, a gap between them. */
|
|
461
|
+
const SQUARE_ON_CIRCLE_FILL: IconNode = [
|
|
462
|
+
['circle', { cx: '9.5', cy: '9.5', r: '7.5' }],
|
|
463
|
+
['rect', { x: '9', y: '9', width: '13', height: '13', rx: '3', stroke: KNOCKOUT_COLOR, 'stroke-width': '2.4' }],
|
|
464
|
+
];
|
|
465
|
+
|
|
219
466
|
const outline = (icon: IconNode): SymbolGlyph => ({ icon, fill: 'outline' });
|
|
220
467
|
const knockout = (icon: IconNode): SymbolGlyph => ({ icon, fill: 'knockout' });
|
|
221
468
|
const solid = (icon: IconNode): SymbolGlyph => ({ icon, fill: 'solid' });
|
|
@@ -322,7 +569,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
322
569
|
'flag.fill': solid(Flag),
|
|
323
570
|
tag: outline(Tag),
|
|
324
571
|
'tag.fill': solid(Tag),
|
|
325
|
-
textformat: outline(
|
|
572
|
+
textformat: outline(CaseSensitive),
|
|
326
573
|
'line.3.horizontal': outline(Menu),
|
|
327
574
|
'line.3.horizontal.decrease': outline(Funnel),
|
|
328
575
|
'line.3.horizontal.decrease.circle': outline(Funnel),
|
|
@@ -338,7 +585,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
338
585
|
|
|
339
586
|
// People and places
|
|
340
587
|
person: outline(User),
|
|
341
|
-
'person.fill':
|
|
588
|
+
'person.fill': solid(User),
|
|
342
589
|
'person.2': outline(Users),
|
|
343
590
|
'person.circle': outline(CircleUser),
|
|
344
591
|
'person.circle.fill': knockout(CircleUser),
|
|
@@ -398,7 +645,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
398
645
|
camera: outline(Camera),
|
|
399
646
|
'camera.fill': outline(Camera),
|
|
400
647
|
photo: outline(Image),
|
|
401
|
-
'photo.fill':
|
|
648
|
+
'photo.fill': knockout(Image),
|
|
402
649
|
'photo.on.rectangle': outline(Image),
|
|
403
650
|
play: outline(Play),
|
|
404
651
|
'play.fill': solid(Play),
|
|
@@ -458,7 +705,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
458
705
|
'doc.text.fill': outline(FileText),
|
|
459
706
|
archivebox: outline(Archive),
|
|
460
707
|
'shippingbox': outline(Package),
|
|
461
|
-
'shippingbox.fill':
|
|
708
|
+
'shippingbox.fill': knockout(Package),
|
|
462
709
|
|
|
463
710
|
// Settings and security
|
|
464
711
|
gear: outline(Settings),
|
|
@@ -494,7 +741,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
494
741
|
crown: outline(Crown),
|
|
495
742
|
'crown.fill': solid(Crown),
|
|
496
743
|
trophy: outline(Trophy),
|
|
497
|
-
'trophy.fill':
|
|
744
|
+
'trophy.fill': solid(Trophy),
|
|
498
745
|
|
|
499
746
|
// Nature and weather
|
|
500
747
|
'sun.max': outline(Sun),
|
|
@@ -517,6 +764,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
517
764
|
'circle.grid.3x3': outline(Grid3x3),
|
|
518
765
|
'fork.knife': outline(Utensils),
|
|
519
766
|
'text.bubble': outline(MessageSquareText),
|
|
767
|
+
'text.bubble.fill': knockout(MessageSquareText),
|
|
520
768
|
'plus.bubble': outline(MessageSquarePlus),
|
|
521
769
|
'box.truck': outline(Truck),
|
|
522
770
|
'list.bullet.below.rectangle': outline(LayoutList),
|
|
@@ -548,20 +796,398 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
|
|
|
548
796
|
|
|
549
797
|
// Activity
|
|
550
798
|
'rays': outline(LoaderCircle),
|
|
799
|
+
// An indeterminate ProgressView's spinner (eight spokes; styles.css animates their fade).
|
|
800
|
+
'progress.indicator': outline(ACTIVITY_INDICATOR),
|
|
551
801
|
'circle.dotted': outline(LoaderCircle),
|
|
802
|
+
|
|
803
|
+
// More common symbols: people, documents, arrows, text, shapes, money,
|
|
804
|
+
// health, travel, weather, nature, media, devices, tools.
|
|
805
|
+
'bed.double': outline(BedDouble),
|
|
806
|
+
'bed.double.fill': solid(BedDouble),
|
|
807
|
+
'qrcode.viewfinder': outline(ScanQrCode),
|
|
808
|
+
barcode: outline(Barcode),
|
|
809
|
+
'barcode.viewfinder': outline(ScanBarcode),
|
|
810
|
+
viewfinder: outline(Scan),
|
|
811
|
+
'questionmark.diamond': outline(BadgeQuestionMark),
|
|
812
|
+
'rectangle.on.rectangle': outline(Copy),
|
|
813
|
+
'rectangle.on.rectangle.angled': outline(GalleryVerticalEnd),
|
|
814
|
+
'person.badge.plus': outline(UserPlus),
|
|
815
|
+
'person.badge.minus': outline(UserMinus),
|
|
816
|
+
'person.crop.circle.badge.plus': outline(UserPlus),
|
|
817
|
+
'person.crop.circle.badge.xmark': outline(UserX),
|
|
818
|
+
'person.crop.circle.badge.checkmark': outline(UserCheck),
|
|
819
|
+
'person.crop.circle.fill.badge.checkmark': outline(UserCheck),
|
|
820
|
+
'person.crop.square': outline(SquareUser),
|
|
821
|
+
'person.crop.square.fill': knockout(SquareUser),
|
|
822
|
+
'person.2.fill': solid(Users),
|
|
823
|
+
'person.2.circle': outline(Users),
|
|
824
|
+
'person.text.rectangle': outline(IdCard),
|
|
825
|
+
'person.crop.rectangle': outline(Contact),
|
|
826
|
+
'folder.badge.plus': outline(FolderPlus),
|
|
827
|
+
'folder.badge.minus': outline(FolderMinus),
|
|
828
|
+
'doc.badge.plus': outline(FilePlus),
|
|
829
|
+
'doc.on.doc.fill': outline(Copy),
|
|
830
|
+
'calendar.badge.plus': outline(CalendarPlus),
|
|
831
|
+
'calendar.badge.clock': outline(CalendarClock),
|
|
832
|
+
'calendar.badge.exclamationmark': outline(CalendarX),
|
|
833
|
+
'clock.arrow.circlepath': outline(History),
|
|
834
|
+
'clock.badge.checkmark': outline(ClockCheck),
|
|
835
|
+
'arrow.uturn.backward': outline(Undo2),
|
|
836
|
+
'arrow.uturn.forward': outline(Redo2),
|
|
837
|
+
'arrow.uturn.left': outline(Undo2),
|
|
838
|
+
'arrow.uturn.right': outline(Redo2),
|
|
839
|
+
'arrow.up.left.and.arrow.down.right': outline(Maximize2),
|
|
840
|
+
'arrow.down.right.and.arrow.up.left': outline(Minimize2),
|
|
841
|
+
'arrow.up.right.square': outline(SquareArrowOutUpRight),
|
|
842
|
+
'arrow.up.forward.app': outline(SquareArrowOutUpRight),
|
|
843
|
+
'arrow.right.square': outline(SquareArrowRight),
|
|
844
|
+
'arrow.left.square': outline(SquareArrowLeft),
|
|
845
|
+
'arrow.up.square': outline(SquareArrowUp),
|
|
846
|
+
'arrow.down.square': outline(SquareArrowDown),
|
|
847
|
+
'arrow.triangle.branch': outline(GitBranch),
|
|
848
|
+
'arrow.triangle.merge': outline(GitMerge),
|
|
849
|
+
'arrow.triangle.swap': outline(ArrowLeftRight),
|
|
850
|
+
'arrow.up.and.down': outline(ArrowUpDown),
|
|
851
|
+
'arrow.left.and.right': outline(ArrowLeftRight),
|
|
852
|
+
'arrow.down.left': outline(ArrowDownLeft),
|
|
853
|
+
'arrow.down.right': outline(ArrowDownRight),
|
|
854
|
+
'arrow.up.left': outline(ArrowUpLeft),
|
|
855
|
+
'arrowshape.turn.up.left': outline(Reply),
|
|
856
|
+
'arrowshape.turn.up.right': outline(Forward),
|
|
857
|
+
'arrowshape.turn.up.left.2': outline(ReplyAll),
|
|
858
|
+
'arrowshape.left': outline(ArrowBigLeft),
|
|
859
|
+
'arrowshape.right': outline(ArrowBigRight),
|
|
860
|
+
'arrowshape.up': outline(ArrowBigUp),
|
|
861
|
+
'arrowshape.down': outline(ArrowBigDown),
|
|
862
|
+
'square.on.square': outline(Copy),
|
|
863
|
+
'square.on.circle': outline(Shapes),
|
|
864
|
+
'square.on.circle.fill': solid(SQUARE_ON_CIRCLE_FILL),
|
|
865
|
+
'plus.square': outline(SquarePlus),
|
|
866
|
+
'plus.square.fill': knockout(SquarePlus),
|
|
867
|
+
'minus.square': outline(SquareMinus),
|
|
868
|
+
'minus.square.fill': knockout(SquareMinus),
|
|
869
|
+
'xmark.square': outline(SquareX),
|
|
870
|
+
'xmark.square.fill': knockout(SquareX),
|
|
871
|
+
'plus.app': outline(SquarePlus),
|
|
872
|
+
'star.circle': outline(Star),
|
|
873
|
+
'star.leadinghalf.filled': outline(StarHalf),
|
|
874
|
+
'star.slash': outline(StarOff),
|
|
875
|
+
'heart.slash': outline(HeartOff),
|
|
876
|
+
'heart.circle': outline(Heart),
|
|
877
|
+
'bell.slash': outline(BellOff),
|
|
878
|
+
'bell.badge': outline(BellDot),
|
|
879
|
+
'bell.badge.fill': outline(BellDot),
|
|
880
|
+
'envelope.badge': outline(MailWarning),
|
|
881
|
+
'envelope.open.fill': outline(MailOpen),
|
|
882
|
+
'tray.full': outline(Inbox),
|
|
883
|
+
'tray.fill': solid(Inbox),
|
|
884
|
+
'tray.and.arrow.down': outline(Inbox),
|
|
885
|
+
'tray.and.arrow.up': outline(Inbox),
|
|
886
|
+
'phone.arrow.up.right': outline(PhoneOutgoing),
|
|
887
|
+
'phone.arrow.down.left': outline(PhoneIncoming),
|
|
888
|
+
'phone.down': outline(PhoneOff),
|
|
889
|
+
video: outline(Video),
|
|
890
|
+
'video.fill': solid(Video),
|
|
891
|
+
'video.slash': outline(VideoOff),
|
|
892
|
+
'bubble.left.and.bubble.right': outline(MessagesSquare),
|
|
893
|
+
'bubble.left.and.bubble.right.fill': outline(MessagesSquare),
|
|
894
|
+
'bubble.right': outline(MessageSquare),
|
|
895
|
+
'bubble.left.fill': solid(MessageSquare),
|
|
896
|
+
'quote.bubble': outline(MessageSquareQuote),
|
|
897
|
+
'ellipsis.bubble': outline(MessageSquareMore),
|
|
898
|
+
'exclamationmark.bubble': outline(MessageSquareWarning),
|
|
899
|
+
'text.alignleft': outline(TextAlignStart),
|
|
900
|
+
'text.aligncenter': outline(TextAlignCenter),
|
|
901
|
+
'text.alignright': outline(TextAlignEnd),
|
|
902
|
+
'text.justify': outline(TextAlignJustify),
|
|
903
|
+
bold: outline(Bold),
|
|
904
|
+
italic: outline(Italic),
|
|
905
|
+
underline: outline(Underline),
|
|
906
|
+
strikethrough: outline(Strikethrough),
|
|
907
|
+
'textformat.size': outline(ALargeSmall),
|
|
908
|
+
character: outline(Type),
|
|
909
|
+
'list.dash': outline(List),
|
|
910
|
+
'list.bullet.indent': outline(ListIndentIncrease),
|
|
911
|
+
'list.clipboard': outline(ClipboardList),
|
|
912
|
+
'square.grid.3x3': outline(Grid3x3),
|
|
913
|
+
'square.grid.2x2.fill': solid(LayoutGrid),
|
|
914
|
+
'rectangle.grid.1x2': outline(Rows2),
|
|
915
|
+
'rectangle.split.2x1': outline(Columns2),
|
|
916
|
+
'sidebar.left': outline(PanelLeft),
|
|
917
|
+
'sidebar.right': outline(PanelRight),
|
|
918
|
+
'rectangle.stack': outline(Layers),
|
|
919
|
+
'square.stack': outline(Layers),
|
|
920
|
+
'square.stack.3d.up': outline(Layers3),
|
|
921
|
+
rectangle: outline(RectangleHorizontal),
|
|
922
|
+
'rectangle.fill': solid(RectangleHorizontal),
|
|
923
|
+
'rectangle.portrait': outline(RectangleVertical),
|
|
924
|
+
triangle: outline(Triangle),
|
|
925
|
+
'triangle.fill': solid(Triangle),
|
|
926
|
+
diamond: outline(Diamond),
|
|
927
|
+
'diamond.fill': solid(Diamond),
|
|
928
|
+
hexagon: outline(Hexagon),
|
|
929
|
+
'hexagon.fill': solid(Hexagon),
|
|
930
|
+
octagon: outline(Octagon),
|
|
931
|
+
'checkmark.seal': outline(BadgeCheck),
|
|
932
|
+
'checkmark.seal.fill': knockout(BadgeCheck),
|
|
933
|
+
'xmark.octagon': outline(OctagonX),
|
|
934
|
+
'xmark.octagon.fill': outline(OctagonX),
|
|
935
|
+
'exclamationmark.octagon': outline(OctagonAlert),
|
|
936
|
+
nosign: outline(Ban),
|
|
937
|
+
'slash.circle': outline(Ban),
|
|
938
|
+
number: outline(Hash),
|
|
939
|
+
percent: outline(Percent),
|
|
940
|
+
dollarsign: outline(DollarSign),
|
|
941
|
+
'dollarsign.circle': outline(CircleDollarSign),
|
|
942
|
+
'dollarsign.circle.fill': knockout(CircleDollarSign),
|
|
943
|
+
eurosign: outline(Euro),
|
|
944
|
+
sterlingsign: outline(PoundSterling),
|
|
945
|
+
yensign: outline(JapaneseYen),
|
|
946
|
+
bitcoinsign: outline(Bitcoin),
|
|
947
|
+
banknote: outline(Banknote),
|
|
948
|
+
basket: outline(ShoppingBasket),
|
|
949
|
+
storefront: outline(Store),
|
|
950
|
+
'building.columns': outline(Landmark),
|
|
951
|
+
ticket: outline(Ticket),
|
|
952
|
+
'chart.bar.fill': outline(ChartBar),
|
|
953
|
+
'chart.bar.xaxis': outline(ChartColumn),
|
|
954
|
+
'chart.line.downtrend.xyaxis': outline(TrendingDown),
|
|
955
|
+
waveform: outline(AudioWaveform),
|
|
956
|
+
'waveform.path.ecg': outline(Activity),
|
|
957
|
+
cross: outline(Cross),
|
|
958
|
+
'cross.case': outline(BriefcaseMedical),
|
|
959
|
+
pills: outline(Pill),
|
|
960
|
+
bandage: outline(Bandage),
|
|
961
|
+
stethoscope: outline(Stethoscope),
|
|
962
|
+
brain: outline(Brain),
|
|
963
|
+
'brain.head.profile': outline(Brain),
|
|
964
|
+
'figure.stand': outline(PersonStanding),
|
|
965
|
+
dumbbell: outline(Dumbbell),
|
|
966
|
+
tram: outline(TramFront),
|
|
967
|
+
'train.side.front.car': outline(TrainFront),
|
|
968
|
+
ferry: outline(Ship),
|
|
969
|
+
sailboat: outline(Sailboat),
|
|
970
|
+
fuelpump: outline(Fuel),
|
|
971
|
+
parkingsign: outline(SquareParking),
|
|
972
|
+
tent: outline(Tent),
|
|
973
|
+
'mountain.2': outline(Mountain),
|
|
974
|
+
tree: outline(TreeDeciduous),
|
|
975
|
+
thermometer: outline(Thermometer),
|
|
976
|
+
'thermometer.medium': outline(Thermometer),
|
|
977
|
+
umbrella: outline(Umbrella),
|
|
978
|
+
snowflake: outline(Snowflake),
|
|
979
|
+
'sun.min': outline(SunDim),
|
|
980
|
+
sunrise: outline(Sunrise),
|
|
981
|
+
sunset: outline(Sunset),
|
|
982
|
+
'cloud.drizzle': outline(CloudDrizzle),
|
|
983
|
+
'cloud.fog': outline(CloudFog),
|
|
984
|
+
'cloud.heavyrain': outline(CloudRainWind),
|
|
985
|
+
'cloud.hail': outline(CloudHail),
|
|
986
|
+
tornado: outline(Tornado),
|
|
987
|
+
humidity: outline(Droplets),
|
|
988
|
+
pawprint: outline(PawPrint),
|
|
989
|
+
hare: outline(Rabbit),
|
|
990
|
+
tortoise: outline(Turtle),
|
|
991
|
+
fish: outline(Fish),
|
|
992
|
+
bird: outline(Bird),
|
|
993
|
+
// The Swift logo: a bird in flight.
|
|
994
|
+
swift: outline(Bird),
|
|
995
|
+
cat: outline(Cat),
|
|
996
|
+
dog: outline(Dog),
|
|
997
|
+
carrot: outline(Carrot),
|
|
998
|
+
'cup.and.saucer': outline(Coffee),
|
|
999
|
+
mug: outline(Coffee),
|
|
1000
|
+
wineglass: outline(Wine),
|
|
1001
|
+
'birthday.cake': outline(Cake),
|
|
1002
|
+
film: outline(Film),
|
|
1003
|
+
'film.stack': outline(Clapperboard),
|
|
1004
|
+
'camera.rotate': outline(SwitchCamera),
|
|
1005
|
+
'photo.stack': outline(Images),
|
|
1006
|
+
'photo.on.rectangle.angled': outline(Images),
|
|
1007
|
+
'music.note.list': outline(ListMusic),
|
|
1008
|
+
'music.mic': outline(MicVocal),
|
|
1009
|
+
radio: outline(Radio),
|
|
1010
|
+
airplayaudio: outline(Airplay),
|
|
1011
|
+
airplayvideo: outline(Airplay),
|
|
1012
|
+
'play.rectangle': outline(MonitorPlay),
|
|
1013
|
+
'play.square': outline(SquarePlay),
|
|
1014
|
+
icloud: outline(Cloud),
|
|
1015
|
+
'icloud.fill': solid(Cloud),
|
|
1016
|
+
'icloud.and.arrow.up': outline(CloudUpload),
|
|
1017
|
+
'icloud.and.arrow.down': outline(CloudDownload),
|
|
1018
|
+
externaldrive: outline(HardDrive),
|
|
1019
|
+
'server.rack': outline(Server),
|
|
1020
|
+
cylinder: outline(Database),
|
|
1021
|
+
network: outline(Network),
|
|
1022
|
+
faceid: outline(ScanFace),
|
|
1023
|
+
touchid: outline(Fingerprint),
|
|
1024
|
+
'lock.shield': outline(ShieldCheck),
|
|
1025
|
+
'hand.tap': outline(Pointer),
|
|
1026
|
+
'hand.wave': outline(Hand),
|
|
1027
|
+
'hand.thumbsdown': outline(ThumbsDown),
|
|
1028
|
+
'hand.thumbsdown.fill': solid(ThumbsDown),
|
|
1029
|
+
eyeglasses: outline(Glasses),
|
|
1030
|
+
sparkle: outline(Sparkle),
|
|
1031
|
+
'wand.and.stars': outline(WandSparkles),
|
|
1032
|
+
paintbrush: outline(Paintbrush),
|
|
1033
|
+
paintpalette: outline(Palette),
|
|
1034
|
+
'pencil.tip': outline(PenTool),
|
|
1035
|
+
'pencil.slash': outline(PencilOff),
|
|
1036
|
+
highlighter: outline(Highlighter),
|
|
1037
|
+
scissors: outline(Scissors),
|
|
1038
|
+
ruler: outline(Ruler),
|
|
1039
|
+
eyedropper: outline(Pipette),
|
|
1040
|
+
lasso: outline(Lasso),
|
|
1041
|
+
crop: outline(Crop),
|
|
1042
|
+
gauge: outline(Gauge),
|
|
1043
|
+
speedometer: outline(Gauge),
|
|
1044
|
+
hammer: outline(Hammer),
|
|
1045
|
+
puzzlepiece: outline(Puzzle),
|
|
1046
|
+
dice: outline(Dices),
|
|
1047
|
+
newspaper: outline(Newspaper),
|
|
1048
|
+
'books.vertical': outline(Library),
|
|
1049
|
+
'books.vertical.fill': solid(BOOKS_VERTICAL_FILL),
|
|
1050
|
+
'note.text': outline(StickyNote),
|
|
1051
|
+
note: outline(StickyNote),
|
|
1052
|
+
'location.circle': outline(LocateFixed),
|
|
1053
|
+
'location.north': outline(Navigation2),
|
|
1054
|
+
'location.slash': outline(MapPinOff),
|
|
1055
|
+
'signpost.right': outline(Signpost),
|
|
1056
|
+
'globe.americas': outline(Earth),
|
|
1057
|
+
'globe.europe.africa': outline(Earth),
|
|
1058
|
+
'bolt.slash': outline(ZapOff),
|
|
1059
|
+
'battery.25': outline(BatteryLow),
|
|
1060
|
+
'battery.50': outline(BatteryMedium),
|
|
1061
|
+
'battery.75': outline(BatteryFull),
|
|
1062
|
+
'battery.0': outline(BatteryWarning),
|
|
1063
|
+
'wifi.slash': outline(WifiOff),
|
|
1064
|
+
cellularbars: outline(Signal),
|
|
1065
|
+
infinity: outline(Infinity),
|
|
1066
|
+
sum: outline(Sigma),
|
|
1067
|
+
command: outline(Command),
|
|
1068
|
+
option: outline(Option),
|
|
1069
|
+
'delete.left': outline(Delete),
|
|
1070
|
+
return: outline(CornerDownLeft),
|
|
1071
|
+
'xmark.bin': outline(Trash2),
|
|
1072
|
+
'square.and.arrow.up.on.square': outline(Share2),
|
|
1073
|
+
'link.badge.plus': outline(Link2),
|
|
1074
|
+
'shippingbox.circle': outline(Package),
|
|
1075
|
+
'graduationcap.fill': solid(GraduationCap),
|
|
1076
|
+
medal: outline(Medal),
|
|
1077
|
+
rosette: outline(Award),
|
|
1078
|
+
'gift.circle': outline(Gift),
|
|
1079
|
+
studentdesk: outline(School),
|
|
552
1080
|
};
|
|
553
1081
|
|
|
554
|
-
/** Number of SF Symbol names the
|
|
1082
|
+
/** Number of SF Symbol names the map lists (more resolve as variants, see `lookupSymbol`). */
|
|
555
1083
|
export const SF_SYMBOL_COUNT = Object.keys(SF_SYMBOLS).length;
|
|
556
1084
|
|
|
557
1085
|
export function lookupSymbol(systemName: string): SymbolGlyph | undefined {
|
|
558
|
-
|
|
1086
|
+
const exact = SF_SYMBOLS[systemName];
|
|
1087
|
+
if (exact) return exact;
|
|
1088
|
+
if (!(systemName in variants)) variants[systemName] = resolveVariant(systemName) ?? null;
|
|
1089
|
+
return variants[systemName] ?? undefined;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
/** Resolved variants (null: none); an object because lucide's `Map` icon shadows the global. */
|
|
1093
|
+
const variants: Record<string, SymbolGlyph | null> = Object.create(null);
|
|
1094
|
+
|
|
1095
|
+
/** Shapes that alone would stand in for too much (`circle.grid.2x2` is not a circle). */
|
|
1096
|
+
const GENERIC_SHAPES = new Set(['circle', 'square', 'rectangle', 'app', 'capsule', 'triangle', 'diamond', 'hexagon', 'octagon', 'seal', 'shield']);
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* A name the map does not list is drawn as the closest listed one: SF Symbol
|
|
1100
|
+
* names extend a base with modifiers, so `person.crop.circle.badge.xmark`
|
|
1101
|
+
* is drawn as `person.crop.circle`, `trash.circle.fill` as `trash.fill` and
|
|
1102
|
+
* `speaker.wave.2.fill` as `speaker.wave.2`. A `.badge…` suffix is dropped,
|
|
1103
|
+
* then trailing parts one at a time; a name with `.fill` tries every filled
|
|
1104
|
+
* form first. A `.slash` variant is never drawn as its base, which would
|
|
1105
|
+
* mean the opposite (`bell.slash` is "notifications off"); nor is a name
|
|
1106
|
+
* drawn as a bare shape. Unresolved names get the caller's placeholder.
|
|
1107
|
+
*/
|
|
1108
|
+
function resolveVariant(systemName: string): SymbolGlyph | undefined {
|
|
1109
|
+
let parts = systemName.split('.');
|
|
1110
|
+
if (parts.includes('slash')) return undefined;
|
|
1111
|
+
const fill = parts.includes('fill');
|
|
1112
|
+
parts = parts.filter((part) => part !== 'fill');
|
|
1113
|
+
const badge = parts.indexOf('badge');
|
|
1114
|
+
if (badge > 0) parts = parts.slice(0, badge);
|
|
1115
|
+
// `trash.circle`, `arrow.down.circle.fill`, `heart.square.fill`: the base
|
|
1116
|
+
// glyph inside the enclosure (drawn whole, or filled with the glyph
|
|
1117
|
+
// knocked out), unless the table lists the full name's base form.
|
|
1118
|
+
const enclosure = parts.at(-1);
|
|
1119
|
+
if ((enclosure === 'circle' || enclosure === 'square') && parts.length > 1) {
|
|
1120
|
+
const listed = SF_SYMBOLS[parts.join('.')];
|
|
1121
|
+
if (listed) {
|
|
1122
|
+
// The listed outline form, its enclosure filled (`arrow.down.circle.fill`).
|
|
1123
|
+
if (fill && enclosingShapeIndex(listed.icon) >= 0) return { icon: listed.icon, fill: 'knockout' };
|
|
1124
|
+
} else {
|
|
1125
|
+
const base = parts.slice(0, -1).join('.');
|
|
1126
|
+
const glyph = GENERIC_SHAPES.has(base) ? undefined : lookupSymbol(base);
|
|
1127
|
+
if (glyph) return enclosed(glyph.icon, enclosure, fill);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
const bases: string[] = [];
|
|
1131
|
+
for (let length = parts.length; length > 0; length--) {
|
|
1132
|
+
const base = parts.slice(0, length).join('.');
|
|
1133
|
+
if (length === 1 && parts.length > 1 && GENERIC_SHAPES.has(base)) break;
|
|
1134
|
+
bases.push(base);
|
|
1135
|
+
}
|
|
1136
|
+
// A filled form at any length before an outline: `heart.circle.fill` is
|
|
1137
|
+
// closer to `heart.fill` than to `heart.circle`.
|
|
1138
|
+
const candidates = fill ? [...bases.map((base) => `${base}.fill`), ...bases] : bases;
|
|
1139
|
+
for (const name of candidates) {
|
|
1140
|
+
const glyph = SF_SYMBOLS[name];
|
|
1141
|
+
if (glyph) return glyph;
|
|
1142
|
+
}
|
|
1143
|
+
return undefined;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
/**
|
|
1147
|
+
* `icon` at 55% inside a circle or rounded square: outlined (`X.circle`), or
|
|
1148
|
+
* filled with the glyph knocked out of it (`X.circle.fill`), as SF Symbols
|
|
1149
|
+
* draw their enclosed forms.
|
|
1150
|
+
*/
|
|
1151
|
+
function enclosed(icon: IconNode, enclosure: 'circle' | 'square', fill: boolean): SymbolGlyph {
|
|
1152
|
+
const outer: IconNode[number] =
|
|
1153
|
+
enclosure === 'circle' ? ['circle', { cx: '12', cy: '12', r: '10' }] : ['rect', { x: '3', y: '3', width: '18', height: '18', rx: '4' }];
|
|
1154
|
+
// Scaled about the center; the stroke is widened to keep its weight.
|
|
1155
|
+
const inner = icon.map(([tag, attrs]) => [tag, { ...attrs, transform: 'translate(5.4 5.4) scale(0.55)', 'stroke-width': '3.3' }] as IconNode[number]);
|
|
1156
|
+
return { icon: [outer, ...inner], fill: fill ? 'knockout' : 'outline' };
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* The name of the filled form of `systemName` when the table can draw one
|
|
1161
|
+
* (`house` → `house.fill`), else the name itself: a tab bar shows its items'
|
|
1162
|
+
* symbols filled, as iOS does (`symbolVariants` `.fill`).
|
|
1163
|
+
*/
|
|
1164
|
+
export function filledSymbolName(systemName: string): string {
|
|
1165
|
+
if (systemName.split('.').includes('fill')) return systemName;
|
|
1166
|
+
const filled = `${systemName}.fill`;
|
|
1167
|
+
const glyph = lookupSymbol(filled);
|
|
1168
|
+
return glyph && glyph.fill !== 'outline' ? filled : systemName;
|
|
559
1169
|
}
|
|
560
1170
|
|
|
561
1171
|
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
562
1172
|
|
|
563
|
-
/**
|
|
564
|
-
|
|
1173
|
+
/**
|
|
1174
|
+
* The shape a `knockout` glyph fills: the enclosing circle or rectangle
|
|
1175
|
+
* (lucide lists it first in most glyphs but not all: `CirclePlay` starts
|
|
1176
|
+
* with its triangle), else the first shape.
|
|
1177
|
+
*/
|
|
1178
|
+
export function outerShapeIndex(icon: IconNode): number {
|
|
1179
|
+
const index = enclosingShapeIndex(icon);
|
|
1180
|
+
return index >= 0 ? index : 0;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/** The index of the circle or rectangle enclosing `icon`'s other marks, or -1. */
|
|
1184
|
+
function enclosingShapeIndex(icon: IconNode): number {
|
|
1185
|
+
return icon.findIndex(([tag, attrs]) => {
|
|
1186
|
+
const n = (key: string): number => Number(attrs[key] ?? 0);
|
|
1187
|
+
return (tag === 'circle' && n('r') >= 9) || (tag === 'rect' && n('width') >= 16 && n('height') >= 12);
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
|
|
565
1191
|
|
|
566
1192
|
/**
|
|
567
1193
|
* Build the `<svg>` for a symbol. Returns `null` for unknown names; the
|
|
@@ -584,12 +1210,16 @@ export function renderSymbol(systemName: string): SVGElement | null {
|
|
|
584
1210
|
shape.setAttribute('fill', 'currentColor');
|
|
585
1211
|
}
|
|
586
1212
|
} else if (glyph.fill === 'knockout') {
|
|
587
|
-
const
|
|
588
|
-
outer
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
1213
|
+
const shapes = Array.from(svg.children);
|
|
1214
|
+
const outer = outerShapeIndex(glyph.icon);
|
|
1215
|
+
shapes.forEach((shape, index) => {
|
|
1216
|
+
if (index === outer) {
|
|
1217
|
+
shape.setAttribute('fill', 'currentColor');
|
|
1218
|
+
} else {
|
|
1219
|
+
shape.setAttribute('stroke', KNOCKOUT_COLOR);
|
|
1220
|
+
shape.setAttribute('fill', 'none');
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
593
1223
|
}
|
|
594
1224
|
return svg;
|
|
595
1225
|
}
|