lapikit 0.6.7 → 0.6.9
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/bin/helpers.js +153 -2
- package/bin/hooks.js +290 -40
- package/bin/index.js +111 -36
- package/dist/components/accordion/accordion.svelte +10 -0
- package/dist/components/accordion/modules/accordion-item.svelte +4 -3
- package/dist/components/app/app.svelte +6 -6
- package/dist/components/btn/btn.svelte +1 -0
- package/dist/components/card/card.svelte +0 -1
- package/dist/components/chip/chip.svelte +1 -0
- package/dist/components/icon/icon.svelte +14 -8
- package/dist/components/list/list.svelte +3 -3
- package/dist/components/list/modules/list-item.svelte +0 -1
- package/package.json +2 -1
package/bin/helpers.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import readline from 'node:readline/promises';
|
|
2
|
+
import { emitKeypressEvents, moveCursor, cursorTo, clearLine } from 'node:readline';
|
|
2
3
|
|
|
3
4
|
const color = {
|
|
4
5
|
red: (text) => `\x1b[31m${text}\x1b[0m`,
|
|
@@ -61,7 +62,16 @@ export const terminal = (type = 'info', msg) => {
|
|
|
61
62
|
};
|
|
62
63
|
|
|
63
64
|
export function createRL() {
|
|
64
|
-
|
|
65
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
66
|
+
|
|
67
|
+
rl.on('SIGINT', () => {
|
|
68
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
69
|
+
console.log('\n');
|
|
70
|
+
terminal('warn', 'installation canceled.');
|
|
71
|
+
process.exit(0);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return rl;
|
|
65
75
|
}
|
|
66
76
|
|
|
67
77
|
export async function toggle(rl, message, initial = true) {
|
|
@@ -87,7 +97,7 @@ export async function text(rl, message, initial = '', validate) {
|
|
|
87
97
|
}
|
|
88
98
|
}
|
|
89
99
|
|
|
90
|
-
|
|
100
|
+
async function selectFallback(rl, message, choices) {
|
|
91
101
|
console.log(`\n${message}`);
|
|
92
102
|
choices.forEach((c, i) => console.log(` ${i + 1}. ${c.title}`));
|
|
93
103
|
|
|
@@ -98,3 +108,144 @@ export async function select(rl, message, choices) {
|
|
|
98
108
|
terminal('warn', `Please enter a number between 1 and ${choices.length}`);
|
|
99
109
|
}
|
|
100
110
|
}
|
|
111
|
+
|
|
112
|
+
async function multiselectFallback(rl, message, choices) {
|
|
113
|
+
console.log(`\n${message}`);
|
|
114
|
+
choices.forEach((c, i) => console.log(` ${i + 1}. ${c.title}`));
|
|
115
|
+
console.log(` (enter numbers separated by commas, e.g. 1,2 - leave empty for none)`);
|
|
116
|
+
|
|
117
|
+
while (true) {
|
|
118
|
+
const answer = (await rl.question(`Choice: `)).trim();
|
|
119
|
+
if (answer === '') return [];
|
|
120
|
+
|
|
121
|
+
const indexes = answer.split(',').map((part) => parseInt(part.trim(), 10) - 1);
|
|
122
|
+
const valid = indexes.every((index) => index >= 0 && index < choices.length);
|
|
123
|
+
if (valid) return [...new Set(indexes)].map((index) => choices[index].value);
|
|
124
|
+
|
|
125
|
+
terminal('warn', `Please enter numbers between 1 and ${choices.length}, separated by commas`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function interactiveList(rl, message, hint, choices, renderLine, onKey) {
|
|
130
|
+
console.log(`\n${message}`);
|
|
131
|
+
console.log(ansi.color.cyan(` (${hint})`));
|
|
132
|
+
choices.forEach((_, i) => console.log(renderLine(i)));
|
|
133
|
+
|
|
134
|
+
const { stdin } = process;
|
|
135
|
+
rl.pause();
|
|
136
|
+
const wasRaw = stdin.isRaw;
|
|
137
|
+
emitKeypressEvents(stdin, rl);
|
|
138
|
+
stdin.setRawMode(true);
|
|
139
|
+
stdin.resume();
|
|
140
|
+
|
|
141
|
+
return new Promise((resolve) => {
|
|
142
|
+
const redrawLine = (index) => {
|
|
143
|
+
const rowsUp = choices.length - index;
|
|
144
|
+
moveCursor(process.stdout, 0, -rowsUp);
|
|
145
|
+
cursorTo(process.stdout, 0);
|
|
146
|
+
clearLine(process.stdout, 1);
|
|
147
|
+
process.stdout.write(renderLine(index));
|
|
148
|
+
moveCursor(process.stdout, 0, rowsUp);
|
|
149
|
+
cursorTo(process.stdout, 0);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const cleanup = () => {
|
|
153
|
+
stdin.removeListener('keypress', onKeypress);
|
|
154
|
+
stdin.setRawMode(wasRaw);
|
|
155
|
+
rl.resume();
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const onKeypress = (str, key) => {
|
|
159
|
+
if (key.ctrl && key.name === 'c') {
|
|
160
|
+
cleanup();
|
|
161
|
+
process.stdout.write('\n');
|
|
162
|
+
terminal('warn', 'installation canceled.');
|
|
163
|
+
process.exit(130);
|
|
164
|
+
}
|
|
165
|
+
onKey(key, redrawLine, (value) => {
|
|
166
|
+
cleanup();
|
|
167
|
+
console.log('');
|
|
168
|
+
resolve(value);
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
stdin.on('keypress', onKeypress);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export async function select(rl, message, choices) {
|
|
177
|
+
const { stdin } = process;
|
|
178
|
+
if (!stdin.isTTY || typeof stdin.setRawMode !== 'function') {
|
|
179
|
+
return selectFallback(rl, message, choices);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let cursor = 0;
|
|
183
|
+
const renderLine = (index) => {
|
|
184
|
+
const radio = index === cursor ? ansi.color.green('(●)') : '( )';
|
|
185
|
+
const pointer = index === cursor ? ansi.color.cyan('❯') : ' ';
|
|
186
|
+
return `${pointer} ${radio} ${choices[index].title}`;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return interactiveList(
|
|
190
|
+
rl,
|
|
191
|
+
message,
|
|
192
|
+
'↑/↓ move, enter to confirm',
|
|
193
|
+
choices,
|
|
194
|
+
renderLine,
|
|
195
|
+
(key, redrawLine, resolve) => {
|
|
196
|
+
const previousCursor = cursor;
|
|
197
|
+
if (key.name === 'up') {
|
|
198
|
+
cursor = (cursor - 1 + choices.length) % choices.length;
|
|
199
|
+
redrawLine(previousCursor);
|
|
200
|
+
redrawLine(cursor);
|
|
201
|
+
} else if (key.name === 'down') {
|
|
202
|
+
cursor = (cursor + 1) % choices.length;
|
|
203
|
+
redrawLine(previousCursor);
|
|
204
|
+
redrawLine(cursor);
|
|
205
|
+
} else if (key.name === 'return') {
|
|
206
|
+
resolve(choices[cursor].value);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export async function multiselect(rl, message, choices) {
|
|
213
|
+
const { stdin } = process;
|
|
214
|
+
if (!stdin.isTTY || typeof stdin.setRawMode !== 'function') {
|
|
215
|
+
return multiselectFallback(rl, message, choices);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const selected = new Set();
|
|
219
|
+
let cursor = 0;
|
|
220
|
+
const renderLine = (index) => {
|
|
221
|
+
const checked = selected.has(index) ? ansi.color.green('[x]') : '[ ]';
|
|
222
|
+
const pointer = index === cursor ? ansi.color.cyan('❯') : ' ';
|
|
223
|
+
return `${pointer} ${checked} ${choices[index].title}`;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
return interactiveList(
|
|
227
|
+
rl,
|
|
228
|
+
message,
|
|
229
|
+
'↑/↓ move, space to select, enter to confirm',
|
|
230
|
+
choices,
|
|
231
|
+
renderLine,
|
|
232
|
+
(key, redrawLine, resolve) => {
|
|
233
|
+
const previousCursor = cursor;
|
|
234
|
+
if (key.name === 'up') {
|
|
235
|
+
cursor = (cursor - 1 + choices.length) % choices.length;
|
|
236
|
+
redrawLine(previousCursor);
|
|
237
|
+
redrawLine(cursor);
|
|
238
|
+
} else if (key.name === 'down') {
|
|
239
|
+
cursor = (cursor + 1) % choices.length;
|
|
240
|
+
redrawLine(previousCursor);
|
|
241
|
+
redrawLine(cursor);
|
|
242
|
+
} else if (key.name === 'space') {
|
|
243
|
+
if (selected.has(cursor)) selected.delete(cursor);
|
|
244
|
+
else selected.add(cursor);
|
|
245
|
+
redrawLine(cursor);
|
|
246
|
+
} else if (key.name === 'return') {
|
|
247
|
+
resolve([...selected].sort((a, b) => a - b).map((index) => choices[index].value));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
}
|
package/bin/hooks.js
CHANGED
|
@@ -1,10 +1,157 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { promises as fs } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
4
5
|
import { terminal } from './helpers.js';
|
|
5
6
|
|
|
7
|
+
const INSTALL_ARGS = {
|
|
8
|
+
npm: ['install', '--save-dev'],
|
|
9
|
+
yarn: ['add', '-D'],
|
|
10
|
+
pnpm: ['add', '--save-dev'],
|
|
11
|
+
bun: ['add', '-D']
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function installDependency(pkgManager, packageName, cwd) {
|
|
15
|
+
const args = INSTALL_ARGS[pkgManager];
|
|
16
|
+
if (!args) throw new Error(`Unsupported package manager: ${pkgManager}`);
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const child = spawn(pkgManager, [...args, packageName], {
|
|
19
|
+
cwd,
|
|
20
|
+
stdio: 'inherit',
|
|
21
|
+
shell: process.platform === 'win32'
|
|
22
|
+
});
|
|
23
|
+
child.on('error', reject);
|
|
24
|
+
child.on('close', (code) =>
|
|
25
|
+
code === 0 ? resolve() : reject(new Error(`${pkgManager} exited with code ${code}`))
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function findMatchingDelimiter(content, openIndex, openChar, closeChar) {
|
|
31
|
+
let depth = 0;
|
|
32
|
+
for (let i = openIndex; i < content.length; i++) {
|
|
33
|
+
const ch = content[i];
|
|
34
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
35
|
+
i = skipString(content, i);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (ch === openChar) depth++;
|
|
39
|
+
else if (ch === closeChar) {
|
|
40
|
+
depth--;
|
|
41
|
+
if (depth === 0) return i;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return -1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function skipString(source, start) {
|
|
48
|
+
const quote = source[start];
|
|
49
|
+
for (let i = start + 1; i < source.length; i++) {
|
|
50
|
+
if (source[i] === '\\') {
|
|
51
|
+
i++;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (source[i] === quote) return i;
|
|
55
|
+
}
|
|
56
|
+
return source.length - 1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function insertImportLine(content, importLine) {
|
|
60
|
+
const lines = content.split('\n');
|
|
61
|
+
let importInsertIndex = 0;
|
|
62
|
+
for (let i = 0; i < lines.length; i++) {
|
|
63
|
+
if (lines[i].trim().startsWith('import ')) importInsertIndex = i + 1;
|
|
64
|
+
}
|
|
65
|
+
lines.splice(importInsertIndex, 0, importLine);
|
|
66
|
+
return lines.join('\n');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function buildPreprocessCall(pluginKeys = []) {
|
|
70
|
+
if (!pluginKeys.length) return `lapikitPreprocess()`;
|
|
71
|
+
const plugins = pluginKeys.map((key) => `'${key}'`).join(', ');
|
|
72
|
+
return `lapikitPreprocess({ plugins: [${plugins}] })`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function mergeExistingPreprocessCall(content, pluginKeys) {
|
|
76
|
+
if (!pluginKeys.length) return null;
|
|
77
|
+
|
|
78
|
+
const callMatch = content.match(/lapikitPreprocess\s*\(\s*(\{[\s\S]*?\})?\s*\)/);
|
|
79
|
+
if (!callMatch) return null;
|
|
80
|
+
|
|
81
|
+
const [fullMatch, optionsSource] = callMatch;
|
|
82
|
+
const pluginsMatch = optionsSource?.match(/plugins\s*:\s*\[([^\]]*)\]/);
|
|
83
|
+
const existingKeys = pluginsMatch
|
|
84
|
+
? [...pluginsMatch[1].matchAll(/'([^']+)'|"([^"]+)"/g)].map((m) => m[1] ?? m[2])
|
|
85
|
+
: [];
|
|
86
|
+
|
|
87
|
+
const merged = [...new Set([...existingKeys, ...pluginKeys])];
|
|
88
|
+
if (merged.length === existingKeys.length) return null;
|
|
89
|
+
|
|
90
|
+
const newCall = buildPreprocessCall(merged);
|
|
91
|
+
return (
|
|
92
|
+
content.slice(0, callMatch.index) + newCall + content.slice(callMatch.index + fullMatch.length)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function findValueEnd(source, start) {
|
|
97
|
+
let depth = 0;
|
|
98
|
+
for (let i = start; i < source.length; i++) {
|
|
99
|
+
const ch = source[i];
|
|
100
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
101
|
+
i = skipString(source, i);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (ch === '(' || ch === '[' || ch === '{') depth++;
|
|
105
|
+
else if (ch === ')' || ch === ']' || ch === '}') {
|
|
106
|
+
if (depth === 0) return i;
|
|
107
|
+
depth--;
|
|
108
|
+
} else if (ch === ',' && depth === 0) return i;
|
|
109
|
+
}
|
|
110
|
+
return source.length;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function injectPreprocessEntry(objectSource, pluginKeys = []) {
|
|
114
|
+
const call = buildPreprocessCall(pluginKeys);
|
|
115
|
+
|
|
116
|
+
const keyMatch = objectSource.match(/preprocess\s*:\s*/);
|
|
117
|
+
if (!keyMatch) {
|
|
118
|
+
return objectSource.replace('{', `{\n\t\t\tpreprocess: [${call}],`);
|
|
119
|
+
}
|
|
120
|
+
const valueStart = keyMatch.index + keyMatch[0].length;
|
|
121
|
+
|
|
122
|
+
if (objectSource[valueStart] === '[') {
|
|
123
|
+
const openBracketIndex = valueStart;
|
|
124
|
+
const closeBracketIndex = findMatchingDelimiter(objectSource, openBracketIndex, '[', ']');
|
|
125
|
+
const inner = objectSource.slice(openBracketIndex + 1, closeBracketIndex);
|
|
126
|
+
const trimmed = inner.trim();
|
|
127
|
+
|
|
128
|
+
let newInner;
|
|
129
|
+
if (!trimmed) {
|
|
130
|
+
newInner = call;
|
|
131
|
+
} else if (inner.includes('\n')) {
|
|
132
|
+
const firstItemMatch = inner.match(/\n(\s*)\S/);
|
|
133
|
+
const indent = firstItemMatch ? firstItemMatch[1] : '\t\t';
|
|
134
|
+
const closingMatch = inner.match(/\n(\s*)$/);
|
|
135
|
+
const closingIndent = closingMatch ? closingMatch[1] : '\t';
|
|
136
|
+
const innerTrimmed = inner.trimEnd();
|
|
137
|
+
const sep = innerTrimmed.endsWith(',') ? '' : ',';
|
|
138
|
+
newInner = `${innerTrimmed}${sep}\n${indent}${call}\n${closingIndent}`;
|
|
139
|
+
} else {
|
|
140
|
+
const sep = trimmed.endsWith(',') ? ' ' : ', ';
|
|
141
|
+
newInner = `${trimmed}${sep}${call}`;
|
|
142
|
+
}
|
|
143
|
+
return (
|
|
144
|
+
objectSource.slice(0, openBracketIndex + 1) + newInner + objectSource.slice(closeBracketIndex)
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const valueEnd = findValueEnd(objectSource, valueStart);
|
|
149
|
+
const expr = objectSource.slice(valueStart, valueEnd).trim();
|
|
150
|
+
return objectSource.slice(0, valueStart) + `[${expr}, ${call}]` + objectSource.slice(valueEnd);
|
|
151
|
+
}
|
|
152
|
+
|
|
6
153
|
export async function findSvelteConfigFile(projectPath) {
|
|
7
|
-
for (const ext of ['js', 'ts']) {
|
|
154
|
+
for (const ext of ['js', 'mjs', 'cjs', 'ts']) {
|
|
8
155
|
const file = path.join(projectPath, `svelte.config.${ext}`);
|
|
9
156
|
try {
|
|
10
157
|
await fs.access(file);
|
|
@@ -13,56 +160,159 @@ export async function findSvelteConfigFile(projectPath) {
|
|
|
13
160
|
// lapikit other step
|
|
14
161
|
}
|
|
15
162
|
}
|
|
16
|
-
throw new Error('No svelte.config
|
|
163
|
+
throw new Error('No svelte.config file found');
|
|
17
164
|
}
|
|
18
165
|
|
|
19
|
-
export async function addLiliPreprocess(svelteConfigFile) {
|
|
166
|
+
export async function addLiliPreprocess(svelteConfigFile, pluginKeys = []) {
|
|
20
167
|
let content = await fs.readFile(svelteConfigFile, 'utf-8');
|
|
21
|
-
const lapikitImport = `import { lapikitPreprocess } from 'lapikit/
|
|
168
|
+
const lapikitImport = `import { lapikitPreprocess } from 'lapikit/preprocess';`;
|
|
22
169
|
|
|
23
|
-
if (content.includes(`from 'lapikit/
|
|
24
|
-
|
|
170
|
+
if (content.includes(`from 'lapikit/preprocess'`)) {
|
|
171
|
+
const updated = mergeExistingPreprocessCall(content, pluginKeys);
|
|
172
|
+
if (!updated) {
|
|
173
|
+
terminal('warn', `lapikitPreprocess already imported in ${svelteConfigFile}`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
await fs.writeFile(svelteConfigFile, updated);
|
|
177
|
+
terminal('success', `lapikitPreprocess plugins updated in ${svelteConfigFile}`);
|
|
25
178
|
return;
|
|
26
179
|
}
|
|
27
180
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (lines[i].trim().startsWith('import ')) importInsertIndex = i + 1;
|
|
181
|
+
const match = content.match(/(?:const\s+\w+\s*=\s*|export\s+default\s*)(\{)/);
|
|
182
|
+
if (!match) {
|
|
183
|
+
throw new Error(`Could not find the exported config object in ${svelteConfigFile}`);
|
|
32
184
|
}
|
|
33
|
-
lines.splice(importInsertIndex, 0, lapikitImport);
|
|
34
|
-
content = lines.join('\n');
|
|
35
185
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
);
|
|
41
|
-
} else if (content.match(/preprocess\s*:\s*\[/)) {
|
|
42
|
-
content = content.replace(/preprocess\s*:\s*\[([\s\S]*?)\]/, (_, inner) => {
|
|
43
|
-
const trimmed = inner.trim();
|
|
44
|
-
if (!trimmed) return `preprocess: [lapikitPreprocess()]`;
|
|
45
|
-
|
|
46
|
-
if (inner.includes('\n')) {
|
|
47
|
-
const firstItemMatch = inner.match(/\n(\s*)\S/);
|
|
48
|
-
const indent = firstItemMatch ? firstItemMatch[1] : '\t\t';
|
|
49
|
-
const closingMatch = inner.match(/\n(\s*)$/);
|
|
50
|
-
const closingIndent = closingMatch ? closingMatch[1] : '\t';
|
|
51
|
-
const innerTrimmed = inner.trimEnd();
|
|
52
|
-
const sep = innerTrimmed.endsWith(',') ? '' : ',';
|
|
53
|
-
return `preprocess: [${innerTrimmed}${sep}\n${indent}lapikitPreprocess()\n${closingIndent}]`;
|
|
54
|
-
} else {
|
|
55
|
-
const sep = trimmed.endsWith(',') ? ' ' : ', ';
|
|
56
|
-
return `preprocess: [${trimmed}${sep}lapikitPreprocess()]`;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
} else {
|
|
60
|
-
content = content.replace(
|
|
61
|
-
/preprocess\s*:\s*([^,\n\]{}]+)/,
|
|
62
|
-
(_, val) => `preprocess: [${val.trim()}, lapikitPreprocess()]`
|
|
63
|
-
);
|
|
186
|
+
const openBraceIndex = match.index + match[0].length - 1;
|
|
187
|
+
const closeBraceIndex = findMatchingDelimiter(content, openBraceIndex, '{', '}');
|
|
188
|
+
if (closeBraceIndex === -1) {
|
|
189
|
+
throw new Error(`Could not parse the config object in ${svelteConfigFile}`);
|
|
64
190
|
}
|
|
65
191
|
|
|
192
|
+
const objectSource = content.slice(openBraceIndex, closeBraceIndex + 1);
|
|
193
|
+
const updatedObject = injectPreprocessEntry(objectSource, pluginKeys);
|
|
194
|
+
content = content.slice(0, openBraceIndex) + updatedObject + content.slice(closeBraceIndex + 1);
|
|
195
|
+
content = insertImportLine(content, lapikitImport);
|
|
196
|
+
|
|
66
197
|
await fs.writeFile(svelteConfigFile, content);
|
|
67
198
|
terminal('success', `lapikitPreprocess added to ${svelteConfigFile}`);
|
|
68
199
|
}
|
|
200
|
+
|
|
201
|
+
export async function findViteConfigFile(projectPath) {
|
|
202
|
+
for (const ext of ['ts', 'js', 'mjs', 'cjs']) {
|
|
203
|
+
const file = path.join(projectPath, `vite.config.${ext}`);
|
|
204
|
+
try {
|
|
205
|
+
await fs.access(file);
|
|
206
|
+
return file;
|
|
207
|
+
} catch {
|
|
208
|
+
// lapikit other step
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function findSveltekitPluginCall(content) {
|
|
215
|
+
const match = content.match(/sveltekit\s*\(\s*\{/);
|
|
216
|
+
if (!match) return null;
|
|
217
|
+
|
|
218
|
+
const openBraceIndex = match.index + match[0].length - 1;
|
|
219
|
+
const closeBraceIndex = findMatchingDelimiter(content, openBraceIndex, '{', '}');
|
|
220
|
+
if (closeBraceIndex === -1) return null;
|
|
221
|
+
|
|
222
|
+
return { openBraceIndex, closeBraceIndex };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export async function addLiliPreprocessToViteConfig(viteConfigFile, pluginKeys = []) {
|
|
226
|
+
let content = await fs.readFile(viteConfigFile, 'utf-8');
|
|
227
|
+
const lapikitImport = `import { lapikitPreprocess } from 'lapikit/preprocess';`;
|
|
228
|
+
|
|
229
|
+
if (content.includes(`from 'lapikit/preprocess'`)) {
|
|
230
|
+
const updated = mergeExistingPreprocessCall(content, pluginKeys);
|
|
231
|
+
if (!updated) {
|
|
232
|
+
terminal('warn', `lapikitPreprocess already imported in ${viteConfigFile}`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
await fs.writeFile(viteConfigFile, updated);
|
|
236
|
+
terminal('success', `lapikitPreprocess plugins updated in ${viteConfigFile}`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const pluginCall = findSveltekitPluginCall(content);
|
|
241
|
+
if (!pluginCall) {
|
|
242
|
+
throw new Error(`Could not find a sveltekit({ ... }) plugin call in ${viteConfigFile}`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const { openBraceIndex, closeBraceIndex } = pluginCall;
|
|
246
|
+
const objectSource = content.slice(openBraceIndex, closeBraceIndex + 1);
|
|
247
|
+
const updatedObject = injectPreprocessEntry(objectSource, pluginKeys);
|
|
248
|
+
content = content.slice(0, openBraceIndex) + updatedObject + content.slice(closeBraceIndex + 1);
|
|
249
|
+
content = insertImportLine(content, lapikitImport);
|
|
250
|
+
|
|
251
|
+
await fs.writeFile(viteConfigFile, content);
|
|
252
|
+
terminal('success', `lapikitPreprocess added to ${viteConfigFile}`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Since SvelteKit 2.62, Svelte/preprocess config can be passed directly to the
|
|
256
|
+
// sveltekit() vite plugin instead of svelte.config.js — when it is, svelte.config.js
|
|
257
|
+
// is ignored, so the vite.config plugin call takes priority when both exist.
|
|
258
|
+
export async function resolveSveltePreprocessTarget(projectPath) {
|
|
259
|
+
const viteConfigFile = await findViteConfigFile(projectPath);
|
|
260
|
+
if (viteConfigFile) {
|
|
261
|
+
const content = await fs.readFile(viteConfigFile, 'utf-8');
|
|
262
|
+
if (findSveltekitPluginCall(content)) {
|
|
263
|
+
return { file: viteConfigFile, add: addLiliPreprocessToViteConfig };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const svelteConfigFile = await findSvelteConfigFile(projectPath);
|
|
269
|
+
return { file: svelteConfigFile, add: addLiliPreprocess };
|
|
270
|
+
} catch {
|
|
271
|
+
throw new Error(
|
|
272
|
+
'No svelte.config file found, and no sveltekit({ ... }) plugin config found in vite.config.(js|ts) ' +
|
|
273
|
+
"Add lapikitPreprocess() manually: import { lapikitPreprocess } from 'lapikit/preprocess'; " +
|
|
274
|
+
'then add it to your preprocess array.'
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export async function findEslintConfigFile(projectPath) {
|
|
280
|
+
for (const ext of ['js', 'mjs', 'cjs', 'ts']) {
|
|
281
|
+
const file = path.join(projectPath, `eslint.config.${ext}`);
|
|
282
|
+
try {
|
|
283
|
+
await fs.access(file);
|
|
284
|
+
return file;
|
|
285
|
+
} catch {
|
|
286
|
+
// lapikit other step
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
throw new Error('No eslint.config.js file found');
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export async function addLapikitEslintConfig(eslintConfigFile) {
|
|
293
|
+
let content = await fs.readFile(eslintConfigFile, 'utf-8');
|
|
294
|
+
const lapikitImport = `import lapikitConfig from 'eslint-config-lapikit';`;
|
|
295
|
+
|
|
296
|
+
if (content.includes(`from 'eslint-config-lapikit'`)) {
|
|
297
|
+
terminal('warn', `eslint-config-lapikit already imported in ${eslintConfigFile}`);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
content = insertImportLine(content, lapikitImport);
|
|
302
|
+
|
|
303
|
+
// Matches `export default [...]` as well as wrapped forms like
|
|
304
|
+
// `export default defineConfig([...])`, `export default defineConfig(a, b)`
|
|
305
|
+
// (rest-args form, no array) and member-expression wrappers like
|
|
306
|
+
// `export default ts.config(...)`.
|
|
307
|
+
const exportArrayPattern = /export\s+default\s*(?:\[|[\w.]+\s*\()/;
|
|
308
|
+
if (!exportArrayPattern.test(content)) {
|
|
309
|
+
throw new Error(
|
|
310
|
+
`Could not find "export default [...]" in ${eslintConfigFile}. Please add "...lapikitConfig" manually.`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
content = content.replace(exportArrayPattern, (m) => `${m}\n\t...lapikitConfig,`);
|
|
315
|
+
|
|
316
|
+
await fs.writeFile(eslintConfigFile, content);
|
|
317
|
+
terminal('success', `eslint-config-lapikit added to ${eslintConfigFile}`);
|
|
318
|
+
}
|
package/bin/index.js
CHANGED
|
@@ -1,31 +1,111 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { ansi, terminal, createRL, toggle } from './helpers.js';
|
|
3
|
-
import {
|
|
2
|
+
import { ansi, terminal, createRL, toggle, select, multiselect } from './helpers.js';
|
|
3
|
+
import {
|
|
4
|
+
resolveSveltePreprocessTarget,
|
|
5
|
+
installDependency,
|
|
6
|
+
findEslintConfigFile,
|
|
7
|
+
addLapikitEslintConfig
|
|
8
|
+
} from './hooks.js';
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
10
|
+
const ADDONS = [{ title: '@lapikit/repl', value: '@lapikit/repl', key: 'repl' }];
|
|
11
|
+
|
|
12
|
+
const PKG_MANAGER = [
|
|
13
|
+
{ title: 'npm', value: 'npm' },
|
|
14
|
+
{ title: 'yarn', value: 'yarn' },
|
|
15
|
+
{ title: 'pnpm', value: 'pnpm' },
|
|
16
|
+
{ title: 'bun', value: 'bun' }
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
function buildSteps(config, projectPath) {
|
|
20
|
+
const pluginKeys = config.addons
|
|
21
|
+
.map((value) => ADDONS.find((addon) => addon.value === value)?.key)
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
|
|
24
|
+
const steps = [];
|
|
25
|
+
|
|
26
|
+
steps.push({
|
|
27
|
+
id: 'preprocess',
|
|
28
|
+
label: 'Add lapikitPreprocess to your project',
|
|
29
|
+
run: async () => {
|
|
30
|
+
const target = await resolveSveltePreprocessTarget(projectPath);
|
|
31
|
+
await target.add(target.file, pluginKeys);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
for (const addonValue of config.addons) {
|
|
36
|
+
steps.push({
|
|
37
|
+
id: `addon:${addonValue}`,
|
|
38
|
+
label: `Install ${addonValue} (${config.pkgManager})`,
|
|
39
|
+
run: () => installDependency(config.pkgManager, addonValue, projectPath)
|
|
40
|
+
});
|
|
41
|
+
}
|
|
7
42
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
43
|
+
if (config.installEslintConfig) {
|
|
44
|
+
steps.push({
|
|
45
|
+
id: 'eslint-install',
|
|
46
|
+
label: `Install eslint-config-lapikit (${config.pkgManager})`,
|
|
47
|
+
run: () => installDependency(config.pkgManager, 'eslint-config-lapikit', projectPath)
|
|
48
|
+
});
|
|
49
|
+
steps.push({
|
|
50
|
+
id: 'eslint-config',
|
|
51
|
+
needs: 'eslint-install',
|
|
52
|
+
label: 'Add eslint-config-lapikit to eslint.config',
|
|
53
|
+
run: async () => {
|
|
54
|
+
const eslintConfigFile = await findEslintConfigFile(projectPath);
|
|
55
|
+
await addLapikitEslintConfig(eslintConfigFile);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return steps;
|
|
61
|
+
}
|
|
16
62
|
|
|
17
|
-
|
|
63
|
+
async function runSteps(config, projectPath) {
|
|
64
|
+
const steps = buildSteps(config, projectPath);
|
|
65
|
+
const results = [];
|
|
66
|
+
const failed = new Set();
|
|
18
67
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
68
|
+
for (let i = 0; i < steps.length; i++) {
|
|
69
|
+
const step = steps[i];
|
|
70
|
+
const tag = ansi.bold.blue(`[${i + 1}/${steps.length}]`);
|
|
22
71
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
72
|
+
if (step.needs && failed.has(step.needs)) {
|
|
73
|
+
results.push({ label: step.label, ok: false, skipped: true });
|
|
74
|
+
terminal('warn', `${tag} ${step.label} - skipped (prerequisite failed)`);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
await step.run();
|
|
80
|
+
results.push({ label: step.label, ok: true });
|
|
81
|
+
terminal('success', `${tag} ${step.label}`);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (step.id) failed.add(step.id);
|
|
84
|
+
results.push({ label: step.label, ok: false, error: error.message });
|
|
85
|
+
terminal('error', `${tag} ${step.label} - ${error.message}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return results;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function run() {
|
|
93
|
+
const rl = createRL();
|
|
94
|
+
const config = {
|
|
95
|
+
installEslintConfig: false,
|
|
96
|
+
addons: []
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
console.log(ansi.color.blue(' ██╗ █████╗ ██████╗ ██╗██╗ ██╗██╗████████╗'));
|
|
100
|
+
console.log(ansi.color.blue(' ██║ ██╔══██╗██╔══██╗██║██║ ██╔╝██║╚══██╔══╝'));
|
|
101
|
+
console.log(ansi.color.blue(' ██║ ███████║██████╔╝██║█████╔╝ ██║ ██║ '));
|
|
102
|
+
console.log(ansi.color.blue(' ██║ ██╔══██║██╔═══╝ ██║██╔═██╗ ██║ ██║ '));
|
|
103
|
+
console.log(ansi.color.blue(' ██████╗ ██║ ██║██║ ██║██║ ██╗██║ ██║ '));
|
|
104
|
+
console.log(ansi.color.blue(' ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ '));
|
|
105
|
+
|
|
106
|
+
terminal('none', `${ansi.bold.blue('Lapikit')} - Components Library for Svelte`);
|
|
107
|
+
terminal('none', `Developed by ${ansi.bold.blue('Nycolaide')}`);
|
|
108
|
+
terminal('none', `Documentation: https://lapikit.dev\n`);
|
|
29
109
|
|
|
30
110
|
const confirm = await toggle(rl, 'Launch install Lapikit on your project?');
|
|
31
111
|
if (!confirm) {
|
|
@@ -33,25 +113,20 @@ async function run() {
|
|
|
33
113
|
process.exit(0);
|
|
34
114
|
}
|
|
35
115
|
|
|
36
|
-
|
|
116
|
+
config.installEslintConfig = await toggle(rl, 'Install eslint-config-lapikit?');
|
|
117
|
+
config.pkgManager = await select(rl, 'Select package manager:', PKG_MANAGER);
|
|
118
|
+
config.addons = await multiselect(rl, 'Select addons to install:', ADDONS);
|
|
37
119
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
} catch (error) {
|
|
42
|
-
terminal('warn', `Warning: Could not update svelte.config file: ${error.message}`);
|
|
43
|
-
}
|
|
120
|
+
const results = await runSteps(config, process.cwd());
|
|
121
|
+
rl.close();
|
|
122
|
+
return results;
|
|
44
123
|
}
|
|
45
124
|
|
|
46
125
|
run()
|
|
47
|
-
.then(() => {
|
|
48
|
-
|
|
49
|
-
terminal('none', `Website: https://lapikit.dev`);
|
|
50
|
-
terminal('none', `Github: https://github.com/lapikit/lapikit`);
|
|
51
|
-
terminal('none', `Support the developement: https://buymeacoffee.com/nycolaide`);
|
|
52
|
-
process.exit(0);
|
|
126
|
+
.then((results) => {
|
|
127
|
+
process.exitCode = results?.some((r) => !r.ok) ? 1 : 0;
|
|
53
128
|
})
|
|
54
129
|
.catch((error) => {
|
|
55
130
|
terminal('error', `Error: ${error}`);
|
|
56
|
-
process.
|
|
131
|
+
process.exitCode = 1;
|
|
57
132
|
});
|
|
@@ -125,6 +125,16 @@
|
|
|
125
125
|
display: none;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
.kit-accordion[data-variant='text'] :global(.kit-accordion-item),
|
|
129
|
+
.kit-accordion[data-variant='text'] :global(.kit-accordion-item:first-child:last-child) {
|
|
130
|
+
border-radius: 0 !important;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.kit-accordion:not([data-variant='text'])
|
|
134
|
+
:global(.kit-accordion-item[data-read-only='false'][data-disabled='false'] > button:hover) {
|
|
135
|
+
background: var(--kit-accordion-item-hover-bg);
|
|
136
|
+
}
|
|
137
|
+
|
|
128
138
|
/**
|
|
129
139
|
* rounded
|
|
130
140
|
* @link ...
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
.kit-accordion-item__separator {
|
|
202
|
-
width:
|
|
202
|
+
width: 100%;
|
|
203
203
|
height: 1px;
|
|
204
204
|
display: block;
|
|
205
205
|
position: relative;
|
|
@@ -207,9 +207,10 @@
|
|
|
207
207
|
margin: 0 auto;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
.kit-accordion-item[data-read-only='false'][data-disabled='false']
|
|
210
|
+
/* .kit-accordion-item[data-read-only='false'][data-disabled='false']:not([data-variant='text'])
|
|
211
|
+
> button:hover {
|
|
211
212
|
background: var(--kit-accordion-item-hover-bg);
|
|
212
|
-
}
|
|
213
|
+
} */
|
|
213
214
|
|
|
214
215
|
/**I think is a good idea for not use this*/
|
|
215
216
|
/* .kit-accordion-item[data-active='true'][data-disabled='false'][data-read-only='false'] > button {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
--kit-density-comfortable: 4px;
|
|
63
63
|
|
|
64
64
|
--kit-shadow-opacity: 30%;
|
|
65
|
-
--kit-shadow-
|
|
65
|
+
--kit-shadow-ambient-opacity: 15%;
|
|
66
66
|
|
|
67
67
|
--kit-disabled-opacity: 0.55;
|
|
68
68
|
--kit-font:
|
|
@@ -261,7 +261,7 @@
|
|
|
261
261
|
box-shadow:
|
|
262
262
|
0 1px 2px color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-opacity), transparent),
|
|
263
263
|
0 3px 8px -2px
|
|
264
|
-
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-
|
|
264
|
+
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-ambient-opacity), transparent);
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
:global([data-elevation='2']),
|
|
@@ -270,7 +270,7 @@
|
|
|
270
270
|
box-shadow:
|
|
271
271
|
0 1px 3px color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-opacity), transparent),
|
|
272
272
|
0 5px 12px -3px
|
|
273
|
-
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-
|
|
273
|
+
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-ambient-opacity), transparent);
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
:global([data-elevation='3']),
|
|
@@ -279,7 +279,7 @@
|
|
|
279
279
|
box-shadow:
|
|
280
280
|
0 2px 4px color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-opacity), transparent),
|
|
281
281
|
0 8px 20px -4px
|
|
282
|
-
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-
|
|
282
|
+
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-ambient-opacity), transparent);
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
:global([data-elevation='4']),
|
|
@@ -288,7 +288,7 @@
|
|
|
288
288
|
box-shadow:
|
|
289
289
|
0 3px 5px color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-opacity), transparent),
|
|
290
290
|
0 11px 26px -5px
|
|
291
|
-
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-
|
|
291
|
+
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-ambient-opacity), transparent);
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
:global([data-elevation='5']),
|
|
@@ -297,7 +297,7 @@
|
|
|
297
297
|
box-shadow:
|
|
298
298
|
0 4px 6px color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-opacity), transparent),
|
|
299
299
|
0 14px 32px -6px
|
|
300
|
-
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-
|
|
300
|
+
color-mix(in oklab, var(--kit-color-shadow) var(--kit-shadow-ambient-opacity), transparent);
|
|
301
301
|
}
|
|
302
302
|
@keyframes -global-animation-l-ripple {
|
|
303
303
|
from {
|
|
@@ -116,20 +116,26 @@
|
|
|
116
116
|
|
|
117
117
|
<style>
|
|
118
118
|
.kit-icon {
|
|
119
|
+
--kit-icon-size-xs: 12px;
|
|
120
|
+
--kit-icon-size-sm: 14px;
|
|
121
|
+
--kit-icon-size-md: 16px;
|
|
122
|
+
--kit-icon-size-lg: 18px;
|
|
123
|
+
--kit-icon-size-xl: 20px;
|
|
124
|
+
|
|
119
125
|
display: inline-flex;
|
|
120
126
|
align-items: center;
|
|
121
127
|
justify-content: center;
|
|
122
128
|
text-indent: 0;
|
|
123
129
|
line-height: 1;
|
|
124
|
-
font-size: var(--kit-icon-current-size);
|
|
130
|
+
font-size: var(--kit-icon-current-size, var(--kit-icon-size-md));
|
|
125
131
|
vertical-align: middle;
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
.kit-icon :global(svg),
|
|
129
135
|
.kit-icon img,
|
|
130
136
|
.kit-icon .kit-icon__mask {
|
|
131
|
-
width: var(--kit-icon-current-size);
|
|
132
|
-
height: var(--kit-icon-current-size);
|
|
137
|
+
width: var(--kit-icon-current-size, var(--kit-icon-size-md));
|
|
138
|
+
height: var(--kit-icon-current-size, var(--kit-icon-size-md));
|
|
133
139
|
flex-shrink: 0;
|
|
134
140
|
display: block;
|
|
135
141
|
}
|
|
@@ -152,18 +158,18 @@
|
|
|
152
158
|
* @link https://lapikit.dev/docs/components/icon#size
|
|
153
159
|
*/
|
|
154
160
|
.kit-icon[data-size='xs'] {
|
|
155
|
-
--kit-icon-current-size:
|
|
161
|
+
--kit-icon-current-size: var(--kit-icon-size-xs);
|
|
156
162
|
}
|
|
157
163
|
.kit-icon[data-size='sm'] {
|
|
158
|
-
--kit-icon-current-size:
|
|
164
|
+
--kit-icon-current-size: var(--kit-icon-size-sm);
|
|
159
165
|
}
|
|
160
166
|
.kit-icon[data-size='md'] {
|
|
161
|
-
--kit-icon-current-size:
|
|
167
|
+
--kit-icon-current-size: var(--kit-icon-size-md);
|
|
162
168
|
}
|
|
163
169
|
.kit-icon[data-size='lg'] {
|
|
164
|
-
--kit-icon-current-size:
|
|
170
|
+
--kit-icon-current-size: var(--kit-icon-size-lg);
|
|
165
171
|
}
|
|
166
172
|
.kit-icon[data-size='xl'] {
|
|
167
|
-
--kit-icon-current-size:
|
|
173
|
+
--kit-icon-current-size: var(--kit-icon-size-xl);
|
|
168
174
|
}
|
|
169
175
|
</style>
|
|
@@ -136,14 +136,14 @@
|
|
|
136
136
|
* variant
|
|
137
137
|
* @link https://lapikit.dev/docs/components/list#variants
|
|
138
138
|
*/
|
|
139
|
-
.kit-list[data-variant='filled']
|
|
139
|
+
.kit-list[data-variant='filled'] {
|
|
140
140
|
--kit-list-item-bg: var(--kit-color-surface-2);
|
|
141
141
|
--kit-list-item-fg: var(--kit-color-text);
|
|
142
142
|
|
|
143
143
|
--kit-list-item-hover-bg: color-mix(in oklab, var(---kit-list-item-bg), black 10%);
|
|
144
144
|
--kit-list-item-active-bg: color-mix(in oklab, var(--kit-list-item-bg), black 16%);
|
|
145
145
|
}
|
|
146
|
-
.kit-list[data-variant='outline']
|
|
146
|
+
.kit-list[data-variant='outline'] {
|
|
147
147
|
--kit-list-item-bg: transparent;
|
|
148
148
|
--kit-list-item-fg: var(--kit-color-text);
|
|
149
149
|
--kit-list-item-bd: var(--kit-list-item-fg);
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
--kit-list-item-hover-bg: color-mix(in oklab, var(--kit-list-item-fg), transparent 80%);
|
|
152
152
|
--kit-list-item-active-bg: color-mix(in oklab, var(--kit-list-item-fg), transparent 92%);
|
|
153
153
|
}
|
|
154
|
-
.kit-list[data-variant='text']
|
|
154
|
+
.kit-list[data-variant='text'] {
|
|
155
155
|
--kit-list-item-bg: transparent;
|
|
156
156
|
--kit-list-item-fg: var(--kit-color-text);
|
|
157
157
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lapikit",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"@tabler/icons-svelte": "^3.40.0",
|
|
84
84
|
"@testing-library/jest-dom": "^6.6.3",
|
|
85
85
|
"@testing-library/svelte": "^5.2.4",
|
|
86
|
+
"@types/node": "^26.1.0",
|
|
86
87
|
"eslint": "^9.18.0",
|
|
87
88
|
"eslint-config-prettier": "^10.0.1",
|
|
88
89
|
"eslint-plugin-svelte": "^3.0.0",
|