@unocss/autocomplete 0.29.0 → 0.29.3
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 +66 -2
- package/dist/index.cjs +54 -28
- package/dist/index.d.ts +4 -2
- package/dist/index.mjs +54 -30
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,8 +1,72 @@
|
|
|
1
1
|
# @unocss/autocomplete
|
|
2
2
|
|
|
3
|
-
Autocomplete utils for UnoCSS.
|
|
3
|
+
Autocomplete utils for UnoCSS. This is embedded in [the playground](https://unocss.antfu.me/) and [the VS Code extension](https://github.com/unocss/unocss/tree/main/packages/vscode).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Syntax
|
|
6
|
+
|
|
7
|
+
To add autocomplete support to your custom rules:
|
|
8
|
+
|
|
9
|
+
### Static Rules
|
|
10
|
+
|
|
11
|
+
Static rules like this will just works without any configuration.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
rules: [
|
|
15
|
+
['flex', { display: 'flex' }]
|
|
16
|
+
]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Dynamic Rules
|
|
20
|
+
|
|
21
|
+
For dynamic rules, you can provide an extra `meta` object to the rule and specify the autocomplete template.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
rules: [
|
|
25
|
+
[
|
|
26
|
+
/^m-(\d)$/,
|
|
27
|
+
([, d]) => ({ margin: `${d / 4}rem` }),
|
|
28
|
+
{ autocomplete: 'm-<num>' }, // <-- this
|
|
29
|
+
],
|
|
30
|
+
]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The template uses a simle DSL to specify the autocomplete suggestions. The syntax is:
|
|
34
|
+
|
|
35
|
+
- `(...|...)`: logic OR groups. `|` as the separator. Will be used as suggestions when the some of the groups match.
|
|
36
|
+
- `<...>`: built-in short hands. currently supports `<num>`, `<percent>` and `<directions>`
|
|
37
|
+
- `$...`: theme infering. for example, `$colors` will list all the properties of the `colors` object of the theme.
|
|
38
|
+
|
|
39
|
+
For examples:
|
|
40
|
+
|
|
41
|
+
###### Example 1
|
|
42
|
+
|
|
43
|
+
- **Template**: `(border|b)-(solid|dashed|dotted|double|hidden|none)`
|
|
44
|
+
- **Input**: `b-do`
|
|
45
|
+
- **Suggestions**: `b-dashed`, `b-double`
|
|
46
|
+
|
|
47
|
+
###### Example 2
|
|
48
|
+
|
|
49
|
+
- **Template**: `m-<num>`
|
|
50
|
+
- **Input**: `m-`
|
|
51
|
+
- **Suggestions**: `m-1`, `m-2`, `m-3` ...
|
|
52
|
+
|
|
53
|
+
###### Example 3
|
|
54
|
+
|
|
55
|
+
- **Template**: `text-$colors`
|
|
56
|
+
- **Input**: `text-r`
|
|
57
|
+
- **Suggestions**: `text-red`, `text-rose` ...
|
|
58
|
+
|
|
59
|
+
###### Example 4
|
|
60
|
+
|
|
61
|
+
For multiple templates
|
|
62
|
+
|
|
63
|
+
- **Template**: `['(border|b)-<num>', '(border|b)-<directions>-<num>']`
|
|
64
|
+
|
|
65
|
+
- **Input**: `b-`
|
|
66
|
+
- **Suggestions**: `b-x`, `b-y`, `b-1`, `b-2` ...
|
|
67
|
+
|
|
68
|
+
- **Input**: `b-x-`
|
|
69
|
+
- **Suggestions**: `b-x-1`, `b-x-2` ...
|
|
6
70
|
|
|
7
71
|
## License
|
|
8
72
|
|
package/dist/index.cjs
CHANGED
|
@@ -11,9 +11,10 @@ const LRU__default = /*#__PURE__*/_interopDefaultLegacy(LRU);
|
|
|
11
11
|
|
|
12
12
|
const shorthands = {
|
|
13
13
|
num: `(${[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 24, 36].join("|")})`,
|
|
14
|
-
|
|
14
|
+
percent: `(${Array.from({ length: 11 }, (_, i) => i * 10).join("|")})`,
|
|
15
15
|
directions: "(x|y|t|b|l|r|s|e)"
|
|
16
16
|
};
|
|
17
|
+
const ignoredThemeKeys = ["DEFAULT"];
|
|
17
18
|
function handleRegexMatch(str, regex, onMatched, onNotMatched) {
|
|
18
19
|
let lastIndex = 0;
|
|
19
20
|
Array.from(str.matchAll(regex)).forEach((m) => {
|
|
@@ -40,10 +41,9 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
40
41
|
};
|
|
41
42
|
function handleNonGroup(input) {
|
|
42
43
|
handleRegexMatch(input, /\$([\w\|]+)/g, (m) => {
|
|
43
|
-
const keys = m[1].split("|");
|
|
44
44
|
parts.push({
|
|
45
45
|
type: "theme",
|
|
46
|
-
objects:
|
|
46
|
+
objects: m[1].split("|").map((i) => {
|
|
47
47
|
if (!i || !theme[i])
|
|
48
48
|
throw new Error(`Invalid theme key ${i}`);
|
|
49
49
|
return theme[i];
|
|
@@ -74,8 +74,14 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
74
74
|
while (tempParts.length) {
|
|
75
75
|
const part = tempParts.shift();
|
|
76
76
|
if (part.type === "static") {
|
|
77
|
-
if (
|
|
77
|
+
if (combinations.length)
|
|
78
|
+
combinations = combinations.map((i) => i + part.value);
|
|
79
|
+
if (part.value.startsWith(rest) && part.value !== rest && !combinations.length) {
|
|
80
|
+
combinations = [part.value];
|
|
78
81
|
break;
|
|
82
|
+
} else if (!rest.startsWith(part.value)) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
79
85
|
matched += part.value;
|
|
80
86
|
rest = rest.slice(part.value.length);
|
|
81
87
|
} else if (part.type === "group") {
|
|
@@ -85,10 +91,11 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
85
91
|
rest = rest.slice(fullMatched.length);
|
|
86
92
|
} else {
|
|
87
93
|
combinations = part.values.filter((i) => i.startsWith(rest));
|
|
88
|
-
|
|
94
|
+
if (tempParts[0]?.type !== "static")
|
|
95
|
+
break;
|
|
89
96
|
}
|
|
90
97
|
} else if (part.type === "theme") {
|
|
91
|
-
const keys = part.objects.flatMap((i) => Object.keys(i));
|
|
98
|
+
const keys = part.objects.flatMap((i) => Object.keys(i)).filter((i) => i && !ignoredThemeKeys.includes(i) && i[0] !== "_");
|
|
92
99
|
const fullMatched = keys.find((i) => i && rest.startsWith(i));
|
|
93
100
|
if (fullMatched != null) {
|
|
94
101
|
matched += fullMatched;
|
|
@@ -105,12 +112,11 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
105
112
|
}
|
|
106
113
|
} else {
|
|
107
114
|
combinations = keys.filter((i) => i.startsWith(rest));
|
|
108
|
-
|
|
115
|
+
if (tempParts[0]?.type !== "static")
|
|
116
|
+
break;
|
|
109
117
|
}
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
|
-
if (!matched)
|
|
113
|
-
return [];
|
|
114
120
|
if (combinations.length === 0)
|
|
115
121
|
combinations.push("");
|
|
116
122
|
return combinations.map((i) => matched + i).filter((i) => i.length >= input.length);
|
|
@@ -121,7 +127,14 @@ function createAutocomplete(uno) {
|
|
|
121
127
|
const templateCache = /* @__PURE__ */ new Map();
|
|
122
128
|
const cache = new LRU__default({ max: 1e3 });
|
|
123
129
|
let staticUtils = [];
|
|
124
|
-
|
|
130
|
+
const templates = [];
|
|
131
|
+
reset();
|
|
132
|
+
return {
|
|
133
|
+
suggest,
|
|
134
|
+
templates,
|
|
135
|
+
cache,
|
|
136
|
+
reset
|
|
137
|
+
};
|
|
125
138
|
function getParsed(template) {
|
|
126
139
|
if (!templateCache.has(template))
|
|
127
140
|
templateCache.set(template, parseAutocomplete(template, uno.config.theme));
|
|
@@ -132,11 +145,18 @@ function createAutocomplete(uno) {
|
|
|
132
145
|
return [];
|
|
133
146
|
if (cache.has(input))
|
|
134
147
|
return cache.get(input);
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
148
|
+
const [, processed, , variants] = uno.matchVariants(input);
|
|
149
|
+
const idx = input.search(processed);
|
|
150
|
+
if (idx === -1)
|
|
151
|
+
return [];
|
|
152
|
+
const variantPrefix = input.slice(0, idx);
|
|
153
|
+
const variantPostfix = input.slice(idx + input.length);
|
|
154
|
+
const result = processSuggestions(await Promise.all([
|
|
155
|
+
suggestSelf(processed),
|
|
156
|
+
suggestStatic(processed),
|
|
157
|
+
...suggestFromPreset(processed),
|
|
158
|
+
...suggestVariant(processed, variants)
|
|
159
|
+
]), variantPrefix, variantPostfix);
|
|
140
160
|
cache.set(input, result);
|
|
141
161
|
return result;
|
|
142
162
|
}
|
|
@@ -150,30 +170,34 @@ function createAutocomplete(uno) {
|
|
|
150
170
|
function suggestFromPreset(input) {
|
|
151
171
|
return templates.map((fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input)) || [];
|
|
152
172
|
}
|
|
173
|
+
function suggestVariant(input, used) {
|
|
174
|
+
return uno.config.variants.filter((v) => v.autocomplete && (v.multiPass || !used.has(v))).flatMap((v) => core.toArray(v.autocomplete || [])).map((fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input));
|
|
175
|
+
}
|
|
153
176
|
function reset() {
|
|
154
177
|
templateCache.clear();
|
|
155
178
|
cache.clear();
|
|
156
179
|
staticUtils = Object.keys(uno.config.rulesStaticMap);
|
|
157
|
-
templates =
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
180
|
+
templates.length = 0;
|
|
181
|
+
templates.push(...uno.config.autocomplete || [], ...uno.config.rulesDynamic.flatMap((i) => core.toArray(i?.[2]?.autocomplete || [])));
|
|
182
|
+
}
|
|
183
|
+
function processSuggestions(suggestions, prefix = "", suffix = "") {
|
|
184
|
+
return core.uniq(suggestions.flat()).filter((i) => !!(i && !i.match(/-$/))).sort((a, b) => {
|
|
185
|
+
const numA = +(a.match(/\d+$/)?.[0] || NaN);
|
|
186
|
+
const numB = +(b.match(/\d+$/)?.[0] || NaN);
|
|
187
|
+
if (!Number.isNaN(numA) && !Number.isNaN(numB))
|
|
188
|
+
return numA - numB;
|
|
189
|
+
return a.localeCompare(b);
|
|
190
|
+
}).map((i) => prefix + i + suffix);
|
|
161
191
|
}
|
|
162
|
-
reset();
|
|
163
|
-
return {
|
|
164
|
-
suggest,
|
|
165
|
-
templates,
|
|
166
|
-
cache,
|
|
167
|
-
reset
|
|
168
|
-
};
|
|
169
192
|
}
|
|
170
193
|
|
|
171
194
|
function searchUsageBoundary(line, index) {
|
|
172
195
|
let start = index;
|
|
173
196
|
let end = index;
|
|
174
|
-
|
|
197
|
+
const regex = /[^\s>"'`]/;
|
|
198
|
+
while (start && regex.test(line.charAt(start - 1)))
|
|
175
199
|
--start;
|
|
176
|
-
while (end < line.length &&
|
|
200
|
+
while (end < line.length && regex.test(line.charAt(end)))
|
|
177
201
|
++end;
|
|
178
202
|
return {
|
|
179
203
|
content: line.slice(start, end),
|
|
@@ -183,5 +207,7 @@ function searchUsageBoundary(line, index) {
|
|
|
183
207
|
}
|
|
184
208
|
|
|
185
209
|
exports.createAutocomplete = createAutocomplete;
|
|
210
|
+
exports.ignoredThemeKeys = ignoredThemeKeys;
|
|
186
211
|
exports.parseAutocomplete = parseAutocomplete;
|
|
187
212
|
exports.searchUsageBoundary = searchUsageBoundary;
|
|
213
|
+
exports.shorthands = shorthands;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { UnoGenerator, AutoCompleteFunction } from '@unocss/core';
|
|
|
2
2
|
import LRU from 'lru-cache';
|
|
3
3
|
|
|
4
4
|
declare function createAutocomplete(uno: UnoGenerator): {
|
|
5
|
-
suggest: (input: string) => Promise<string[]
|
|
5
|
+
suggest: (input: string) => Promise<string[]>;
|
|
6
6
|
templates: (string | AutoCompleteFunction)[];
|
|
7
7
|
cache: LRU<string, string[]>;
|
|
8
8
|
reset: () => void;
|
|
@@ -26,6 +26,8 @@ interface ParsedAutocompleteTemplate {
|
|
|
26
26
|
suggest(input: string): string[] | undefined;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
declare const shorthands: Record<string, string>;
|
|
30
|
+
declare const ignoredThemeKeys: string[];
|
|
29
31
|
declare function parseAutocomplete(template: string, theme?: any): ParsedAutocompleteTemplate;
|
|
30
32
|
|
|
31
33
|
declare function searchUsageBoundary(line: string, index: number): {
|
|
@@ -34,4 +36,4 @@ declare function searchUsageBoundary(line: string, index: number): {
|
|
|
34
36
|
end: number;
|
|
35
37
|
};
|
|
36
38
|
|
|
37
|
-
export { AutocompleteTemplateGroup, AutocompleteTemplatePart, AutocompleteTemplateStatic, AutocompleteTemplateTheme, ParsedAutocompleteTemplate, createAutocomplete, parseAutocomplete, searchUsageBoundary };
|
|
39
|
+
export { AutocompleteTemplateGroup, AutocompleteTemplatePart, AutocompleteTemplateStatic, AutocompleteTemplateTheme, ParsedAutocompleteTemplate, createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchUsageBoundary, shorthands };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toArray, uniq } from '@unocss/core';
|
|
2
2
|
import LRU from 'lru-cache';
|
|
3
3
|
|
|
4
4
|
const shorthands = {
|
|
5
5
|
num: `(${[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 24, 36].join("|")})`,
|
|
6
|
-
|
|
6
|
+
percent: `(${Array.from({ length: 11 }, (_, i) => i * 10).join("|")})`,
|
|
7
7
|
directions: "(x|y|t|b|l|r|s|e)"
|
|
8
8
|
};
|
|
9
|
+
const ignoredThemeKeys = ["DEFAULT"];
|
|
9
10
|
function handleRegexMatch(str, regex, onMatched, onNotMatched) {
|
|
10
11
|
let lastIndex = 0;
|
|
11
12
|
Array.from(str.matchAll(regex)).forEach((m) => {
|
|
@@ -32,10 +33,9 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
32
33
|
};
|
|
33
34
|
function handleNonGroup(input) {
|
|
34
35
|
handleRegexMatch(input, /\$([\w\|]+)/g, (m) => {
|
|
35
|
-
const keys = m[1].split("|");
|
|
36
36
|
parts.push({
|
|
37
37
|
type: "theme",
|
|
38
|
-
objects:
|
|
38
|
+
objects: m[1].split("|").map((i) => {
|
|
39
39
|
if (!i || !theme[i])
|
|
40
40
|
throw new Error(`Invalid theme key ${i}`);
|
|
41
41
|
return theme[i];
|
|
@@ -66,8 +66,14 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
66
66
|
while (tempParts.length) {
|
|
67
67
|
const part = tempParts.shift();
|
|
68
68
|
if (part.type === "static") {
|
|
69
|
-
if (
|
|
69
|
+
if (combinations.length)
|
|
70
|
+
combinations = combinations.map((i) => i + part.value);
|
|
71
|
+
if (part.value.startsWith(rest) && part.value !== rest && !combinations.length) {
|
|
72
|
+
combinations = [part.value];
|
|
70
73
|
break;
|
|
74
|
+
} else if (!rest.startsWith(part.value)) {
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
71
77
|
matched += part.value;
|
|
72
78
|
rest = rest.slice(part.value.length);
|
|
73
79
|
} else if (part.type === "group") {
|
|
@@ -77,10 +83,11 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
77
83
|
rest = rest.slice(fullMatched.length);
|
|
78
84
|
} else {
|
|
79
85
|
combinations = part.values.filter((i) => i.startsWith(rest));
|
|
80
|
-
|
|
86
|
+
if (tempParts[0]?.type !== "static")
|
|
87
|
+
break;
|
|
81
88
|
}
|
|
82
89
|
} else if (part.type === "theme") {
|
|
83
|
-
const keys = part.objects.flatMap((i) => Object.keys(i));
|
|
90
|
+
const keys = part.objects.flatMap((i) => Object.keys(i)).filter((i) => i && !ignoredThemeKeys.includes(i) && i[0] !== "_");
|
|
84
91
|
const fullMatched = keys.find((i) => i && rest.startsWith(i));
|
|
85
92
|
if (fullMatched != null) {
|
|
86
93
|
matched += fullMatched;
|
|
@@ -97,12 +104,11 @@ function parseAutocomplete(template, theme = {}) {
|
|
|
97
104
|
}
|
|
98
105
|
} else {
|
|
99
106
|
combinations = keys.filter((i) => i.startsWith(rest));
|
|
100
|
-
|
|
107
|
+
if (tempParts[0]?.type !== "static")
|
|
108
|
+
break;
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
|
-
if (!matched)
|
|
105
|
-
return [];
|
|
106
112
|
if (combinations.length === 0)
|
|
107
113
|
combinations.push("");
|
|
108
114
|
return combinations.map((i) => matched + i).filter((i) => i.length >= input.length);
|
|
@@ -113,7 +119,14 @@ function createAutocomplete(uno) {
|
|
|
113
119
|
const templateCache = /* @__PURE__ */ new Map();
|
|
114
120
|
const cache = new LRU({ max: 1e3 });
|
|
115
121
|
let staticUtils = [];
|
|
116
|
-
|
|
122
|
+
const templates = [];
|
|
123
|
+
reset();
|
|
124
|
+
return {
|
|
125
|
+
suggest,
|
|
126
|
+
templates,
|
|
127
|
+
cache,
|
|
128
|
+
reset
|
|
129
|
+
};
|
|
117
130
|
function getParsed(template) {
|
|
118
131
|
if (!templateCache.has(template))
|
|
119
132
|
templateCache.set(template, parseAutocomplete(template, uno.config.theme));
|
|
@@ -124,11 +137,18 @@ function createAutocomplete(uno) {
|
|
|
124
137
|
return [];
|
|
125
138
|
if (cache.has(input))
|
|
126
139
|
return cache.get(input);
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
const [, processed, , variants] = uno.matchVariants(input);
|
|
141
|
+
const idx = input.search(processed);
|
|
142
|
+
if (idx === -1)
|
|
143
|
+
return [];
|
|
144
|
+
const variantPrefix = input.slice(0, idx);
|
|
145
|
+
const variantPostfix = input.slice(idx + input.length);
|
|
146
|
+
const result = processSuggestions(await Promise.all([
|
|
147
|
+
suggestSelf(processed),
|
|
148
|
+
suggestStatic(processed),
|
|
149
|
+
...suggestFromPreset(processed),
|
|
150
|
+
...suggestVariant(processed, variants)
|
|
151
|
+
]), variantPrefix, variantPostfix);
|
|
132
152
|
cache.set(input, result);
|
|
133
153
|
return result;
|
|
134
154
|
}
|
|
@@ -142,30 +162,34 @@ function createAutocomplete(uno) {
|
|
|
142
162
|
function suggestFromPreset(input) {
|
|
143
163
|
return templates.map((fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input)) || [];
|
|
144
164
|
}
|
|
165
|
+
function suggestVariant(input, used) {
|
|
166
|
+
return uno.config.variants.filter((v) => v.autocomplete && (v.multiPass || !used.has(v))).flatMap((v) => toArray(v.autocomplete || [])).map((fn) => typeof fn === "function" ? fn(input) : getParsed(fn)(input));
|
|
167
|
+
}
|
|
145
168
|
function reset() {
|
|
146
169
|
templateCache.clear();
|
|
147
170
|
cache.clear();
|
|
148
171
|
staticUtils = Object.keys(uno.config.rulesStaticMap);
|
|
149
|
-
templates =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
172
|
+
templates.length = 0;
|
|
173
|
+
templates.push(...uno.config.autocomplete || [], ...uno.config.rulesDynamic.flatMap((i) => toArray(i?.[2]?.autocomplete || [])));
|
|
174
|
+
}
|
|
175
|
+
function processSuggestions(suggestions, prefix = "", suffix = "") {
|
|
176
|
+
return uniq(suggestions.flat()).filter((i) => !!(i && !i.match(/-$/))).sort((a, b) => {
|
|
177
|
+
const numA = +(a.match(/\d+$/)?.[0] || NaN);
|
|
178
|
+
const numB = +(b.match(/\d+$/)?.[0] || NaN);
|
|
179
|
+
if (!Number.isNaN(numA) && !Number.isNaN(numB))
|
|
180
|
+
return numA - numB;
|
|
181
|
+
return a.localeCompare(b);
|
|
182
|
+
}).map((i) => prefix + i + suffix);
|
|
153
183
|
}
|
|
154
|
-
reset();
|
|
155
|
-
return {
|
|
156
|
-
suggest,
|
|
157
|
-
templates,
|
|
158
|
-
cache,
|
|
159
|
-
reset
|
|
160
|
-
};
|
|
161
184
|
}
|
|
162
185
|
|
|
163
186
|
function searchUsageBoundary(line, index) {
|
|
164
187
|
let start = index;
|
|
165
188
|
let end = index;
|
|
166
|
-
|
|
189
|
+
const regex = /[^\s>"'`]/;
|
|
190
|
+
while (start && regex.test(line.charAt(start - 1)))
|
|
167
191
|
--start;
|
|
168
|
-
while (end < line.length &&
|
|
192
|
+
while (end < line.length && regex.test(line.charAt(end)))
|
|
169
193
|
++end;
|
|
170
194
|
return {
|
|
171
195
|
content: line.slice(start, end),
|
|
@@ -174,4 +198,4 @@ function searchUsageBoundary(line, index) {
|
|
|
174
198
|
};
|
|
175
199
|
}
|
|
176
200
|
|
|
177
|
-
export { createAutocomplete, parseAutocomplete, searchUsageBoundary };
|
|
201
|
+
export { createAutocomplete, ignoredThemeKeys, parseAutocomplete, searchUsageBoundary, shorthands };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unocss/autocomplete",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.3",
|
|
4
4
|
"description": "Autocomplete utils for UnoCSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"unocss",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/lru-cache": "^7.4.0",
|
|
39
|
-
"@unocss/core": "0.29.
|
|
39
|
+
"@unocss/core": "0.29.3"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "unbuild",
|
|
43
43
|
"stub": "unbuild --stub"
|
|
44
44
|
},
|
|
45
|
-
"readme": "# @unocss/autocomplete\n\nAutocomplete utils for UnoCSS.\n\n>
|
|
45
|
+
"readme": "# @unocss/autocomplete\n\nAutocomplete utils for UnoCSS. This is embedded in [the playground](https://unocss.antfu.me/) and [the VS Code extension](https://github.com/unocss/unocss/tree/main/packages/vscode).\n\n## Syntax\n\nTo add autocomplete support to your custom rules:\n\n### Static Rules\n\nStatic rules like this will just works without any configuration.\n\n```ts\nrules: [\n ['flex', { display: 'flex' }]\n]\n```\n\n### Dynamic Rules\n\nFor dynamic rules, you can provide an extra `meta` object to the rule and specify the autocomplete template.\n\n```ts\nrules: [\n [\n /^m-(\\d)$/,\n ([, d]) => ({ margin: `${d / 4}rem` }),\n { autocomplete: 'm-<num>' }, // <-- this\n ],\n]\n```\n\nThe template uses a simle DSL to specify the autocomplete suggestions. The syntax is:\n\n- `(...|...)`: logic OR groups. `|` as the separator. Will be used as suggestions when the some of the groups match.\n- `<...>`: built-in short hands. currently supports `<num>`, `<percent>` and `<directions>`\n- `$...`: theme infering. for example, `$colors` will list all the properties of the `colors` object of the theme.\n\nFor examples:\n\n###### Example 1\n\n- **Template**: `(border|b)-(solid|dashed|dotted|double|hidden|none)`\n- **Input**: `b-do`\n- **Suggestions**: `b-dashed`, `b-double`\n\n###### Example 2\n\n- **Template**: `m-<num>`\n- **Input**: `m-`\n- **Suggestions**: `m-1`, `m-2`, `m-3` ...\n\n###### Example 3\n\n- **Template**: `text-$colors`\n- **Input**: `text-r`\n- **Suggestions**: `text-red`, `text-rose` ...\n\n###### Example 4\n\nFor multiple templates\n\n- **Template**: `['(border|b)-<num>', '(border|b)-<directions>-<num>']`\n\n- **Input**: `b-`\n- **Suggestions**: `b-x`, `b-y`, `b-1`, `b-2` ...\n\n- **Input**: `b-x-`\n- **Suggestions**: `b-x-1`, `b-x-2` ...\n\n## License\n\nMIT License © 2021-PRESENT [Anthony Fu](https://github.com/antfu)\n"
|
|
46
46
|
}
|