@portabletext/plugin-typeahead-picker 6.0.21 → 6.0.23
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 +21 -15
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# `@portabletext/plugin-typeahead-picker`
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Build typeahead pickers (emoji, mentions, slash commands) for the Portable Text Editor
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @portabletext/plugin-typeahead-picker
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
6
12
|
|
|
7
13
|
The `useTypeaheadPicker` hook provides the state and logic needed to build typeahead pickers (emoji pickers, mention pickers, slash commands, etc.) for the Portable Text Editor. It manages keyword matching, keyboard navigation, and triggering of actions, but is not concerned with the UI, how the picker is rendered, or how it's positioned in the document.
|
|
8
14
|
|
|
@@ -93,7 +99,7 @@ function MyEditor() {
|
|
|
93
99
|
|
|
94
100
|
The picker component must be rendered inside `EditorProvider` to access the editor context. Position it as a sibling to `PortableTextEditable` - you'll handle the visual positioning (popover, dropdown, etc.) separately with CSS or a positioning library.
|
|
95
101
|
|
|
96
|
-
## How
|
|
102
|
+
## How it works
|
|
97
103
|
|
|
98
104
|
The picker activates when users type the `trigger` pattern (e.g., `:` or `@`). The `keyword` pattern then matches characters typed after the trigger.
|
|
99
105
|
|
|
@@ -218,7 +224,7 @@ The guard is useful for:
|
|
|
218
224
|
- Avoiding conflicts when another picker or dialog is already open
|
|
219
225
|
- Checking editor state or mode before allowing the picker
|
|
220
226
|
|
|
221
|
-
## API
|
|
227
|
+
## API reference
|
|
222
228
|
|
|
223
229
|
### `defineTypeaheadPicker(config)`
|
|
224
230
|
|
|
@@ -289,11 +295,11 @@ React hook that activates a picker and returns its state.
|
|
|
289
295
|
| `send(event)` | Dispatch events: `{type: 'select'}`, `{type: 'dismiss'}`, `{type: 'navigate to', index}` |
|
|
290
296
|
| `snapshot.context.error` | Error from `getMatches` if it threw/rejected, otherwise `undefined` |
|
|
291
297
|
|
|
292
|
-
## Async
|
|
298
|
+
## Async mode
|
|
293
299
|
|
|
294
300
|
When `mode: 'async'` is configured, the picker handles asynchronous `getMatches` functions with loading states and race condition protection.
|
|
295
301
|
|
|
296
|
-
### Loading
|
|
302
|
+
### Loading states
|
|
297
303
|
|
|
298
304
|
Use `snapshot.matches()` to check nested loading states:
|
|
299
305
|
|
|
@@ -325,11 +331,11 @@ function MentionPicker() {
|
|
|
325
331
|
}
|
|
326
332
|
```
|
|
327
333
|
|
|
328
|
-
### Race
|
|
334
|
+
### Race condition handling
|
|
329
335
|
|
|
330
336
|
When users type quickly, earlier slow requests may complete after later fast requests. The picker automatically ignores stale results to prevent them from overwriting fresh data.
|
|
331
337
|
|
|
332
|
-
## Error
|
|
338
|
+
## Error handling
|
|
333
339
|
|
|
334
340
|
If `getMatches` throws or rejects, the error is captured in `snapshot.context.error`. The picker transitions to `'no matches'` state and continues to function.
|
|
335
341
|
|
|
@@ -404,9 +410,9 @@ const commandPicker = defineTypeaheadPicker<CommandMatch>({
|
|
|
404
410
|
| `event` | The select event with `match`, `keyword`, and `patternSelection` |
|
|
405
411
|
| `snapshot` | Current editor snapshot with `context.schema`, `context.keyGenerator()`, etc. |
|
|
406
412
|
|
|
407
|
-
## Performance
|
|
413
|
+
## Performance guidelines
|
|
408
414
|
|
|
409
|
-
### Match
|
|
415
|
+
### Match list size
|
|
410
416
|
|
|
411
417
|
Keep your match lists reasonably sized for smooth keyboard navigation:
|
|
412
418
|
|
|
@@ -421,7 +427,7 @@ getMatches: async ({keyword}) => {
|
|
|
421
427
|
}
|
|
422
428
|
```
|
|
423
429
|
|
|
424
|
-
### Debounce
|
|
430
|
+
### Debounce timing
|
|
425
431
|
|
|
426
432
|
Choose debounce values based on your data source:
|
|
427
433
|
|
|
@@ -452,7 +458,7 @@ const mentionPicker = defineTypeaheadPicker({
|
|
|
452
458
|
})
|
|
453
459
|
```
|
|
454
460
|
|
|
455
|
-
### Memory
|
|
461
|
+
### Memory considerations
|
|
456
462
|
|
|
457
463
|
- Avoid storing large datasets in component state
|
|
458
464
|
- For emoji pickers, consider lazy-loading the emoji database
|
|
@@ -462,7 +468,7 @@ const mentionPicker = defineTypeaheadPicker({
|
|
|
462
468
|
|
|
463
469
|
The picker manages keyboard navigation and selection internally, but you're responsible for the UI semantics.
|
|
464
470
|
|
|
465
|
-
### Recommended ARIA
|
|
471
|
+
### Recommended ARIA attributes
|
|
466
472
|
|
|
467
473
|
```tsx
|
|
468
474
|
function PickerUI() {
|
|
@@ -487,7 +493,7 @@ function PickerUI() {
|
|
|
487
493
|
}
|
|
488
494
|
```
|
|
489
495
|
|
|
490
|
-
### Keyboard
|
|
496
|
+
### Keyboard handling
|
|
491
497
|
|
|
492
498
|
The following keyboard shortcuts are handled automatically by the picker:
|
|
493
499
|
|
|
@@ -499,7 +505,7 @@ The following keyboard shortcuts are handled automatically by the picker:
|
|
|
499
505
|
| `Escape` | Dismiss picker |
|
|
500
506
|
| `Space` | Dismiss picker (configurable) |
|
|
501
507
|
|
|
502
|
-
### Screen
|
|
508
|
+
### Screen reader considerations
|
|
503
509
|
|
|
504
510
|
- Announce match count changes with live regions if desired
|
|
505
511
|
- Ensure selected item is visible (scroll into view)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/plugin-typeahead-picker",
|
|
3
|
-
"version": "6.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "6.0.23",
|
|
4
|
+
"description": "Build typeahead pickers (emoji, mentions, slash commands) for the Portable Text Editor",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"portabletext",
|
|
7
7
|
"plugin",
|
|
@@ -34,30 +34,30 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@xstate/react": "^6.1.0",
|
|
36
36
|
"xstate": "^5.32.1",
|
|
37
|
-
"@portabletext/keyboard-shortcuts": "^2.1.
|
|
38
|
-
"@portabletext/plugin-input-rule": "^5.0.
|
|
37
|
+
"@portabletext/keyboard-shortcuts": "^2.1.3",
|
|
38
|
+
"@portabletext/plugin-input-rule": "^5.0.23"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@sanity/pkg-utils": "^10.2.1",
|
|
42
42
|
"@sanity/tsconfig": "^2.1.0",
|
|
43
|
-
"@types/react": "^19.2.
|
|
43
|
+
"@types/react": "^19.2.17",
|
|
44
44
|
"@vitejs/plugin-react": "^5.2.0",
|
|
45
|
-
"@vitest/browser": "^4.1.
|
|
46
|
-
"@vitest/browser-playwright": "^4.1.
|
|
45
|
+
"@vitest/browser": "^4.1.9",
|
|
46
|
+
"@vitest/browser-playwright": "^4.1.9",
|
|
47
47
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
48
48
|
"eslint": "^9.39.1",
|
|
49
49
|
"eslint-formatter-gha": "^1.6.0",
|
|
50
50
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
51
|
-
"react": "^19.2.
|
|
51
|
+
"react": "^19.2.7",
|
|
52
52
|
"typescript": "5.9.3",
|
|
53
53
|
"typescript-eslint": "^8.48.0",
|
|
54
|
-
"vitest": "^4.1.
|
|
55
|
-
"@portabletext/editor": "^7.
|
|
56
|
-
"@portabletext/schema": "2.2.
|
|
57
|
-
"racejar": "2.0.
|
|
54
|
+
"vitest": "^4.1.9",
|
|
55
|
+
"@portabletext/editor": "^7.8.0",
|
|
56
|
+
"@portabletext/schema": "2.2.2",
|
|
57
|
+
"racejar": "2.0.9"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@portabletext/editor": "^7.
|
|
60
|
+
"@portabletext/editor": "^7.8.0",
|
|
61
61
|
"react": "^19.2"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|