termcast 1.3.34 → 1.3.36
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/dist/build.d.ts.map +1 -1
- package/dist/build.js +25 -0
- package/dist/build.js.map +1 -1
- package/dist/components/footer.d.ts.map +1 -1
- package/dist/components/footer.js +1 -1
- package/dist/components/footer.js.map +1 -1
- package/dist/components/icon.d.ts.map +1 -1
- package/dist/components/icon.js +386 -23
- package/dist/components/icon.js.map +1 -1
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/list.js +70 -7
- package/dist/components/list.js.map +1 -1
- package/dist/extensions/home.js +1 -1
- package/dist/extensions/home.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/dialog.d.ts.map +1 -1
- package/dist/internal/dialog.js +4 -5
- package/dist/internal/dialog.js.map +1 -1
- package/dist/internal/providers.d.ts.map +1 -1
- package/dist/internal/providers.js +18 -5
- package/dist/internal/providers.js.map +1 -1
- package/dist/state.d.ts +1 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js.map +1 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +6 -2
- package/dist/theme.js.map +1 -1
- package/dist/utils.d.ts +16 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +28 -1
- package/dist/utils.js.map +1 -1
- package/package.json +8 -4
- package/src/build.tsx +28 -0
- package/src/compile.vitest.tsx +18 -18
- package/src/components/footer.tsx +4 -2
- package/src/components/icon.tsx +385 -23
- package/src/components/list.tsx +84 -13
- package/src/examples/github.vitest.tsx +36 -36
- package/src/examples/list-detail-metadata.vitest.tsx +1 -1
- package/src/examples/list-dropdown-default.vitest.tsx +9 -9
- package/src/examples/list-scrollbox.vitest.tsx +41 -41
- package/src/examples/list-with-detail.vitest.tsx +35 -36
- package/src/examples/list-with-sections.vitest.tsx +117 -117
- package/src/examples/simple-grid.vitest.tsx +44 -44
- package/src/examples/simple-navigation.vitest.tsx +43 -12
- package/src/examples/store.vitest.tsx +1 -1
- package/src/examples/swift-extension.vitest.tsx +3 -3
- package/src/extensions/dev.vitest.tsx +21 -21
- package/src/extensions/home.tsx +1 -1
- package/src/index.tsx +1 -0
- package/src/internal/dialog.tsx +21 -23
- package/src/internal/providers.tsx +18 -5
- package/src/state.tsx +1 -0
- package/src/theme.tsx +6 -2
- package/src/utils.tsx +40 -1
package/src/components/icon.tsx
CHANGED
|
@@ -1,32 +1,394 @@
|
|
|
1
1
|
import { pascalCase } from 'change-case'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
// Semantic unicode mapping for Raycast icon IDs.
|
|
4
|
+
// Uses ONLY characters from emoji-safe unicode ranges for consistent terminal text rendering.
|
|
5
|
+
// Safe ranges used: Arrows (U+2190), Math Operators (U+2200), Geometric Shapes (U+25A0,
|
|
6
|
+
// excluding U+25B6/U+25C0), Block Elements (U+2580), Misc Technical non-emoji subset,
|
|
7
|
+
// Box Drawing (U+2500), Letterlike Symbols, General Punctuation, Latin/ASCII.
|
|
8
|
+
const ICON_MAP: Record<string, string> = {
|
|
9
|
+
'add-person-16': '⊕',
|
|
10
|
+
'airplane-16': '↗',
|
|
11
|
+
'airplane-filled-16': '↗',
|
|
12
|
+
'airplane-landing-16': '↘',
|
|
13
|
+
'airplane-takeoff-16': '↗',
|
|
14
|
+
'airpods-16': '⊚',
|
|
15
|
+
'alarm-16': '⌀',
|
|
16
|
+
'alarm-ringing-16': '⌀',
|
|
17
|
+
'align-centre-16': '≡',
|
|
18
|
+
'align-left-16': '≡',
|
|
19
|
+
'align-right-16': '≡',
|
|
20
|
+
'american-football-16': '◇',
|
|
21
|
+
'anchor-16': '⊥',
|
|
22
|
+
'app-window-16': '⊞',
|
|
23
|
+
'app-window-grid-2x2-16': '⊞',
|
|
24
|
+
'app-window-grid-3x3-16': '⊞',
|
|
25
|
+
'app-window-list-16': '≡',
|
|
26
|
+
'app-window-sidebar-left-16': '◧',
|
|
27
|
+
'app-window-sidebar-right-16': '◨',
|
|
28
|
+
'arrow-clockwise-16': '↻',
|
|
29
|
+
'arrow-counter-clockwise-16': '↺',
|
|
30
|
+
'arrow-down-16': '↓',
|
|
31
|
+
'arrow-down-circle-16': '⇩',
|
|
32
|
+
'arrow-down-circle-filled-16': '⇩',
|
|
33
|
+
'arrow-left-16': '←',
|
|
34
|
+
'arrow-left-circle-16': '⇦',
|
|
35
|
+
'arrow-left-circle-filled-16': '⇦',
|
|
36
|
+
'arrow-ne-16': '↗',
|
|
37
|
+
'arrow-right-16': '→',
|
|
38
|
+
'arrow-right-circle-16': '⇨',
|
|
39
|
+
'arrow-right-circle-filled-16': '⇨',
|
|
40
|
+
'arrow-up-16': '↑',
|
|
41
|
+
'arrow-up-circle-16': '⇧',
|
|
42
|
+
'arrow-up-circle-filled-16': '⇧',
|
|
43
|
+
'arrows-contract-16': '⇤',
|
|
44
|
+
'arrows-expand-16': '⇥',
|
|
45
|
+
'at-symbol-16': '@',
|
|
46
|
+
'band-aid-16': '╋',
|
|
47
|
+
'bank-note-16': '¤',
|
|
48
|
+
'bar-chart-16': '▊',
|
|
49
|
+
'bar-code-16': '▐',
|
|
50
|
+
'bath-tub-16': '▬',
|
|
51
|
+
'battery-16': '▮',
|
|
52
|
+
'battery-charging-16': '▮',
|
|
53
|
+
'battery-disabled-16': '▯',
|
|
54
|
+
'bell-16': '⍾',
|
|
55
|
+
'bell-disabled-16': '⍻',
|
|
56
|
+
'bike-16': '⎌',
|
|
57
|
+
'binoculars-16': '⌕',
|
|
58
|
+
'bird-16': '∿',
|
|
59
|
+
'blank-document-16': '▯',
|
|
60
|
+
'bluetooth-16': 'ᛒ',
|
|
61
|
+
'boat-16': '≈',
|
|
62
|
+
'bold-16': '𝐁',
|
|
63
|
+
'bolt-16': '↯',
|
|
64
|
+
'bolt-disabled-16': '↯',
|
|
65
|
+
'book-16': '⊞',
|
|
66
|
+
'bookmark-16': '▷',
|
|
67
|
+
'box-16': '□',
|
|
68
|
+
'brush-16': '⊘',
|
|
69
|
+
'bug-16': '⊗',
|
|
70
|
+
'building-16': '⌂',
|
|
71
|
+
'bullet-points-16': '•',
|
|
72
|
+
'bulls-eye-16': '◎',
|
|
73
|
+
'bulls-eye-missed-16': '◌',
|
|
74
|
+
'buoy-16': '◉',
|
|
75
|
+
'calculator-16': '⊞',
|
|
76
|
+
'calendar-16': '▦',
|
|
77
|
+
'camera-16': '⌬',
|
|
78
|
+
'car-16': '⊳',
|
|
79
|
+
'cart-16': '⊲',
|
|
80
|
+
'cd-16': '◎',
|
|
81
|
+
'center-16': '⊡',
|
|
82
|
+
'check-16': '✓',
|
|
83
|
+
'check-circle-16': '✓',
|
|
84
|
+
'check-list-16': '✓',
|
|
85
|
+
'check-rosette-16': '✓',
|
|
86
|
+
'checkmark-16': '✓',
|
|
87
|
+
'chess-piece-16': '⊠',
|
|
88
|
+
'chevron-down-16': '⌄',
|
|
89
|
+
'chevron-down-small-16': '⌄',
|
|
90
|
+
'chevron-left-16': '‹',
|
|
91
|
+
'chevron-left-small-16': '‹',
|
|
92
|
+
'chevron-right-16': '›',
|
|
93
|
+
'chevron-right-small-16': '›',
|
|
94
|
+
'chevron-up-16': '⌃',
|
|
95
|
+
'chevron-up-down-16': '⇕',
|
|
96
|
+
'chevron-up-small-16': '⌃',
|
|
97
|
+
'circle-16': '○',
|
|
98
|
+
'circle-disabled-16': '⊘',
|
|
99
|
+
'circle-ellipsis-16': '◯',
|
|
100
|
+
'circle-filled-16': '●',
|
|
101
|
+
'circle-progress-16': '◔',
|
|
102
|
+
'circle-progress-100-16': '●',
|
|
103
|
+
'circle-progress-25-16': '◔',
|
|
104
|
+
'circle-progress-50-16': '◑',
|
|
105
|
+
'circle-progress-75-16': '◕',
|
|
106
|
+
'clear-formatting-16': '⌧',
|
|
107
|
+
'clipboard-16': '⎘',
|
|
108
|
+
'clock-16': '◴',
|
|
109
|
+
'cloud-16': '◠',
|
|
110
|
+
'cloud-lightning-16': '◠',
|
|
111
|
+
'cloud-rain-16': '◠',
|
|
112
|
+
'cloud-snow-16': '◠',
|
|
113
|
+
'cloud-sun-16': '◠',
|
|
114
|
+
'code-16': '⟨⟩',
|
|
115
|
+
'code-block-16': '▤',
|
|
116
|
+
'cog-16': '⊛',
|
|
117
|
+
'coin-16': '¤',
|
|
118
|
+
'coins-16': '¤',
|
|
119
|
+
'command-symbol-16': '⌘',
|
|
120
|
+
'compass-16': '◎',
|
|
121
|
+
'computer-chip-16': '⎔',
|
|
122
|
+
'contrast-16': '◑',
|
|
123
|
+
'copy-clipboard-16': '⎘',
|
|
124
|
+
'credit-card-16': '▬',
|
|
125
|
+
'cricket-ball-16': '◉',
|
|
126
|
+
'crop-16': '⌌',
|
|
127
|
+
'crown-16': '△',
|
|
128
|
+
'crypto-16': '₿',
|
|
129
|
+
'delete-document-16': '⌧',
|
|
130
|
+
'desktop-16': '⎚',
|
|
131
|
+
'devices-16': '⎚',
|
|
132
|
+
'dna-16': '⧖',
|
|
133
|
+
'document-16': '▯',
|
|
134
|
+
'dot-16': '·',
|
|
135
|
+
'download-16': '⤓',
|
|
136
|
+
'droplets-16': '≋',
|
|
137
|
+
'duplicate-16': '⧉',
|
|
138
|
+
'edit-shape-16': '⌑',
|
|
139
|
+
'eject-16': '△',
|
|
140
|
+
'ellipsis-16': '…',
|
|
141
|
+
'ellipsis-vertical-16': '⋮',
|
|
142
|
+
'emoji-16': '◠',
|
|
143
|
+
'emoji-sad-16': '◡',
|
|
144
|
+
'envelope-16': '▷',
|
|
145
|
+
'eraser-16': '⌫',
|
|
146
|
+
'exclamationmark-16': '!',
|
|
147
|
+
'exclamationmark-2-16': '‼',
|
|
148
|
+
'exclamationmark-3-16': '‼',
|
|
149
|
+
'eye-16': '◉',
|
|
150
|
+
'eye-disabled-16': '⊘',
|
|
151
|
+
'eye-dropper-16': '⊙',
|
|
152
|
+
'female-16': '⊕',
|
|
153
|
+
'film-strip-16': '▥',
|
|
154
|
+
'filter-16': '⧩',
|
|
155
|
+
'finder-16': '⌕',
|
|
156
|
+
'fingerprint-16': '◉',
|
|
157
|
+
'flag-16': '⊳',
|
|
158
|
+
'folder-16': '▤',
|
|
159
|
+
'footprints-16': '⊹',
|
|
160
|
+
'forward-16': '▸',
|
|
161
|
+
'forward-filled-16': '▸',
|
|
162
|
+
'fountain-tip-16': '⌑',
|
|
163
|
+
'full-signal-16': '▊',
|
|
164
|
+
'game-controller-16': '⊞',
|
|
165
|
+
'gauge-16': '◔',
|
|
166
|
+
'geopin-16': '⊙',
|
|
167
|
+
'germ-16': '※',
|
|
168
|
+
'gift-16': '⊠',
|
|
169
|
+
'glasses-16': '∞',
|
|
170
|
+
'globe-01-16': '⊕',
|
|
171
|
+
'goal-16': '⊡',
|
|
172
|
+
'hammer-16': '⊤',
|
|
173
|
+
'hard-drive-16': '▬',
|
|
174
|
+
'hashtag-16': '#',
|
|
175
|
+
'heading-16': '𝐇',
|
|
176
|
+
'headphones-16': '⊚',
|
|
177
|
+
'heart-16': '◆',
|
|
178
|
+
'heart-disabled-16': '◇',
|
|
179
|
+
'heartbeat-16': '◆',
|
|
180
|
+
'highlight-16': '▮',
|
|
181
|
+
'hourglass-16': '⧖',
|
|
182
|
+
'house-16': '⌂',
|
|
183
|
+
'humidity-16': '≋',
|
|
184
|
+
'image-16': '⊞',
|
|
185
|
+
'important-01-16': '‼',
|
|
186
|
+
'info-01-16': 'ℹ',
|
|
187
|
+
'italics-16': '𝐼',
|
|
188
|
+
'key-16': '⊢',
|
|
189
|
+
'keyboard-16': '⌗',
|
|
190
|
+
'layers-16': '◫',
|
|
191
|
+
'leaderboard-16': '▊',
|
|
192
|
+
'leaf-16': '∿',
|
|
193
|
+
'light-bulb-16': '※',
|
|
194
|
+
'light-bulb-off-16': '※',
|
|
195
|
+
'line-chart-16': '⌒',
|
|
196
|
+
'link-16': '∞',
|
|
197
|
+
'livestream-01-16': '◉',
|
|
198
|
+
'livestream-disabled-01-16': '◌',
|
|
199
|
+
'lock-16': '⊟',
|
|
200
|
+
'lock-disabled-16': '⊠',
|
|
201
|
+
'lock-unlocked-16': '⊠',
|
|
202
|
+
'logout-16': '⎋',
|
|
203
|
+
'lorry-16': '⊳',
|
|
204
|
+
'lowercase-16': 'aᵃ',
|
|
205
|
+
'magnifying-glass-16': '⌕',
|
|
206
|
+
'male-16': '⊕',
|
|
207
|
+
'map-16': '▦',
|
|
208
|
+
'mask-16': '◑',
|
|
209
|
+
'maximize-16': '⤢',
|
|
210
|
+
'medical-support-16': '╋',
|
|
211
|
+
'megaphone-16': '⊳',
|
|
212
|
+
'memory-stick-16': '▬',
|
|
213
|
+
'microphone-16': '⊙',
|
|
214
|
+
'microphone-disabled-16': '⊘',
|
|
215
|
+
'minimize-16': '⤡',
|
|
216
|
+
'minus-16': '−',
|
|
217
|
+
'minus-circle-16': '⊖',
|
|
218
|
+
'minus-circle-filled-16': '⊖',
|
|
219
|
+
'mobile-16': '▯',
|
|
220
|
+
'monitor-16': '⎚',
|
|
221
|
+
'moon-16': '◐',
|
|
222
|
+
'moon-down-16': '◐',
|
|
223
|
+
'moon-up-16': '◐',
|
|
224
|
+
'moonrise-16': '◐',
|
|
225
|
+
'mountain-16': '△',
|
|
226
|
+
'mouse-16': '⊙',
|
|
227
|
+
'move-16': '⊹',
|
|
228
|
+
'mug-16': '⊔',
|
|
229
|
+
'mug-steam-16': '⊔',
|
|
230
|
+
'multiply-16': '×',
|
|
231
|
+
'music-16': '∿',
|
|
232
|
+
'network-16': '⊕',
|
|
233
|
+
'new-document-16': '▯',
|
|
234
|
+
'new-folder-16': '▤',
|
|
235
|
+
'number-list-16': '⑴',
|
|
236
|
+
'paperclip-16': '⊶',
|
|
237
|
+
'paragraph-16': '¶',
|
|
238
|
+
'patch-16': '╋',
|
|
239
|
+
'pause-16': '‖',
|
|
240
|
+
'pause-filled-16': '‖',
|
|
241
|
+
'pencil-16': '⌑',
|
|
242
|
+
'person-16': '⊙',
|
|
243
|
+
'person-circle-16': '⊙',
|
|
244
|
+
'person-lines-16': '⊙',
|
|
245
|
+
'phone-16': '⌕',
|
|
246
|
+
'phone-ringing-16': '⌕',
|
|
247
|
+
'pie-chart-16': '◔',
|
|
248
|
+
'pill-16': '⊝',
|
|
249
|
+
'pin-16': '⊙',
|
|
250
|
+
'pin-disabled-16': '⊘',
|
|
251
|
+
'play-16': '▸',
|
|
252
|
+
'play-filled-16': '▸',
|
|
253
|
+
'plug-16': '⊢',
|
|
254
|
+
'plus-16': '+',
|
|
255
|
+
'plus-circle-16': '⊕',
|
|
256
|
+
'plus-circle-filled-16': '⊕',
|
|
257
|
+
'plus-minus-divide-multiply-16': '±',
|
|
258
|
+
'plus-square-16': '⊞',
|
|
259
|
+
'plus-top-right-square-16': '⊞',
|
|
260
|
+
'power-16': '⊙',
|
|
261
|
+
'print-16': '⎙',
|
|
262
|
+
'question-mark-circle-16': '?',
|
|
263
|
+
'quicklink-16': '∞',
|
|
264
|
+
'quotation-marks-16': '❝',
|
|
265
|
+
'quote-block-16': '❝',
|
|
266
|
+
'racket-16': '⊙',
|
|
267
|
+
'raindrop-16': '≋',
|
|
268
|
+
'raycast-logo-neg-16': '◆',
|
|
269
|
+
'raycast-logo-pos-16': '◆',
|
|
270
|
+
'receipt-16': '▯',
|
|
271
|
+
'redo-16': '↻',
|
|
272
|
+
'remove-person-16': '⊖',
|
|
273
|
+
'repeat-16': '↻',
|
|
274
|
+
'replace-16': '⇄',
|
|
275
|
+
'replace-one-16': '⇄',
|
|
276
|
+
'reply-16': '↩',
|
|
277
|
+
'rewind-16': '◂',
|
|
278
|
+
'rewind-filled-16': '◂',
|
|
279
|
+
'rocket-16': '⁕',
|
|
280
|
+
'rosette-16': '✦',
|
|
281
|
+
'rotate-anti-clockwise-16': '↺',
|
|
282
|
+
'rotate-clockwise-16': '↻',
|
|
283
|
+
'rss-16': '◉',
|
|
284
|
+
'ruler-16': '⊢',
|
|
285
|
+
'save-document-16': '⊞',
|
|
286
|
+
'shield-01-16': '⊛',
|
|
287
|
+
'short-paragraph-16': '¶',
|
|
288
|
+
'shuffle-16': '⇝',
|
|
289
|
+
'signal-0-16': '▁',
|
|
290
|
+
'signal-1-16': '▂',
|
|
291
|
+
'signal-2-16': '▄',
|
|
292
|
+
'signal-3-16': '█',
|
|
293
|
+
'snippets-16': '⊠',
|
|
294
|
+
'snowflake-16': '※',
|
|
295
|
+
'soccer-ball-16': '◎',
|
|
296
|
+
'speaker-16': '◁',
|
|
297
|
+
'speaker-down-16': '◁',
|
|
298
|
+
'speaker-high-16': '◂',
|
|
299
|
+
'speaker-low-16': '◁',
|
|
300
|
+
'speaker-off-16': '◃',
|
|
301
|
+
'speaker-on-16': '◂',
|
|
302
|
+
'speaker-up-16': '◂',
|
|
303
|
+
'speech-bubble-16': '⊐',
|
|
304
|
+
'speech-bubble-active-16': '⊐',
|
|
305
|
+
'speech-bubble-important-16': '⊐',
|
|
306
|
+
'square-ellipsis-16': '□',
|
|
307
|
+
'stacked-bars-1-16': '▁',
|
|
308
|
+
'stacked-bars-2-16': '▃',
|
|
309
|
+
'stacked-bars-3-16': '▅',
|
|
310
|
+
'stacked-bars-4-16': '▇',
|
|
311
|
+
'star-16': '★',
|
|
312
|
+
'star-circle-16': '★',
|
|
313
|
+
'star-disabled-16': '☆',
|
|
314
|
+
'stars-16': '✦',
|
|
315
|
+
'stop-16': '■',
|
|
316
|
+
'stop-filled-16': '■',
|
|
317
|
+
'stopwatch-16': '◴',
|
|
318
|
+
'store-16': '⊞',
|
|
319
|
+
'strike-through-16': 'S̶',
|
|
320
|
+
'sun-16': '※',
|
|
321
|
+
'sunrise-16': '※',
|
|
322
|
+
'swatch-16': '◧',
|
|
323
|
+
'switch-16': '⇋',
|
|
324
|
+
'syringe-16': '⊸',
|
|
325
|
+
'tack-16': '⊙',
|
|
326
|
+
'tack-disabled-16': '⊘',
|
|
327
|
+
'tag-16': '⊢',
|
|
328
|
+
'temperature-16': '⊥',
|
|
329
|
+
'tennis-ball-16': '◎',
|
|
330
|
+
'terminal-16': '>_',
|
|
331
|
+
'text-16': '𝐓',
|
|
332
|
+
'text-cursor-16': '⌶',
|
|
333
|
+
'text-input-16': '⌗',
|
|
334
|
+
'text-selection-16': '▮',
|
|
335
|
+
'thumbs-down-16': '⊘',
|
|
336
|
+
'thumbs-down-filled-16': '⊘',
|
|
337
|
+
'thumbs-up-16': '✓',
|
|
338
|
+
'thumbs-up-filled-16': '✓',
|
|
339
|
+
'ticket-16': '▬',
|
|
340
|
+
'torch-16': '※',
|
|
341
|
+
'train-16': '⊳',
|
|
342
|
+
'trash-16': '⌧',
|
|
343
|
+
'tray-16': '⊔',
|
|
344
|
+
'tree-16': '⊥',
|
|
345
|
+
'trophy-16': '⊛',
|
|
346
|
+
'two-people-16': '⊙',
|
|
347
|
+
'umbrella-16': '△',
|
|
348
|
+
'underline-16': 'U̲',
|
|
349
|
+
'undo-16': '↺',
|
|
350
|
+
'upload-16': '⤒',
|
|
351
|
+
'uppercase-16': 'Aᴬ',
|
|
352
|
+
'video-16': '▸',
|
|
353
|
+
'video-disabled-16': '⊘',
|
|
354
|
+
'wallet-16': '▬',
|
|
355
|
+
'wand-16': '✧',
|
|
356
|
+
'warning-16': '△',
|
|
357
|
+
'waveform-16': '∿',
|
|
358
|
+
'weights-16': '⊥',
|
|
359
|
+
'wifi-16': '⊛',
|
|
360
|
+
'wifi-disabled-16': '⊘',
|
|
361
|
+
'wind-16': '≋',
|
|
362
|
+
'windsock-16': '⊳',
|
|
363
|
+
'wrench-screwdriver-16': '⊤',
|
|
364
|
+
'wrist-watch-16': '◴',
|
|
365
|
+
'x-mark-circle-16': '×',
|
|
366
|
+
'x-mark-circle-filled-16': '×',
|
|
367
|
+
'x-mark-circle-half-dash-16': '×',
|
|
368
|
+
'x-mark-top-right-square-16': '×',
|
|
369
|
+
'xmark-16': '×',
|
|
370
|
+
}
|
|
15
371
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
372
|
+
// Number icons (number-00-16 through number-99-16) use circled numbers where available,
|
|
373
|
+
// falling back to the plain digit string for values without unicode circled forms.
|
|
374
|
+
for (let i = 0; i <= 99; i++) {
|
|
375
|
+
const id = `number-${String(i).padStart(2, '0')}-16`
|
|
376
|
+
if (i >= 0 && i <= 20) {
|
|
377
|
+
// Unicode circled numbers: ⓪①②…⑳
|
|
378
|
+
ICON_MAP[id] = String.fromCodePoint(i === 0 ? 0x24EA : 0x2460 + i - 1)
|
|
379
|
+
} else if (i <= 50) {
|
|
380
|
+
// Unicode circled numbers 21-50: ㉑㉒…㊿
|
|
381
|
+
ICON_MAP[id] = String.fromCodePoint(0x3251 + i - 21)
|
|
382
|
+
} else {
|
|
383
|
+
// No standard circled unicode above 50, use plain digits
|
|
384
|
+
ICON_MAP[id] = String(i)
|
|
22
385
|
}
|
|
23
|
-
return Math.abs(hash)
|
|
24
386
|
}
|
|
25
387
|
|
|
388
|
+
const FALLBACK_ICON = '●'
|
|
389
|
+
|
|
26
390
|
export function getIconShape(iconId: string): string {
|
|
27
|
-
|
|
28
|
-
const index = hash % ICON_SHAPES.length
|
|
29
|
-
return ICON_SHAPES[index]
|
|
391
|
+
return ICON_MAP[iconId] || FALLBACK_ICON
|
|
30
392
|
}
|
|
31
393
|
|
|
32
394
|
export const iconIds = [
|
|
@@ -591,7 +953,7 @@ export function getIconValue(icon: unknown): string {
|
|
|
591
953
|
|
|
592
954
|
// Handle { fileIcon: string }
|
|
593
955
|
if ('fileIcon' in obj && typeof obj.fileIcon === 'string') {
|
|
594
|
-
return '
|
|
956
|
+
return '▤'
|
|
595
957
|
}
|
|
596
958
|
|
|
597
959
|
// Unknown format - return empty string instead of [object Object]
|
package/src/components/list.tsx
CHANGED
|
@@ -81,30 +81,30 @@ function ListFooter(): any {
|
|
|
81
81
|
const hasDropdown = listContext?.hasDropdown ?? false
|
|
82
82
|
|
|
83
83
|
const content = hasToast ? null : (
|
|
84
|
-
<box style={{ flexDirection: 'row', gap: 3 }}>
|
|
84
|
+
<box style={{ flexDirection: 'row', gap: 3, flexShrink: 0 }}>
|
|
85
85
|
{firstActionTitle && (
|
|
86
|
-
<box style={{ flexDirection: 'row', gap: 1 }}>
|
|
86
|
+
<box style={{ flexDirection: 'row', gap: 1, flexShrink: 0 }}>
|
|
87
87
|
<text flexShrink={0} fg={theme.text} attributes={TextAttributes.BOLD}>
|
|
88
88
|
↵
|
|
89
89
|
</text>
|
|
90
90
|
<text flexShrink={0} fg={theme.textMuted}>{firstActionTitle.toLowerCase()}</text>
|
|
91
91
|
</box>
|
|
92
92
|
)}
|
|
93
|
-
<box style={{ flexDirection: 'row', gap: 1 }}>
|
|
93
|
+
<box style={{ flexDirection: 'row', gap: 1, flexShrink: 0 }}>
|
|
94
94
|
<text flexShrink={0} fg={theme.text} attributes={TextAttributes.BOLD}>
|
|
95
95
|
↑↓
|
|
96
96
|
</text>
|
|
97
97
|
<text flexShrink={0} fg={theme.textMuted}>navigate</text>
|
|
98
98
|
</box>
|
|
99
99
|
{hasDropdown && (
|
|
100
|
-
<box style={{ flexDirection: 'row', gap: 1 }}>
|
|
100
|
+
<box style={{ flexDirection: 'row', gap: 1, flexShrink: 0 }}>
|
|
101
101
|
<text flexShrink={0} fg={theme.text} attributes={TextAttributes.BOLD}>
|
|
102
102
|
^p
|
|
103
103
|
</text>
|
|
104
104
|
<text flexShrink={0} fg={theme.textMuted}>dropdown</text>
|
|
105
105
|
</box>
|
|
106
106
|
)}
|
|
107
|
-
<box style={{ flexDirection: 'row', gap: 1 }}>
|
|
107
|
+
<box style={{ flexDirection: 'row', gap: 1, flexShrink: 0 }}>
|
|
108
108
|
<text flexShrink={0} fg={theme.text} attributes={TextAttributes.BOLD}>
|
|
109
109
|
^k
|
|
110
110
|
</text>
|
|
@@ -774,8 +774,15 @@ export const List: ListType = (props) => {
|
|
|
774
774
|
} = props
|
|
775
775
|
|
|
776
776
|
const theme = useTheme()
|
|
777
|
+
const currentStackSelectedListIndex = useStore((state) => {
|
|
778
|
+
const stack = state.navigationStack
|
|
779
|
+
const currentItem = stack[stack.length - 1]
|
|
780
|
+
return currentItem?.selectedListIndex
|
|
781
|
+
})
|
|
777
782
|
const [internalSearchText, setInternalSearchText] = useState('')
|
|
778
|
-
const [selectedIndex, setSelectedIndex] = useState(
|
|
783
|
+
const [selectedIndex, setSelectedIndex] = useState<number>(() => {
|
|
784
|
+
return currentStackSelectedListIndex ?? 0
|
|
785
|
+
})
|
|
779
786
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
|
|
780
787
|
const [currentDetail, setCurrentDetail] = useState<ReactNode>(null)
|
|
781
788
|
|
|
@@ -845,6 +852,36 @@ export const List: ListType = (props) => {
|
|
|
845
852
|
setIsDropdownOpen(true)
|
|
846
853
|
}
|
|
847
854
|
|
|
855
|
+
const persistSelectedIndexInCurrentNavigationItem = (index: number) => {
|
|
856
|
+
useStore.setState((state) => {
|
|
857
|
+
const stack = state.navigationStack
|
|
858
|
+
const currentIndex = stack.length - 1
|
|
859
|
+
const currentItem = stack[currentIndex]
|
|
860
|
+
if (!currentItem) {
|
|
861
|
+
return {}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (currentItem.selectedListIndex === index) {
|
|
865
|
+
return {}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
const nextStack = [...stack]
|
|
869
|
+
nextStack[currentIndex] = {
|
|
870
|
+
...currentItem,
|
|
871
|
+
selectedListIndex: index,
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
return {
|
|
875
|
+
navigationStack: nextStack,
|
|
876
|
+
}
|
|
877
|
+
})
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
const setSelectedIndexWithPersistence = (index: number) => {
|
|
881
|
+
setSelectedIndex(index)
|
|
882
|
+
persistSelectedIndexInCurrentNavigationItem(index)
|
|
883
|
+
}
|
|
884
|
+
|
|
848
885
|
// Sync selection to the first visible item whenever searchText changes.
|
|
849
886
|
// Runs after children's useLayoutEffects (descendants registered) but before paint,
|
|
850
887
|
// so there is no intermediate frame with stale selection.
|
|
@@ -861,7 +898,7 @@ export const List: ListType = (props) => {
|
|
|
861
898
|
.sort((a, b) => a.index - b.index)
|
|
862
899
|
|
|
863
900
|
if (items.length > 0 && items[0]) {
|
|
864
|
-
|
|
901
|
+
setSelectedIndexWithPersistence(items[0].index)
|
|
865
902
|
}
|
|
866
903
|
})
|
|
867
904
|
|
|
@@ -871,7 +908,7 @@ export const List: ListType = (props) => {
|
|
|
871
908
|
setIsDropdownOpen,
|
|
872
909
|
openDropdown,
|
|
873
910
|
selectedIndex,
|
|
874
|
-
setSelectedIndex,
|
|
911
|
+
setSelectedIndex: setSelectedIndexWithPersistence,
|
|
875
912
|
searchText,
|
|
876
913
|
isFiltering: isFilteringEnabled,
|
|
877
914
|
setCurrentDetail,
|
|
@@ -899,7 +936,7 @@ export const List: ListType = (props) => {
|
|
|
899
936
|
|
|
900
937
|
const foundItem = items.find((item) => item.props?.id === selectedItemId)
|
|
901
938
|
if (foundItem) {
|
|
902
|
-
|
|
939
|
+
setSelectedIndexWithPersistence(foundItem.index)
|
|
903
940
|
}
|
|
904
941
|
}
|
|
905
942
|
}, [selectedItemId])
|
|
@@ -935,6 +972,21 @@ export const List: ListType = (props) => {
|
|
|
935
972
|
scrollBox.scrollTo(Math.max(0, targetScrollTop))
|
|
936
973
|
}
|
|
937
974
|
|
|
975
|
+
// Track whether onLoadMore has been called and we're waiting for new items.
|
|
976
|
+
// Reset when item count changes (new items arrived) so we can trigger again.
|
|
977
|
+
const paginationCalledRef = useRef(false)
|
|
978
|
+
const prevItemCountRef = useRef(0)
|
|
979
|
+
|
|
980
|
+
const triggerPaginationIfNeeded = (currentVisibleIndex: number, totalItems: number) => {
|
|
981
|
+
if (!props.pagination?.hasMore || paginationCalledRef.current) return
|
|
982
|
+
// Trigger when within 5 items of the end, matching Raycast's behavior
|
|
983
|
+
const threshold = Math.min(5, Math.max(1, Math.floor(totalItems * 0.2)))
|
|
984
|
+
if (totalItems - currentVisibleIndex <= threshold) {
|
|
985
|
+
paginationCalledRef.current = true
|
|
986
|
+
props.pagination.onLoadMore()
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
938
990
|
const move = (direction: -1 | 1) => {
|
|
939
991
|
// Get all visible items
|
|
940
992
|
const items = Object.values(descendantsContext.map.current)
|
|
@@ -943,6 +995,12 @@ export const List: ListType = (props) => {
|
|
|
943
995
|
|
|
944
996
|
if (items.length === 0) return
|
|
945
997
|
|
|
998
|
+
// Reset pagination lock when new items arrive
|
|
999
|
+
if (items.length !== prevItemCountRef.current) {
|
|
1000
|
+
prevItemCountRef.current = items.length
|
|
1001
|
+
paginationCalledRef.current = false
|
|
1002
|
+
}
|
|
1003
|
+
|
|
946
1004
|
// Find currently selected item's position in visible items
|
|
947
1005
|
let currentVisibleIndex = items.findIndex(
|
|
948
1006
|
(item) => item.index === selectedIndex,
|
|
@@ -950,13 +1008,21 @@ export const List: ListType = (props) => {
|
|
|
950
1008
|
if (currentVisibleIndex === -1) {
|
|
951
1009
|
// If current selection is not visible, select first visible item
|
|
952
1010
|
if (items[0]) {
|
|
953
|
-
|
|
1011
|
+
setSelectedIndexWithPersistence(items[0].index)
|
|
954
1012
|
}
|
|
955
1013
|
return
|
|
956
1014
|
}
|
|
957
1015
|
|
|
958
1016
|
// Calculate next visible index
|
|
959
1017
|
let nextVisibleIndex = currentVisibleIndex + direction
|
|
1018
|
+
|
|
1019
|
+
// When navigating past the end and pagination has more, don't wrap
|
|
1020
|
+
if (direction === 1 && nextVisibleIndex >= items.length && props.pagination?.hasMore) {
|
|
1021
|
+
triggerPaginationIfNeeded(currentVisibleIndex, items.length)
|
|
1022
|
+
// Stay on the last item instead of wrapping
|
|
1023
|
+
return
|
|
1024
|
+
}
|
|
1025
|
+
|
|
960
1026
|
if (nextVisibleIndex < 0) nextVisibleIndex = items.length - 1
|
|
961
1027
|
if (nextVisibleIndex >= items.length) nextVisibleIndex = 0
|
|
962
1028
|
|
|
@@ -965,7 +1031,11 @@ export const List: ListType = (props) => {
|
|
|
965
1031
|
flushSync(() => {
|
|
966
1032
|
setSelectedIndex(nextItem.index)
|
|
967
1033
|
})
|
|
1034
|
+
persistSelectedIndexInCurrentNavigationItem(nextItem.index)
|
|
968
1035
|
scrollToItem(nextItem)
|
|
1036
|
+
|
|
1037
|
+
// Check if we're approaching the end and should trigger pagination
|
|
1038
|
+
triggerPaginationIfNeeded(nextVisibleIndex, items.length)
|
|
969
1039
|
}
|
|
970
1040
|
}
|
|
971
1041
|
|
|
@@ -1107,10 +1177,11 @@ export const List: ListType = (props) => {
|
|
|
1107
1177
|
rootOptions: {
|
|
1108
1178
|
backgroundColor: undefined,
|
|
1109
1179
|
},
|
|
1180
|
+
viewportOptions: {
|
|
1181
|
+
paddingRight: 0,
|
|
1182
|
+
},
|
|
1110
1183
|
scrollbarOptions: {
|
|
1111
|
-
|
|
1112
|
-
showArrows: true,
|
|
1113
|
-
|
|
1184
|
+
visible: false,
|
|
1114
1185
|
},
|
|
1115
1186
|
}}
|
|
1116
1187
|
>
|