@srothgan/sanity-plugin-autocomplete-input 3.0.0 → 3.0.2
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/LICENSE +7 -0
- package/README.md +197 -121
- package/lib/AutoCompleteInput.js +23 -20
- package/package.json +82 -63
- package/lib/src/AutoCompleteInput.js +0 -87
- package/lib/src/index.js +0 -10
- package/lib/src/schemas/autocompleteString.js +0 -11
- package/lib/src/types/InputOptions.js +0 -1
- package/lib/src/types/Option.js +0 -1
- package/lib/src/types/index.js +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright © 2025 Simon Peter Rothgang
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,121 +1,197 @@
|
|
|
1
|
-
# @srothgan/sanity-plugin-autocomplete-input
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@srothgan/sanity-plugin-autocomplete-input)
|
|
4
|
-
[](https://github.com/LiamMartens/sanity-plugin-autocomplete-input)
|
|
5
|
-
|
|
6
|
-

|
|
7
|
-
|
|
8
|
-
This plugin is similar to the [Autocomplete Tags Plugin](https://www.sanity.io/plugins/autocomplete-tags), but it acts as a single text input as opposed to an array of tags. The input can also be customized to change the autocomplete options.
|
|
9
|
-
|
|
10
|
-
**Successor to [sanity-plugin-autocomplete-input](https://github.com/LiamMartens/sanity-plugin-autocomplete-input)**
|
|
11
|
-
Original by [@LiamMartens](https://github.com/LiamMartens) (last updated 2023).
|
|
12
|
-
This maintained fork adds Sanity v4 & v5 compatibility and modern tooling.
|
|
13
|
-
|
|
14
|
-
> **Note**: A PR with these changes was submitted to the original repository.
|
|
15
|
-
> If the original becomes active again, this fork may redirect users back.
|
|
16
|
-
|
|
17
|
-
## Compatibility
|
|
18
|
-
|
|
19
|
-
- **v3.x:** Sanity Studio v4 & v5 (Node.js v20.19+, React 18 or 19)
|
|
20
|
-
- Fully compatible with both Sanity v4 and v5
|
|
21
|
-
- Supports React 18 (Sanity v4) and React 19 (Sanity v5)
|
|
22
|
-
- **v2.x:** Sanity Studio v3 (Node.js v18+, React 18)
|
|
23
|
-
- **v1.x:** Sanity Studio v2
|
|
24
|
-
|
|
25
|
-
## Installation
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
npm install --save @srothgan/sanity-plugin-autocomplete-input
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
or
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
yarn add @srothgan/sanity-plugin-autocomplete-input
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Usage
|
|
38
|
-
|
|
39
|
-
Add it as a plugin in sanity.config.ts (or .js):
|
|
40
|
-
|
|
41
|
-
```js
|
|
42
|
-
import { autocompletInput } from "@srothgan/sanity-plugin-autocomplete-input";
|
|
43
|
-
|
|
44
|
-
export default defineConfig({
|
|
45
|
-
// ...
|
|
46
|
-
plugins: [autocompletInput()],
|
|
47
|
-
});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
You can just use it as a schema type. To customize the autocomplete list you have 3 options:
|
|
51
|
-
|
|
52
|
-
1. Specify the `autocompleteFieldPath` option, which the plugin will use to look for documents with the same field path to aggregate the option values.
|
|
53
|
-
2. Manually specify options in the schema option
|
|
54
|
-
3. Specify your own GROQ query returning a `[{ "value": "foobar" }]` format (you can use a `transform` function if this is not achievable using GROQ only)
|
|
55
|
-
|
|
56
|
-
```javascript
|
|
57
|
-
export default {
|
|
58
|
-
fields: [
|
|
59
|
-
{
|
|
60
|
-
name: "autocomplete-input",
|
|
61
|
-
type: "autocomplete",
|
|
62
|
-
options: {
|
|
63
|
-
// specify field path
|
|
64
|
-
autocompleteFieldPath: "title",
|
|
65
|
-
// this option can be used to disable using "new" values
|
|
66
|
-
disableNew: false,
|
|
67
|
-
// manually specify options
|
|
68
|
-
options: [{ value: "Option 1" }, { value: "Option 2" }],
|
|
69
|
-
// specify custom groq query
|
|
70
|
-
groq: {
|
|
71
|
-
query: '*[_type == $type] { "value": title }',
|
|
72
|
-
params: {
|
|
73
|
-
type: "page",
|
|
74
|
-
},
|
|
75
|
-
transform: (values) => values,
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
};
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Advanced GROQ parameters
|
|
84
|
-
|
|
85
|
-
It is also possible to refer to the current parent value (for a top-level field this would be the current document) by passing a function to the `params` option:
|
|
86
|
-
|
|
87
|
-
```javascript
|
|
88
|
-
export default {
|
|
89
|
-
fields: [
|
|
90
|
-
{
|
|
91
|
-
name: "autocomplete-input",
|
|
92
|
-
type: "autocomplete",
|
|
93
|
-
options: {
|
|
94
|
-
groq: {
|
|
95
|
-
query: "*[_id != $docId]",
|
|
96
|
-
params: (parent) => ({
|
|
97
|
-
docId: parent?._id,
|
|
98
|
-
}),
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
],
|
|
103
|
-
};
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Differences from Original
|
|
107
|
-
|
|
108
|
-
This maintained fork includes the following enhancements:
|
|
109
|
-
|
|
110
|
-
### Updated Dependencies
|
|
111
|
-
- **Sanity v4 & v5 Support**: Fully compatible with both Sanity Studio v4 and v5
|
|
112
|
-
- **React 18 & 19 Support**: Works with React 18 (Sanity v4) and React 19 (Sanity v5)
|
|
113
|
-
- **Modern Build Tooling**: Migrated from Babel to SWC for faster builds
|
|
114
|
-
- **TypeScript 5.3**: Updated to latest TypeScript with improved type safety
|
|
115
|
-
|
|
116
|
-
### Maintained & Active
|
|
117
|
-
- Regular dependency updates for security and compatibility
|
|
118
|
-
- Active issue tracking and bug fixes
|
|
119
|
-
- Community-driven improvements
|
|
120
|
-
|
|
121
|
-
All original functionality and API remain unchanged for seamless migration.
|
|
1
|
+
# @srothgan/sanity-plugin-autocomplete-input
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@srothgan/sanity-plugin-autocomplete-input)
|
|
4
|
+
[](https://github.com/LiamMartens/sanity-plugin-autocomplete-input)
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
This plugin is similar to the [Autocomplete Tags Plugin](https://www.sanity.io/plugins/autocomplete-tags), but it acts as a single text input as opposed to an array of tags. The input can also be customized to change the autocomplete options.
|
|
9
|
+
|
|
10
|
+
**Successor to [sanity-plugin-autocomplete-input](https://github.com/LiamMartens/sanity-plugin-autocomplete-input)**
|
|
11
|
+
Original by [@LiamMartens](https://github.com/LiamMartens) (last updated 2023).
|
|
12
|
+
This maintained fork adds Sanity v4 & v5 compatibility and modern tooling.
|
|
13
|
+
|
|
14
|
+
> **Note**: A PR with these changes was submitted to the original repository.
|
|
15
|
+
> If the original becomes active again, this fork may redirect users back.
|
|
16
|
+
|
|
17
|
+
## Compatibility
|
|
18
|
+
|
|
19
|
+
- **v3.x:** Sanity Studio v4 & v5 (Node.js v20.19+, React 18 or 19)
|
|
20
|
+
- Fully compatible with both Sanity v4 and v5
|
|
21
|
+
- Supports React 18 (Sanity v4) and React 19 (Sanity v5)
|
|
22
|
+
- **v2.x:** Sanity Studio v3 (Node.js v18+, React 18)
|
|
23
|
+
- **v1.x:** Sanity Studio v2
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
npm install --save @srothgan/sanity-plugin-autocomplete-input
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
or
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
yarn add @srothgan/sanity-plugin-autocomplete-input
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
Add it as a plugin in sanity.config.ts (or .js):
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { autocompletInput } from "@srothgan/sanity-plugin-autocomplete-input";
|
|
43
|
+
|
|
44
|
+
export default defineConfig({
|
|
45
|
+
// ...
|
|
46
|
+
plugins: [autocompletInput()],
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
You can just use it as a schema type. To customize the autocomplete list you have 3 options:
|
|
51
|
+
|
|
52
|
+
1. Specify the `autocompleteFieldPath` option, which the plugin will use to look for documents with the same field path to aggregate the option values.
|
|
53
|
+
2. Manually specify options in the schema option
|
|
54
|
+
3. Specify your own GROQ query returning a `[{ "value": "foobar" }]` format (you can use a `transform` function if this is not achievable using GROQ only)
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
export default {
|
|
58
|
+
fields: [
|
|
59
|
+
{
|
|
60
|
+
name: "autocomplete-input",
|
|
61
|
+
type: "autocomplete",
|
|
62
|
+
options: {
|
|
63
|
+
// specify field path
|
|
64
|
+
autocompleteFieldPath: "title",
|
|
65
|
+
// this option can be used to disable using "new" values
|
|
66
|
+
disableNew: false,
|
|
67
|
+
// manually specify options
|
|
68
|
+
options: [{ value: "Option 1" }, { value: "Option 2" }],
|
|
69
|
+
// specify custom groq query
|
|
70
|
+
groq: {
|
|
71
|
+
query: '*[_type == $type] { "value": title }',
|
|
72
|
+
params: {
|
|
73
|
+
type: "page",
|
|
74
|
+
},
|
|
75
|
+
transform: (values) => values,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Advanced GROQ parameters
|
|
84
|
+
|
|
85
|
+
It is also possible to refer to the current parent value (for a top-level field this would be the current document) by passing a function to the `params` option:
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
export default {
|
|
89
|
+
fields: [
|
|
90
|
+
{
|
|
91
|
+
name: "autocomplete-input",
|
|
92
|
+
type: "autocomplete",
|
|
93
|
+
options: {
|
|
94
|
+
groq: {
|
|
95
|
+
query: "*[_id != $docId]",
|
|
96
|
+
params: (parent) => ({
|
|
97
|
+
docId: parent?._id,
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Differences from Original
|
|
107
|
+
|
|
108
|
+
This maintained fork includes the following enhancements:
|
|
109
|
+
|
|
110
|
+
### Updated Dependencies
|
|
111
|
+
- **Sanity v4 & v5 Support**: Fully compatible with both Sanity Studio v4 and v5
|
|
112
|
+
- **React 18 & 19 Support**: Works with React 18 (Sanity v4) and React 19 (Sanity v5)
|
|
113
|
+
- **Modern Build Tooling**: Migrated from Babel to SWC for faster builds
|
|
114
|
+
- **TypeScript 5.3**: Updated to latest TypeScript with improved type safety
|
|
115
|
+
|
|
116
|
+
### Maintained & Active
|
|
117
|
+
- Regular dependency updates for security and compatibility
|
|
118
|
+
- Active issue tracking and bug fixes
|
|
119
|
+
- Community-driven improvements
|
|
120
|
+
|
|
121
|
+
All original functionality and API remain unchanged for seamless migration.
|
|
122
|
+
|
|
123
|
+
## TypeScript Usage
|
|
124
|
+
|
|
125
|
+
The plugin is written in TypeScript and exports all necessary types:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { defineConfig } from 'sanity'
|
|
129
|
+
import { autocompletInput } from '@srothgan/sanity-plugin-autocomplete-input'
|
|
130
|
+
import type { InputOptions } from '@srothgan/sanity-plugin-autocomplete-input'
|
|
131
|
+
|
|
132
|
+
export default defineConfig({
|
|
133
|
+
// ...
|
|
134
|
+
plugins: [autocompletInput()],
|
|
135
|
+
schema: {
|
|
136
|
+
types: [
|
|
137
|
+
{
|
|
138
|
+
name: 'myDocument',
|
|
139
|
+
type: 'document',
|
|
140
|
+
fields: [
|
|
141
|
+
{
|
|
142
|
+
name: 'category',
|
|
143
|
+
type: 'autocomplete',
|
|
144
|
+
options: {
|
|
145
|
+
autocompleteFieldPath: 'category',
|
|
146
|
+
disableNew: false,
|
|
147
|
+
} satisfies InputOptions,
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Troubleshooting
|
|
157
|
+
|
|
158
|
+
### Plugin not appearing in Studio
|
|
159
|
+
Make sure you've added the plugin to your `sanity.config.ts`:
|
|
160
|
+
```typescript
|
|
161
|
+
import { autocompletInput } from '@srothgan/sanity-plugin-autocomplete-input'
|
|
162
|
+
|
|
163
|
+
export default defineConfig({
|
|
164
|
+
plugins: [autocompletInput()],
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Autocomplete options not loading
|
|
169
|
+
- Verify your GROQ query returns data in the format `[{ "value": "..." }]`
|
|
170
|
+
- Check the browser console for any query errors
|
|
171
|
+
- Ensure the `autocompleteFieldPath` matches an existing field in your documents
|
|
172
|
+
|
|
173
|
+
### TypeScript errors
|
|
174
|
+
Make sure your `tsconfig.json` includes:
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"compilerOptions": {
|
|
178
|
+
"moduleResolution": "node",
|
|
179
|
+
"esModuleInterop": true
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Contributing
|
|
185
|
+
|
|
186
|
+
Contributions are welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to contribute to this project.
|
|
187
|
+
|
|
188
|
+
## Changelog
|
|
189
|
+
|
|
190
|
+
See [CHANGELOG.md](./CHANGELOG.md) for a list of changes and version history.
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
195
|
+
|
|
196
|
+
Original work by [Liam Martens](https://github.com/LiamMartens)
|
|
197
|
+
Maintained fork by [Simon Rothgang](https://github.com/srothgan)
|
package/lib/AutoCompleteInput.js
CHANGED
|
@@ -35,7 +35,7 @@ export const AutoCompleteInput = (props)=>{
|
|
|
35
35
|
canCreateNew
|
|
36
36
|
]);
|
|
37
37
|
const handleQueryChange = useCallback((query)=>{
|
|
38
|
-
setQuery(query ??
|
|
38
|
+
setQuery(query ?? "");
|
|
39
39
|
}, []);
|
|
40
40
|
const handleChange = useCallback((value)=>{
|
|
41
41
|
onChange(PatchEvent.from(value ? set(value) : unset()));
|
|
@@ -44,28 +44,31 @@ export const AutoCompleteInput = (props)=>{
|
|
|
44
44
|
]);
|
|
45
45
|
useEffect(()=>{
|
|
46
46
|
if (schemaType.options?.options) {
|
|
47
|
-
|
|
47
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
48
48
|
setOptions(schemaType.options.options);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const { query, transform, params = {} } = schemaType.options?.groq || {
|
|
52
|
-
query: `*[defined(${path})] { "value": ${path} }`
|
|
53
|
-
};
|
|
54
|
-
const resolvedParams = typeof params === "function" ? params(documentValue) : params;
|
|
55
|
-
sanityClient.fetch(query, resolvedParams).then((results)=>{
|
|
56
|
-
if (Array.isArray(results)) {
|
|
57
|
-
const transformedResults = transform ? transform(results) : results;
|
|
58
|
-
const compactedValues = compact(transformedResults.map((doc)=>get(doc, "value")));
|
|
59
|
-
setLoading(false);
|
|
60
|
-
setOptions(compactedValues.map((value)=>({
|
|
61
|
-
value: String(value)
|
|
62
|
-
})));
|
|
63
|
-
}
|
|
64
|
-
});
|
|
49
|
+
setLoading(false);
|
|
50
|
+
return;
|
|
65
51
|
}
|
|
52
|
+
const path = schemaType.options?.autocompleteFieldPath ?? "title";
|
|
53
|
+
const { query, transform, params = {} } = schemaType.options?.groq || {
|
|
54
|
+
query: `*[defined(${path})] { "value": ${path} }`
|
|
55
|
+
};
|
|
56
|
+
const resolvedParams = typeof params === "function" ? params(documentValue) : params;
|
|
57
|
+
setLoading(true);
|
|
58
|
+
sanityClient.fetch(query, resolvedParams).then((results)=>{
|
|
59
|
+
if (Array.isArray(results)) {
|
|
60
|
+
const transformedResults = transform ? transform(results) : results;
|
|
61
|
+
const compactedValues = compact(transformedResults.map((doc)=>get(doc, "value")));
|
|
62
|
+
setOptions(compactedValues.map((value)=>({
|
|
63
|
+
value: String(value)
|
|
64
|
+
})));
|
|
65
|
+
setLoading(false);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
66
68
|
}, [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
schemaType.options,
|
|
70
|
+
documentValue,
|
|
71
|
+
sanityClient
|
|
69
72
|
]);
|
|
70
73
|
return /*#__PURE__*/ React.createElement(Autocomplete, {
|
|
71
74
|
id: id,
|
package/package.json
CHANGED
|
@@ -1,63 +1,82 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@srothgan/sanity-plugin-autocomplete-input",
|
|
3
|
-
"version": "3.0.
|
|
4
|
-
"license": "MIT",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"sanity"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@srothgan/sanity-plugin-autocomplete-input",
|
|
3
|
+
"version": "3.0.2",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build:js": "swc ./src -d ./lib --strip-leading-paths",
|
|
8
|
+
"build:types": "tsc -p .",
|
|
9
|
+
"build": "run-p build:*",
|
|
10
|
+
"lint": "eslint src/**/*.{ts,tsx}",
|
|
11
|
+
"lint:fix": "eslint src/**/*.{ts,tsx} --fix",
|
|
12
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,json}\"",
|
|
13
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx,json}\""
|
|
14
|
+
},
|
|
15
|
+
"types": "./lib/index.d.ts",
|
|
16
|
+
"module": "./lib/index.js",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./lib/index.d.ts",
|
|
20
|
+
"import": "./lib/index.js",
|
|
21
|
+
"default": "./lib/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"browserslist": "> 0.5%, last 2 versions, not dead",
|
|
25
|
+
"files": [
|
|
26
|
+
"lib"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/srothgan/srothgan-sanity-plugin-autocomplete-input"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/srothgan/srothgan-sanity-plugin-autocomplete-input/issues"
|
|
34
|
+
},
|
|
35
|
+
"author": {
|
|
36
|
+
"name": "Simon Rothgang",
|
|
37
|
+
"email": "simonrothgang@gmail.com"
|
|
38
|
+
},
|
|
39
|
+
"contributors": [
|
|
40
|
+
{
|
|
41
|
+
"name": "Liam Martens",
|
|
42
|
+
"email": "liam@freighter.studio",
|
|
43
|
+
"url": "https://github.com/LiamMartens"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"keywords": [
|
|
47
|
+
"sanity-plugin",
|
|
48
|
+
"autocomplete",
|
|
49
|
+
"v4",
|
|
50
|
+
"v5",
|
|
51
|
+
"maintained",
|
|
52
|
+
"input",
|
|
53
|
+
"sanity-v5"
|
|
54
|
+
],
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@eslint/js": "^9.39.2",
|
|
57
|
+
"@sanity/ui": "^3.1.11",
|
|
58
|
+
"@swc/cli": "^0.7.9",
|
|
59
|
+
"@swc/core": "^1.3.99",
|
|
60
|
+
"@types/node": "^20.19.0",
|
|
61
|
+
"@types/react": "^18.2.38",
|
|
62
|
+
"@types/react-dom": "^18.2.17",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
64
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
65
|
+
"eslint": "^9.39.2",
|
|
66
|
+
"eslint-config-prettier": "^10.1.8",
|
|
67
|
+
"eslint-plugin-react": "^7.37.5",
|
|
68
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
69
|
+
"npm-run-all": "^4.1.5",
|
|
70
|
+
"react": "^19.2.3",
|
|
71
|
+
"react-dom": "^19.2.3",
|
|
72
|
+
"sanity": "^5.1.0",
|
|
73
|
+
"styled-components": "^6.1.19",
|
|
74
|
+
"typescript": "~5.3.2"
|
|
75
|
+
},
|
|
76
|
+
"dependencies": {
|
|
77
|
+
"just-compact": "^3.2.0",
|
|
78
|
+
"just-pick": "^4.2.0",
|
|
79
|
+
"just-safe-get": "^4.2.0",
|
|
80
|
+
"just-unique": "^4.2.0"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
-
import get from "just-safe-get";
|
|
3
|
-
import compact from "just-compact";
|
|
4
|
-
import unique from "just-unique";
|
|
5
|
-
import { Autocomplete, Text, Card } from "@sanity/ui";
|
|
6
|
-
import { PatchEvent, set, unset, useClient, useFormValue } from "sanity";
|
|
7
|
-
export const AutoCompleteInput = (props)=>{
|
|
8
|
-
const { id, schemaType, value, validationError, readOnly, onChange } = props;
|
|
9
|
-
const sanityClient = useClient();
|
|
10
|
-
const documentValue = useFormValue([]);
|
|
11
|
-
const [loading, setLoading] = useState(false);
|
|
12
|
-
const [query, setQuery] = React.useState("");
|
|
13
|
-
const [options, setOptions] = React.useState([]);
|
|
14
|
-
const canCreateNew = schemaType.options?.disableNew !== true;
|
|
15
|
-
const optionsList = useMemo(()=>{
|
|
16
|
-
const uniqueOptions = unique(options.map(({ value })=>value), false, true);
|
|
17
|
-
const queryInOptions = uniqueOptions.find((value)=>value === query);
|
|
18
|
-
if (!queryInOptions && canCreateNew) {
|
|
19
|
-
return [
|
|
20
|
-
...uniqueOptions.map((value)=>({
|
|
21
|
-
value
|
|
22
|
-
})),
|
|
23
|
-
{
|
|
24
|
-
value: query,
|
|
25
|
-
isNew: true
|
|
26
|
-
}
|
|
27
|
-
];
|
|
28
|
-
}
|
|
29
|
-
return uniqueOptions.map((value)=>({
|
|
30
|
-
value
|
|
31
|
-
}));
|
|
32
|
-
}, [
|
|
33
|
-
query,
|
|
34
|
-
options,
|
|
35
|
-
canCreateNew
|
|
36
|
-
]);
|
|
37
|
-
const handleQueryChange = useCallback((query)=>{
|
|
38
|
-
setQuery(query ?? '');
|
|
39
|
-
}, []);
|
|
40
|
-
const handleChange = useCallback((value)=>{
|
|
41
|
-
onChange(PatchEvent.from(value ? set(value) : unset()));
|
|
42
|
-
}, [
|
|
43
|
-
onChange
|
|
44
|
-
]);
|
|
45
|
-
useEffect(()=>{
|
|
46
|
-
if (schemaType.options?.options) {
|
|
47
|
-
setLoading(false);
|
|
48
|
-
setOptions(schemaType.options.options);
|
|
49
|
-
} else {
|
|
50
|
-
const path = schemaType.options?.autocompleteFieldPath ?? "title";
|
|
51
|
-
const { query, transform, params = {} } = schemaType.options?.groq || {
|
|
52
|
-
query: `*[defined(${path})] { "value": ${path} }`
|
|
53
|
-
};
|
|
54
|
-
const resolvedParams = typeof params === "function" ? params(documentValue) : params;
|
|
55
|
-
sanityClient.fetch(query, resolvedParams).then((results)=>{
|
|
56
|
-
if (Array.isArray(results)) {
|
|
57
|
-
const transformedResults = transform ? transform(results) : results;
|
|
58
|
-
const compactedValues = compact(transformedResults.map((doc)=>get(doc, "value")));
|
|
59
|
-
setLoading(false);
|
|
60
|
-
setOptions(compactedValues.map((value)=>({
|
|
61
|
-
value: String(value)
|
|
62
|
-
})));
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}, [
|
|
67
|
-
query,
|
|
68
|
-
schemaType.options
|
|
69
|
-
]);
|
|
70
|
-
return /*#__PURE__*/ React.createElement(Autocomplete, {
|
|
71
|
-
id: id,
|
|
72
|
-
readOnly: readOnly ?? false,
|
|
73
|
-
customValidity: validationError,
|
|
74
|
-
loading: loading,
|
|
75
|
-
disabled: loading,
|
|
76
|
-
options: optionsList,
|
|
77
|
-
value: value ?? "",
|
|
78
|
-
onChange: handleChange,
|
|
79
|
-
onQueryChange: handleQueryChange,
|
|
80
|
-
renderOption: (option)=>/*#__PURE__*/ React.createElement(Card, {
|
|
81
|
-
as: "button",
|
|
82
|
-
padding: 3,
|
|
83
|
-
tone: option.isNew ? "primary" : "default",
|
|
84
|
-
shadow: 1
|
|
85
|
-
}, option.isNew ? canCreateNew && /*#__PURE__*/ React.createElement(Text, null, 'Create new option "', option.value, '"') : /*#__PURE__*/ React.createElement(Text, null, option.value))
|
|
86
|
-
});
|
|
87
|
-
};
|
package/lib/src/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { defineType } from "sanity";
|
|
2
|
-
import { AutoCompleteInput } from "../AutoCompleteInput";
|
|
3
|
-
const typeName = "autocomplete";
|
|
4
|
-
export const autocompleteString = defineType({
|
|
5
|
-
name: typeName,
|
|
6
|
-
type: "string",
|
|
7
|
-
title: "Autocomplete",
|
|
8
|
-
components: {
|
|
9
|
-
input: AutoCompleteInput
|
|
10
|
-
}
|
|
11
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
package/lib/src/types/Option.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
package/lib/src/types/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|