yaxa-svelte 2.0.4 → 2.2.0
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 +38 -3
- package/dist/components/blocks/FAQ.svelte.d.ts +1 -1
- package/dist/components/blocks/FeatureGrid.svelte.d.ts +1 -1
- package/dist/components/blocks/Testimonials.svelte.d.ts +1 -1
- package/dist/components/elements/Avatar.svelte.d.ts +7 -25
- package/dist/components/elements/Badge.svelte.d.ts +15 -57
- package/dist/components/elements/Button.svelte.d.ts +19 -77
- package/dist/components/elements/Carousel.svelte.d.ts +2 -54
- package/dist/components/elements/CodeBlock.svelte +237 -8
- package/dist/components/elements/CodeBlock.test.js +227 -0
- package/dist/components/elements/CodeDiff.svelte +14 -0
- package/dist/components/elements/CodeDiff.test.js +16 -0
- package/dist/components/elements/EmptyState.svelte.d.ts +6 -26
- package/dist/components/elements/Icon.svelte.d.ts +6 -22
- package/dist/components/elements/Kbd.svelte.d.ts +5 -19
- package/dist/components/elements/Progress.svelte.d.ts +9 -35
- package/dist/components/elements/Skeleton.svelte.d.ts +8 -32
- package/dist/components/elements/Terminal.svelte.d.ts +1 -1
- package/dist/components/elements/Timeline.svelte.d.ts +4 -16
- package/dist/components/elements/Tree.svelte.d.ts +3 -13
- package/dist/components/elements/VirtualList.svelte.d.ts +3 -13
- package/dist/components/forms/Combobox.svelte.d.ts +7 -29
- package/dist/components/forms/Input.svelte.d.ts +9 -35
- package/dist/components/forms/MultiSelect.svelte.d.ts +7 -29
- package/dist/components/forms/NumberInput.svelte.d.ts +7 -29
- package/dist/components/forms/Select.svelte.d.ts +7 -29
- package/dist/components/forms/Switch.svelte.d.ts +8 -32
- package/dist/components/forms/Textarea.svelte.d.ts +11 -45
- package/dist/components/layout/Card.svelte.d.ts +10 -42
- package/dist/components/layout/Container.svelte.d.ts +7 -25
- package/dist/components/layout/DashboardShell.svelte.d.ts +1 -31
- package/dist/components/layout/ResizablePanels.svelte.d.ts +1 -35
- package/dist/components/navigation/CommandPalette.dom.test.d.ts +1 -0
- package/dist/components/navigation/CommandPalette.dom.test.js +76 -0
- package/dist/components/navigation/Stepper.svelte.d.ts +3 -13
- package/dist/components/overlays/Alert.svelte.d.ts +5 -19
- package/dist/components/overlays/Drawer.svelte.d.ts +3 -13
- package/dist/components/overlays/Modal.svelte.d.ts +6 -22
- package/dist/components/overlays/NotificationCenter.svelte.d.ts +1 -1
- package/dist/components/overlays/Slideover.svelte.d.ts +5 -19
- package/dist/components/overlays/Toast.svelte.d.ts +12 -44
- package/dist/components/saas/OrgSwitcher.svelte.d.ts +1 -1
- package/dist/components/saas/PasskeyUI.svelte.d.ts +1 -1
- package/dist/server/endpoint/endpoint.test.d.ts +1 -0
- package/dist/server/endpoint/endpoint.test.js +364 -0
- package/dist/server/endpoint/guards.d.ts +52 -0
- package/dist/server/endpoint/guards.js +137 -0
- package/dist/server/endpoint/index.d.ts +14 -0
- package/dist/server/endpoint/index.js +238 -0
- package/dist/server/endpoint/problem.d.ts +26 -0
- package/dist/server/endpoint/problem.js +62 -0
- package/dist/server/endpoint/types.d.ts +144 -0
- package/dist/server/endpoint/types.js +1 -0
- package/dist/server/endpoint/validate.d.ts +21 -0
- package/dist/server/endpoint/validate.js +128 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/polar/index.d.ts +2 -1
- package/dist/server/polar/index.js +9 -8
- package/dist/server/polar/webhook.js +14 -11
- package/dist/server/polar/webhook.test.js +81 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +12 -1
- package/dist/utils/cn.d.ts +2 -2
- package/package.json +11 -13
|
@@ -46,10 +46,15 @@
|
|
|
46
46
|
const isSvelte = ['svelte', 'svelte5', 'sv'].includes(lang);
|
|
47
47
|
const isHtml = ['html', 'xml', 'svg'].includes(lang);
|
|
48
48
|
const isPython = ['python', 'py'].includes(lang);
|
|
49
|
-
const
|
|
49
|
+
const isRust = ['rust', 'rs'].includes(lang);
|
|
50
|
+
const isGo = ['go', 'golang'].includes(lang);
|
|
51
|
+
const isSql = ['sql', 'pgsql', 'postgres', 'postgresql', 'mysql', 'sqlite'].includes(lang);
|
|
52
|
+
const isGraphQL = ['graphql', 'gql'].includes(lang);
|
|
50
53
|
const isBash = ['bash', 'sh', 'zsh', 'shell'].includes(lang);
|
|
51
54
|
const isJson = ['json', 'jsonc', 'json5'].includes(lang);
|
|
52
55
|
const isCss = ['css', 'scss', 'postcss', 'tailwind', 'tailwindcss'].includes(lang);
|
|
56
|
+
const isYaml = ['yaml', 'yml'].includes(lang);
|
|
57
|
+
const isToml = ['toml', 'cargo'].includes(lang);
|
|
53
58
|
|
|
54
59
|
let multilineState:
|
|
55
60
|
| null
|
|
@@ -179,7 +184,7 @@
|
|
|
179
184
|
|
|
180
185
|
if (
|
|
181
186
|
(!isLatex && remaining.startsWith('//')) ||
|
|
182
|
-
((isPython || isBash || lang === 'env' ||
|
|
187
|
+
((isPython || isBash || lang === 'env' || isYaml || isToml || isGraphQL) &&
|
|
183
188
|
remaining.startsWith('#')) ||
|
|
184
189
|
(isLatex && remaining.startsWith('%')) ||
|
|
185
190
|
(isSql && remaining.startsWith('--'))
|
|
@@ -188,8 +193,8 @@
|
|
|
188
193
|
break;
|
|
189
194
|
}
|
|
190
195
|
|
|
191
|
-
// 2. Python Triple-Quoted Strings (Docstrings)
|
|
192
|
-
if (isPython && (remaining.startsWith('"""') || remaining.startsWith("'''"))) {
|
|
196
|
+
// 2. Python & TOML Triple-Quoted Strings (Docstrings / Multiline)
|
|
197
|
+
if ((isPython || isToml) && (remaining.startsWith('"""') || remaining.startsWith("'''"))) {
|
|
193
198
|
const delim = remaining.startsWith('"""') ? '"""' : "'''";
|
|
194
199
|
const closeIdx = remaining.indexOf(delim, 3);
|
|
195
200
|
if (closeIdx !== -1) {
|
|
@@ -228,6 +233,110 @@
|
|
|
228
233
|
}
|
|
229
234
|
}
|
|
230
235
|
|
|
236
|
+
// 4b. YAML Key-Value Pairs, Anchors, Aliases & Directives
|
|
237
|
+
if (isYaml) {
|
|
238
|
+
// Anchors & Aliases (&anchor, *alias)
|
|
239
|
+
const anchorMatch = remaining.match(/^([&*][\w.-]+)/);
|
|
240
|
+
if (anchorMatch) {
|
|
241
|
+
tokens.push({ text: anchorMatch[0], type: 'macro' });
|
|
242
|
+
remaining = remaining.slice(anchorMatch[0].length);
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Tags (!!str, !!int, !!map, !custom)
|
|
247
|
+
const yamlTagMatch = remaining.match(/^(!{1,2}[\w.-]+)/);
|
|
248
|
+
if (yamlTagMatch) {
|
|
249
|
+
tokens.push({ text: yamlTagMatch[0], type: 'directive' });
|
|
250
|
+
remaining = remaining.slice(yamlTagMatch[0].length);
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Document start/end markers (--- or ...)
|
|
255
|
+
if (remaining === line) {
|
|
256
|
+
const docMarkerMatch = remaining.match(/^(\s*(?:---|(?:\.\.\.))\s*)$/);
|
|
257
|
+
if (docMarkerMatch) {
|
|
258
|
+
tokens.push({ text: docMarkerMatch[1], type: 'punctuation' });
|
|
259
|
+
remaining = remaining.slice(docMarkerMatch[1].length);
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Quoted keys before ':'
|
|
265
|
+
const yamlQuotedKeyMatch = remaining.match(
|
|
266
|
+
/^("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')(?=\s*:(?:\s|$))/
|
|
267
|
+
);
|
|
268
|
+
if (yamlQuotedKeyMatch) {
|
|
269
|
+
tokens.push({ text: yamlQuotedKeyMatch[1], type: 'attr' });
|
|
270
|
+
remaining = remaining.slice(yamlQuotedKeyMatch[1].length);
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Bare keys before ':'
|
|
275
|
+
const yamlKeyMatch = remaining.match(/^([\w.-]+)(?=\s*:(?:\s|$))/);
|
|
276
|
+
if (yamlKeyMatch) {
|
|
277
|
+
tokens.push({ text: yamlKeyMatch[0], type: 'attr' });
|
|
278
|
+
remaining = remaining.slice(yamlKeyMatch[0].length);
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// YAML booleans, nulls & block scalar indicators
|
|
283
|
+
const yamlKwMatch = remaining.match(/^(true|false|yes|no|on|off|null|~|[|>][+-]?)\b/i);
|
|
284
|
+
if (yamlKwMatch) {
|
|
285
|
+
tokens.push({ text: yamlKwMatch[0], type: 'keyword' });
|
|
286
|
+
remaining = remaining.slice(yamlKwMatch[0].length);
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// 4c. TOML Table Headers & Key-Value Pairs
|
|
292
|
+
if (isToml) {
|
|
293
|
+
// Table headers ([table] or [[array_of_tables]])
|
|
294
|
+
const tomlTableMatch = remaining.match(/^(\[\[?[\w.:"-]+\]\]?)/);
|
|
295
|
+
if (tomlTableMatch) {
|
|
296
|
+
tokens.push({ text: tomlTableMatch[0], type: 'directive' });
|
|
297
|
+
remaining = remaining.slice(tomlTableMatch[0].length);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Quoted keys before '='
|
|
302
|
+
const tomlQuotedKeyMatch = remaining.match(
|
|
303
|
+
/^("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')(?=\s*=)/
|
|
304
|
+
);
|
|
305
|
+
if (tomlQuotedKeyMatch) {
|
|
306
|
+
tokens.push({ text: tomlQuotedKeyMatch[1], type: 'attr' });
|
|
307
|
+
remaining = remaining.slice(tomlQuotedKeyMatch[1].length);
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Bare or dotted keys before '='
|
|
312
|
+
const tomlKeyMatch = remaining.match(/^([\w.-]+)(?=\s*=)/);
|
|
313
|
+
if (tomlKeyMatch) {
|
|
314
|
+
tokens.push({ text: tomlKeyMatch[0], type: 'attr' });
|
|
315
|
+
remaining = remaining.slice(tomlKeyMatch[0].length);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Special TOML float constants (+inf, -inf, nan)
|
|
320
|
+
const tomlFloatMatch = remaining.match(/^([+-]?(?:inf|nan))\b/i);
|
|
321
|
+
if (tomlFloatMatch) {
|
|
322
|
+
tokens.push({ text: tomlFloatMatch[0], type: 'number' });
|
|
323
|
+
remaining = remaining.slice(tomlFloatMatch[0].length);
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// 4d. ISO Dates / Timestamps for YAML & TOML
|
|
329
|
+
if (isYaml || isToml) {
|
|
330
|
+
const dateMatch = remaining.match(
|
|
331
|
+
/^(\d{4}-\d{2}-\d{2}(?:[Tt\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:[Zz]|[+-]\d{2}:\d{2})?)?|\d{2}:\d{2}:\d{2}(?:\.\d+)?)\b/
|
|
332
|
+
);
|
|
333
|
+
if (dateMatch) {
|
|
334
|
+
tokens.push({ text: dateMatch[0], type: 'number' });
|
|
335
|
+
remaining = remaining.slice(dateMatch[0].length);
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
231
340
|
// 5. CSS & Tailwind CSS v4 At-Rules, Variables & Colors
|
|
232
341
|
if (isCss) {
|
|
233
342
|
// Tailwind v4 & CSS At-rules (@theme, @utility, @source, @plugin, @import, @custom-variant, etc.)
|
|
@@ -316,10 +425,10 @@
|
|
|
316
425
|
}
|
|
317
426
|
}
|
|
318
427
|
|
|
319
|
-
// 9. Python Built-in Types
|
|
428
|
+
// 9. Python Built-in Types & Modern Typing Constructs (Python 3.0 to 3.13+)
|
|
320
429
|
if (isPython) {
|
|
321
430
|
const pyTypeMatch = remaining.match(
|
|
322
|
-
/^(str|int|float|bool|dict|list|tuple|set|bytes|Any|Optional|Union|Callable|Literal)\b/
|
|
431
|
+
/^(str|int|float|bool|dict|list|tuple|set|bytes|Any|Optional|Union|Callable|Literal|TypeIs|TypeGuard|Self)\b/
|
|
323
432
|
);
|
|
324
433
|
if (pyTypeMatch) {
|
|
325
434
|
tokens.push({ text: pyTypeMatch[0], type: 'macro' });
|
|
@@ -340,6 +449,126 @@
|
|
|
340
449
|
}
|
|
341
450
|
}
|
|
342
451
|
|
|
452
|
+
// 10b. Rust Attributes, Macro Invocations, Lifetimes & Standard Types
|
|
453
|
+
if (isRust) {
|
|
454
|
+
// Rust Attributes (#[derive(Debug, Clone)], #![no_std])
|
|
455
|
+
const rustAttrMatch = remaining.match(/^#(!?\[[\w:,()=\s"-]+\])/);
|
|
456
|
+
if (rustAttrMatch) {
|
|
457
|
+
tokens.push({ text: rustAttrMatch[0], type: 'decorator' });
|
|
458
|
+
remaining = remaining.slice(rustAttrMatch[0].length);
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Rust Macro Invocations (println!, vec!, format!, panic!, etc.)
|
|
463
|
+
const rustMacroMatch = remaining.match(
|
|
464
|
+
/^(println|eprintln|print|eprint|format|vec|panic|assert|assert_eq|assert_ne|todo|unimplemented|unreachable|write|writeln|cfg|include|env|concat)!/
|
|
465
|
+
);
|
|
466
|
+
if (rustMacroMatch) {
|
|
467
|
+
tokens.push({ text: rustMacroMatch[0], type: 'macro' });
|
|
468
|
+
remaining = remaining.slice(rustMacroMatch[0].length);
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Rust Lifetimes ('a, 'static)
|
|
473
|
+
const lifetimeMatch = remaining.match(/^'(?:static|[a-z_]\w*)(?!')\b/);
|
|
474
|
+
if (lifetimeMatch) {
|
|
475
|
+
tokens.push({ text: lifetimeMatch[0], type: 'macro' });
|
|
476
|
+
remaining = remaining.slice(lifetimeMatch[0].length);
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Rust Primitive & Standard Types
|
|
481
|
+
const rustTypeMatch = remaining.match(
|
|
482
|
+
/^(i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize|f32|f64|bool|char|str|String|Option|Result|Vec|Box|Rc|Arc|Cell|RefCell|Mutex|RwLock|HashMap|HashSet|BTreeMap|BTreeSet|Self|None|Some|Ok|Err)\b/
|
|
483
|
+
);
|
|
484
|
+
if (rustTypeMatch) {
|
|
485
|
+
tokens.push({ text: rustTypeMatch[0], type: 'macro' });
|
|
486
|
+
remaining = remaining.slice(rustTypeMatch[0].length);
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// 10c. Go Primitive Types & Built-ins
|
|
492
|
+
if (isGo) {
|
|
493
|
+
const goTypeMatch = remaining.match(
|
|
494
|
+
/^(string|int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|uintptr|byte|rune|float32|float64|complex64|complex128|error|any|bool)\b/
|
|
495
|
+
);
|
|
496
|
+
if (goTypeMatch) {
|
|
497
|
+
tokens.push({ text: goTypeMatch[0], type: 'macro' });
|
|
498
|
+
remaining = remaining.slice(goTypeMatch[0].length);
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const goBuiltinMatch = remaining.match(
|
|
503
|
+
/^(make|len|cap|new|append|copy|close|delete|panic|recover|print|println|complex|real|imag)\b(?=\s*\()/
|
|
504
|
+
);
|
|
505
|
+
if (goBuiltinMatch) {
|
|
506
|
+
tokens.push({ text: goBuiltinMatch[0], type: 'function' });
|
|
507
|
+
remaining = remaining.slice(goBuiltinMatch[0].length);
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// 10d. SQL Data Types & Clauses
|
|
513
|
+
if (isSql) {
|
|
514
|
+
// SQL Standard Data Types
|
|
515
|
+
const sqlTypeMatch = remaining.match(
|
|
516
|
+
/^(INTEGER|INT|BIGINT|SMALLINT|TINYINT|SERIAL|BIGSERIAL|VARCHAR|TEXT|CHAR|CHARACTER|BOOLEAN|BOOL|DATE|TIME|TIMESTAMP|TIMESTAMPTZ|NUMERIC|DECIMAL|FLOAT|REAL|DOUBLE\s+PRECISION|DOUBLE|JSON|JSONB|UUID|BLOB|BYTEA|ARRAY|INTERVAL)\b/i
|
|
517
|
+
);
|
|
518
|
+
if (sqlTypeMatch) {
|
|
519
|
+
tokens.push({ text: sqlTypeMatch[0], type: 'macro' });
|
|
520
|
+
remaining = remaining.slice(sqlTypeMatch[0].length);
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Comprehensive SQL Clauses & Keywords
|
|
525
|
+
const sqlKwMatch = remaining.match(
|
|
526
|
+
/^(CREATE|ALTER|DROP|TRUNCATE|TABLE|DATABASE|SCHEMA|VIEW|INDEX|TRIGGER|FUNCTION|PROCEDURE|PRIMARY|FOREIGN|KEY|REFERENCES|CONSTRAINT|CHECK|DEFAULT|UNIQUE|NOT|NULL|CASCADE|RESTRICT|SELECT|DISTINCT|FROM|WHERE|AND|OR|IN|BETWEEN|LIKE|ILIKE|IS|EXISTS|HAVING|GROUP|ORDER|BY|ASC|DESC|LIMIT|OFFSET|FETCH|FIRST|NEXT|ROWS|ONLY|JOIN|INNER|LEFT|RIGHT|FULL|OUTER|CROSS|ON|USING|INSERT|INTO|VALUES|UPDATE|SET|DELETE|RETURNING|UNION|INTERSECT|EXCEPT|ALL|CASE|WHEN|THEN|ELSE|END|AS|BEGIN|COMMIT|ROLLBACK|TRANSACTION|SAVEPOINT|GRANT|REVOKE|WITH|RECURSIVE|OVER|PARTITION)\b/i
|
|
527
|
+
);
|
|
528
|
+
if (sqlKwMatch) {
|
|
529
|
+
tokens.push({ text: sqlKwMatch[0], type: 'keyword' });
|
|
530
|
+
remaining = remaining.slice(sqlKwMatch[0].length);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// 10e. GraphQL Variables, Directives & Scalars
|
|
536
|
+
if (isGraphQL) {
|
|
537
|
+
// GraphQL Variables ($id, $input)
|
|
538
|
+
const gqlVarMatch = remaining.match(/^(\$[\w]+)\b/);
|
|
539
|
+
if (gqlVarMatch) {
|
|
540
|
+
tokens.push({ text: gqlVarMatch[0], type: 'macro' });
|
|
541
|
+
remaining = remaining.slice(gqlVarMatch[0].length);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Directives (@include, @skip, @deprecated, @specifiedBy)
|
|
546
|
+
const gqlDirMatch = remaining.match(/^(@(?:include|skip|deprecated|specifiedBy))\b/);
|
|
547
|
+
if (gqlDirMatch) {
|
|
548
|
+
tokens.push({ text: gqlDirMatch[0], type: 'decorator' });
|
|
549
|
+
remaining = remaining.slice(gqlDirMatch[0].length);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Core Scalars
|
|
554
|
+
const gqlScalarMatch = remaining.match(/^(String|Int|Float|Boolean|ID)\b/);
|
|
555
|
+
if (gqlScalarMatch) {
|
|
556
|
+
tokens.push({ text: gqlScalarMatch[0], type: 'macro' });
|
|
557
|
+
remaining = remaining.slice(gqlScalarMatch[0].length);
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// GraphQL Keywords
|
|
562
|
+
const gqlKwMatch = remaining.match(
|
|
563
|
+
/^(query|mutation|subscription|fragment|on|type|input|interface|union|enum|scalar|schema|directive|extend)\b/
|
|
564
|
+
);
|
|
565
|
+
if (gqlKwMatch) {
|
|
566
|
+
tokens.push({ text: gqlKwMatch[0], type: 'keyword' });
|
|
567
|
+
remaining = remaining.slice(gqlKwMatch[0].length);
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
343
572
|
// 11. Bash / Shell Variables & CLI Flags
|
|
344
573
|
if (isBash) {
|
|
345
574
|
const bashVarMatch = remaining.match(/^(\$\{?[\w#?@*!$-]+\}?)/);
|
|
@@ -591,7 +820,7 @@
|
|
|
591
820
|
? 'text-neutral-800 dark:text-neutral-200'
|
|
592
821
|
: 'text-neutral-200'} {wrap ? 'whitespace-pre-wrap' : 'whitespace-pre'}"><code
|
|
593
822
|
class="language-{language}"
|
|
594
|
-
>{#each tokenizedLines as lineTokens, lineIdx}{@const lineNum =
|
|
823
|
+
>{#each tokenizedLines as lineTokens, lineIdx (lineIdx)}{@const lineNum =
|
|
595
824
|
lineIdx + 1}{@const isHighlighted = highlightLines.includes(lineNum)}<div
|
|
596
825
|
class="table-row {isHighlighted
|
|
597
826
|
? '-mx-4 block border-l-2 border-primary-500 bg-primary-500/10 px-4'
|
|
@@ -600,7 +829,7 @@
|
|
|
600
829
|
? 'text-neutral-400 dark:text-neutral-600'
|
|
601
830
|
: 'text-neutral-600 dark:text-neutral-500'}">{lineNum}</span
|
|
602
831
|
>{/if}<span class="table-cell"
|
|
603
|
-
>{#each lineTokens as token}{#if token.type === 'rune'}<span
|
|
832
|
+
>{#each lineTokens as token, tokenIdx (tokenIdx)}{#if token.type === 'rune'}<span
|
|
604
833
|
class="font-bold text-amber-500 dark:text-amber-400">{token.text}</span
|
|
605
834
|
>{:else if token.type === 'keyword'}<span class="font-semibold text-primary-500"
|
|
606
835
|
>{token.text}</span
|
|
@@ -48,6 +48,36 @@ describe('tokenizeCode', () => {
|
|
|
48
48
|
const line4 = tokens[4].map((t) => ({ text: t.text, type: t.type }));
|
|
49
49
|
expect(line4).toContainEqual({ text: 'assert', type: 'keyword' });
|
|
50
50
|
});
|
|
51
|
+
it('tokenizes Python 3.13+ syntax: type parameters, TypeIs narrowing, match/case and decorators', () => {
|
|
52
|
+
const pyCode = `type Point[T = int] = tuple[T, T]
|
|
53
|
+
@deprecated
|
|
54
|
+
def is_str(val: object) -> TypeIs[str]:
|
|
55
|
+
match val:
|
|
56
|
+
case str():
|
|
57
|
+
return True
|
|
58
|
+
case _:
|
|
59
|
+
return False`;
|
|
60
|
+
const tokens = tokenizeCode(pyCode, 'python');
|
|
61
|
+
expect(tokens).toHaveLength(8);
|
|
62
|
+
// Line 0: type Point[T = int] = tuple[T, T]
|
|
63
|
+
const line0 = tokens[0].map((t) => ({ text: t.text, type: t.type }));
|
|
64
|
+
expect(line0).toContainEqual({ text: 'type', type: 'keyword' });
|
|
65
|
+
expect(line0).toContainEqual({ text: 'int', type: 'macro' });
|
|
66
|
+
expect(line0).toContainEqual({ text: 'tuple', type: 'macro' });
|
|
67
|
+
// Line 1: @deprecated
|
|
68
|
+
const line1 = tokens[1].map((t) => ({ text: t.text, type: t.type }));
|
|
69
|
+
expect(line1).toContainEqual({ text: '@deprecated', type: 'decorator' });
|
|
70
|
+
// Line 2: def is_str(val: object) -> TypeIs[str]:
|
|
71
|
+
const line2 = tokens[2].map((t) => ({ text: t.text, type: t.type }));
|
|
72
|
+
expect(line2).toContainEqual({ text: 'def', type: 'keyword' });
|
|
73
|
+
expect(line2).toContainEqual({ text: 'TypeIs', type: 'macro' });
|
|
74
|
+
expect(line2).toContainEqual({ text: 'str', type: 'macro' });
|
|
75
|
+
// Line 3 & 4: match / case
|
|
76
|
+
const line3 = tokens[3].map((t) => ({ text: t.text, type: t.type }));
|
|
77
|
+
expect(line3).toContainEqual({ text: 'match', type: 'keyword' });
|
|
78
|
+
const line4 = tokens[4].map((t) => ({ text: t.text, type: t.type }));
|
|
79
|
+
expect(line4).toContainEqual({ text: 'case', type: 'keyword' });
|
|
80
|
+
});
|
|
51
81
|
it('tokenizes tailwind css v4 at-rules, variables and hex colors', () => {
|
|
52
82
|
const cssCode = `@theme {
|
|
53
83
|
--color-primary-500: #ff3e00;
|
|
@@ -150,4 +180,201 @@ type TaskResult = Awaited<Promise<Record<string, unknown>>>;`;
|
|
|
150
180
|
const line11 = tokens[11].map((t) => ({ text: t.text, type: t.type }));
|
|
151
181
|
expect(line11).toContainEqual({ text: 'Awaited', type: 'macro' });
|
|
152
182
|
});
|
|
183
|
+
it('tokenizes YAML keys, anchors, aliases, tags, booleans and document markers', () => {
|
|
184
|
+
const yamlCode = `---
|
|
185
|
+
# App configuration
|
|
186
|
+
name: "yaxa-app"
|
|
187
|
+
version: 2.1
|
|
188
|
+
enabled: true
|
|
189
|
+
maintenance: off
|
|
190
|
+
defaults: &base_config
|
|
191
|
+
timeout: 30
|
|
192
|
+
production: *base_config
|
|
193
|
+
tag_demo: !custom_tag
|
|
194
|
+
created_at: 2026-10-27`;
|
|
195
|
+
const tokens = tokenizeCode(yamlCode, 'yaml');
|
|
196
|
+
expect(tokens).toHaveLength(11);
|
|
197
|
+
// Line 0: ---
|
|
198
|
+
expect(tokens[0][0]).toEqual({ text: '---', type: 'punctuation' });
|
|
199
|
+
// Line 1: # App configuration
|
|
200
|
+
expect(tokens[1][0]).toEqual({ text: '# App configuration', type: 'comment' });
|
|
201
|
+
// Line 2: name: "yaxa-app"
|
|
202
|
+
const line2 = tokens[2].map((t) => ({ text: t.text, type: t.type }));
|
|
203
|
+
expect(line2).toContainEqual({ text: 'name', type: 'attr' });
|
|
204
|
+
expect(line2).toContainEqual({ text: '"yaxa-app"', type: 'string' });
|
|
205
|
+
// Line 4: enabled: true
|
|
206
|
+
const line4 = tokens[4].map((t) => ({ text: t.text, type: t.type }));
|
|
207
|
+
expect(line4).toContainEqual({ text: 'enabled', type: 'attr' });
|
|
208
|
+
expect(line4).toContainEqual({ text: 'true', type: 'keyword' });
|
|
209
|
+
// Line 5: maintenance: off
|
|
210
|
+
const line5 = tokens[5].map((t) => ({ text: t.text, type: t.type }));
|
|
211
|
+
expect(line5).toContainEqual({ text: 'maintenance', type: 'attr' });
|
|
212
|
+
expect(line5).toContainEqual({ text: 'off', type: 'keyword' });
|
|
213
|
+
// Line 6: defaults: &base_config
|
|
214
|
+
const line6 = tokens[6].map((t) => ({ text: t.text, type: t.type }));
|
|
215
|
+
expect(line6).toContainEqual({ text: 'defaults', type: 'attr' });
|
|
216
|
+
expect(line6).toContainEqual({ text: '&base_config', type: 'macro' });
|
|
217
|
+
// Line 8: production: *base_config
|
|
218
|
+
const line8 = tokens[8].map((t) => ({ text: t.text, type: t.type }));
|
|
219
|
+
expect(line8).toContainEqual({ text: 'production', type: 'attr' });
|
|
220
|
+
expect(line8).toContainEqual({ text: '*base_config', type: 'macro' });
|
|
221
|
+
// Line 9: tag_demo: !custom_tag
|
|
222
|
+
const line9 = tokens[9].map((t) => ({ text: t.text, type: t.type }));
|
|
223
|
+
expect(line9).toContainEqual({ text: 'tag_demo', type: 'attr' });
|
|
224
|
+
expect(line9).toContainEqual({ text: '!custom_tag', type: 'directive' });
|
|
225
|
+
// Line 10: created_at: 2026-10-27
|
|
226
|
+
const line10 = tokens[10].map((t) => ({ text: t.text, type: t.type }));
|
|
227
|
+
expect(line10).toContainEqual({ text: 'created_at', type: 'attr' });
|
|
228
|
+
expect(line10).toContainEqual({ text: '2026-10-27', type: 'number' });
|
|
229
|
+
});
|
|
230
|
+
it('tokenizes TOML table headers, keys, dates, and multiline strings', () => {
|
|
231
|
+
const tomlCode = `[server]
|
|
232
|
+
port = 8080
|
|
233
|
+
enabled = true
|
|
234
|
+
started = 1979-05-27T07:32:00Z
|
|
235
|
+
bio = """
|
|
236
|
+
Hello World
|
|
237
|
+
Multilined
|
|
238
|
+
"""`;
|
|
239
|
+
const tokens = tokenizeCode(tomlCode, 'toml');
|
|
240
|
+
expect(tokens).toHaveLength(8);
|
|
241
|
+
// Line 0: [server]
|
|
242
|
+
expect(tokens[0][0]).toEqual({ text: '[server]', type: 'directive' });
|
|
243
|
+
// Line 1: port = 8080
|
|
244
|
+
const line1 = tokens[1].map((t) => ({ text: t.text, type: t.type }));
|
|
245
|
+
expect(line1).toContainEqual({ text: 'port', type: 'attr' });
|
|
246
|
+
expect(line1).toContainEqual({ text: '8080', type: 'number' });
|
|
247
|
+
// Line 2: enabled = true
|
|
248
|
+
const line2 = tokens[2].map((t) => ({ text: t.text, type: t.type }));
|
|
249
|
+
expect(line2).toContainEqual({ text: 'enabled', type: 'attr' });
|
|
250
|
+
expect(line2).toContainEqual({ text: 'true', type: 'keyword' });
|
|
251
|
+
// Line 3: started = 1979-05-27T07:32:00Z
|
|
252
|
+
const line3 = tokens[3].map((t) => ({ text: t.text, type: t.type }));
|
|
253
|
+
expect(line3).toContainEqual({ text: 'started', type: 'attr' });
|
|
254
|
+
expect(line3).toContainEqual({ text: '1979-05-27T07:32:00Z', type: 'number' });
|
|
255
|
+
// Multiline string across lines 4, 5, 6, 7
|
|
256
|
+
expect(tokens[4].some((t) => t.type === 'string')).toBe(true);
|
|
257
|
+
expect(tokens[5][0].type).toBe('string');
|
|
258
|
+
expect(tokens[6][0].type).toBe('string');
|
|
259
|
+
expect(tokens[7].some((t) => t.type === 'string')).toBe(true);
|
|
260
|
+
});
|
|
261
|
+
it('tokenizes Rust attributes, macros, lifetimes, and standard types to Tier 1 standard', () => {
|
|
262
|
+
const rustCode = `#[derive(Debug, Clone)]
|
|
263
|
+
pub fn process<'a>(name: &'a str) -> Option<String> {
|
|
264
|
+
let items: Vec<i32> = vec![1, 2, 3];
|
|
265
|
+
println!("Processed: {}", name);
|
|
266
|
+
Some(name.to_string())
|
|
267
|
+
}`;
|
|
268
|
+
const tokens = tokenizeCode(rustCode, 'rust');
|
|
269
|
+
expect(tokens).toHaveLength(6);
|
|
270
|
+
// Line 0: #[derive(Debug, Clone)]
|
|
271
|
+
expect(tokens[0][0].type).toBe('decorator');
|
|
272
|
+
// Line 1: pub fn process<'a>(name: &'a str) -> Option<String>
|
|
273
|
+
const line1 = tokens[1].map((t) => ({ text: t.text, type: t.type }));
|
|
274
|
+
expect(line1).toContainEqual({ text: 'pub', type: 'keyword' });
|
|
275
|
+
expect(line1).toContainEqual({ text: 'fn', type: 'keyword' });
|
|
276
|
+
expect(line1).toContainEqual({ text: "'a", type: 'macro' });
|
|
277
|
+
expect(line1).toContainEqual({ text: 'str', type: 'macro' });
|
|
278
|
+
expect(line1).toContainEqual({ text: 'Option', type: 'macro' });
|
|
279
|
+
expect(line1).toContainEqual({ text: 'String', type: 'macro' });
|
|
280
|
+
// Line 2: let items: Vec<i32> = vec![1, 2, 3];
|
|
281
|
+
const line2 = tokens[2].map((t) => ({ text: t.text, type: t.type }));
|
|
282
|
+
expect(line2).toContainEqual({ text: 'Vec', type: 'macro' });
|
|
283
|
+
expect(line2).toContainEqual({ text: 'i32', type: 'macro' });
|
|
284
|
+
expect(line2).toContainEqual({ text: 'vec!', type: 'macro' });
|
|
285
|
+
// Line 3: println!("...")
|
|
286
|
+
const line3 = tokens[3].map((t) => ({ text: t.text, type: t.type }));
|
|
287
|
+
expect(line3).toContainEqual({ text: 'println!', type: 'macro' });
|
|
288
|
+
// Line 4: Some(...)
|
|
289
|
+
const line4 = tokens[4].map((t) => ({ text: t.text, type: t.type }));
|
|
290
|
+
expect(line4).toContainEqual({ text: 'Some', type: 'macro' });
|
|
291
|
+
});
|
|
292
|
+
it('tokenizes Go built-in functions and primitive types to Tier 1 standard', () => {
|
|
293
|
+
const goCode = `package main
|
|
294
|
+
func NewBuffer(size int) (error, any) {
|
|
295
|
+
buf := make([]byte, size)
|
|
296
|
+
println(len(buf))
|
|
297
|
+
return nil, buf
|
|
298
|
+
}`;
|
|
299
|
+
const tokens = tokenizeCode(goCode, 'go');
|
|
300
|
+
expect(tokens).toHaveLength(6);
|
|
301
|
+
// Line 0: package main
|
|
302
|
+
expect(tokens[0].some((t) => t.text === 'package' && t.type === 'keyword')).toBe(true);
|
|
303
|
+
// Line 1: func NewBuffer(size int) (error, any)
|
|
304
|
+
const line1 = tokens[1].map((t) => ({ text: t.text, type: t.type }));
|
|
305
|
+
expect(line1).toContainEqual({ text: 'func', type: 'keyword' });
|
|
306
|
+
expect(line1).toContainEqual({ text: 'int', type: 'macro' });
|
|
307
|
+
expect(line1).toContainEqual({ text: 'error', type: 'macro' });
|
|
308
|
+
expect(line1).toContainEqual({ text: 'any', type: 'macro' });
|
|
309
|
+
// Line 2: make([]byte)
|
|
310
|
+
const line2 = tokens[2].map((t) => ({ text: t.text, type: t.type }));
|
|
311
|
+
expect(line2).toContainEqual({ text: 'make', type: 'function' });
|
|
312
|
+
expect(line2).toContainEqual({ text: 'byte', type: 'macro' });
|
|
313
|
+
// Line 3: len(buf)
|
|
314
|
+
const line3 = tokens[3].map((t) => ({ text: t.text, type: t.type }));
|
|
315
|
+
expect(line3).toContainEqual({ text: 'len', type: 'function' });
|
|
316
|
+
});
|
|
317
|
+
it('tokenizes SQL DDL, constraints, clauses, and data types to Tier 1 standard', () => {
|
|
318
|
+
const sqlCode = `CREATE TABLE users (
|
|
319
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
320
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
321
|
+
metadata JSONB,
|
|
322
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
323
|
+
);
|
|
324
|
+
SELECT id, email FROM users WHERE id IS NOT NULL ORDER BY created_at DESC LIMIT 10;`;
|
|
325
|
+
const tokens = tokenizeCode(sqlCode, 'sql');
|
|
326
|
+
expect(tokens).toHaveLength(7);
|
|
327
|
+
// Line 0: CREATE TABLE users (
|
|
328
|
+
const line0 = tokens[0].map((t) => ({ text: t.text.toUpperCase(), type: t.type }));
|
|
329
|
+
expect(line0).toContainEqual({ text: 'CREATE', type: 'keyword' });
|
|
330
|
+
expect(line0).toContainEqual({ text: 'TABLE', type: 'keyword' });
|
|
331
|
+
// Line 1: id UUID PRIMARY KEY DEFAULT ...
|
|
332
|
+
const line1 = tokens[1].map((t) => ({ text: t.text.toUpperCase(), type: t.type }));
|
|
333
|
+
expect(line1).toContainEqual({ text: 'UUID', type: 'macro' });
|
|
334
|
+
expect(line1).toContainEqual({ text: 'PRIMARY', type: 'keyword' });
|
|
335
|
+
expect(line1).toContainEqual({ text: 'KEY', type: 'keyword' });
|
|
336
|
+
expect(line1).toContainEqual({ text: 'DEFAULT', type: 'keyword' });
|
|
337
|
+
// Line 2: VARCHAR
|
|
338
|
+
const line2 = tokens[2].map((t) => ({ text: t.text.toUpperCase(), type: t.type }));
|
|
339
|
+
expect(line2).toContainEqual({ text: 'VARCHAR', type: 'macro' });
|
|
340
|
+
expect(line2).toContainEqual({ text: 'NOT', type: 'keyword' });
|
|
341
|
+
expect(line2).toContainEqual({ text: 'NULL', type: 'keyword' });
|
|
342
|
+
expect(line2).toContainEqual({ text: 'UNIQUE', type: 'keyword' });
|
|
343
|
+
// Line 3: JSONB
|
|
344
|
+
const line3 = tokens[3].map((t) => ({ text: t.text.toUpperCase(), type: t.type }));
|
|
345
|
+
expect(line3).toContainEqual({ text: 'JSONB', type: 'macro' });
|
|
346
|
+
// Line 4: TIMESTAMPTZ
|
|
347
|
+
const line4 = tokens[4].map((t) => ({ text: t.text.toUpperCase(), type: t.type }));
|
|
348
|
+
expect(line4).toContainEqual({ text: 'TIMESTAMPTZ', type: 'macro' });
|
|
349
|
+
// Line 6: SELECT query
|
|
350
|
+
const line6 = tokens[6].map((t) => ({ text: t.text.toUpperCase(), type: t.type }));
|
|
351
|
+
expect(line6).toContainEqual({ text: 'SELECT', type: 'keyword' });
|
|
352
|
+
expect(line6).toContainEqual({ text: 'FROM', type: 'keyword' });
|
|
353
|
+
expect(line6).toContainEqual({ text: 'WHERE', type: 'keyword' });
|
|
354
|
+
expect(line6).toContainEqual({ text: 'ORDER', type: 'keyword' });
|
|
355
|
+
expect(line6).toContainEqual({ text: 'BY', type: 'keyword' });
|
|
356
|
+
expect(line6).toContainEqual({ text: 'DESC', type: 'keyword' });
|
|
357
|
+
expect(line6).toContainEqual({ text: 'LIMIT', type: 'keyword' });
|
|
358
|
+
});
|
|
359
|
+
it('tokenizes GraphQL queries, variables, directives, and scalar types to Tier 1 standard', () => {
|
|
360
|
+
const gqlCode = `query GetUser($userId: ID!, $withDetails: Boolean = true) {
|
|
361
|
+
user(id: $userId) {
|
|
362
|
+
id
|
|
363
|
+
name
|
|
364
|
+
email @include(if: $withDetails)
|
|
365
|
+
}
|
|
366
|
+
}`;
|
|
367
|
+
const tokens = tokenizeCode(gqlCode, 'graphql');
|
|
368
|
+
expect(tokens).toHaveLength(7);
|
|
369
|
+
// Line 0: query GetUser($userId: ID!, $withDetails: Boolean = true)
|
|
370
|
+
const line0 = tokens[0].map((t) => ({ text: t.text, type: t.type }));
|
|
371
|
+
expect(line0).toContainEqual({ text: 'query', type: 'keyword' });
|
|
372
|
+
expect(line0).toContainEqual({ text: '$userId', type: 'macro' });
|
|
373
|
+
expect(line0).toContainEqual({ text: 'ID', type: 'macro' });
|
|
374
|
+
expect(line0).toContainEqual({ text: '$withDetails', type: 'macro' });
|
|
375
|
+
expect(line0).toContainEqual({ text: 'Boolean', type: 'macro' });
|
|
376
|
+
// Line 4: email @include(if: $withDetails)
|
|
377
|
+
const line4 = tokens[4].map((t) => ({ text: t.text, type: t.type }));
|
|
378
|
+
expect(line4).toContainEqual({ text: '@include', type: 'decorator' });
|
|
379
|
+
});
|
|
153
380
|
});
|
|
@@ -318,6 +318,8 @@
|
|
|
318
318
|
>{token.text}</span
|
|
319
319
|
>{:else if token.type === 'macro'}<span
|
|
320
320
|
class="font-semibold text-indigo-600 dark:text-indigo-400">{token.text}</span
|
|
321
|
+
>{:else if token.type === 'decorator'}<span
|
|
322
|
+
class="text-purple-600 dark:text-purple-400">{token.text}</span
|
|
321
323
|
>{:else if token.type === 'number'}<span
|
|
322
324
|
class="text-purple-600 dark:text-purple-400">{token.text}</span
|
|
323
325
|
>{:else if token.type === 'punctuation'}<span
|
|
@@ -378,6 +380,12 @@
|
|
|
378
380
|
<span class="text-amber-600 dark:text-amber-300">{token.text}</span>
|
|
379
381
|
{:else if token.type === 'function'}
|
|
380
382
|
<span class="text-sky-600 dark:text-sky-400">{token.text}</span>
|
|
383
|
+
{:else if token.type === 'macro'}
|
|
384
|
+
<span class="font-semibold text-indigo-600 dark:text-indigo-400"
|
|
385
|
+
>{token.text}</span
|
|
386
|
+
>
|
|
387
|
+
{:else if token.type === 'decorator'}
|
|
388
|
+
<span class="text-purple-600 dark:text-purple-400">{token.text}</span>
|
|
381
389
|
{:else if token.type === 'number'}
|
|
382
390
|
<span class="text-purple-600 dark:text-purple-400">{token.text}</span>
|
|
383
391
|
{:else if token.type === 'punctuation'}
|
|
@@ -437,6 +445,12 @@
|
|
|
437
445
|
<span class="text-amber-600 dark:text-amber-300">{token.text}</span>
|
|
438
446
|
{:else if token.type === 'function'}
|
|
439
447
|
<span class="text-sky-600 dark:text-sky-400">{token.text}</span>
|
|
448
|
+
{:else if token.type === 'macro'}
|
|
449
|
+
<span class="font-semibold text-indigo-600 dark:text-indigo-400"
|
|
450
|
+
>{token.text}</span
|
|
451
|
+
>
|
|
452
|
+
{:else if token.type === 'decorator'}
|
|
453
|
+
<span class="text-purple-600 dark:text-purple-400">{token.text}</span>
|
|
440
454
|
{:else if token.type === 'number'}
|
|
441
455
|
<span class="text-purple-600 dark:text-purple-400">{token.text}</span>
|
|
442
456
|
{:else if token.type === 'punctuation'}
|
|
@@ -49,4 +49,20 @@ describe('CodeDiff Component & Diff Algorithm', () => {
|
|
|
49
49
|
expect(target.textContent).toContain('Greeting.svelte');
|
|
50
50
|
cleanup();
|
|
51
51
|
});
|
|
52
|
+
it('should highlight modern Python 3.13 and macro tokens in diff view', () => {
|
|
53
|
+
const original = `def check(val: object):\n return False`;
|
|
54
|
+
const modified = `@deprecated\ndef check(val: object) -> TypeIs[str]:\n return True`;
|
|
55
|
+
const { target, cleanup } = renderComponent(CodeDiff, {
|
|
56
|
+
original,
|
|
57
|
+
modified,
|
|
58
|
+
filename: 'validator.py',
|
|
59
|
+
language: 'python',
|
|
60
|
+
viewMode: 'unified'
|
|
61
|
+
});
|
|
62
|
+
expect(target.textContent).toContain('@deprecated');
|
|
63
|
+
expect(target.textContent).toContain('TypeIs');
|
|
64
|
+
expect(target.textContent).toContain('+3');
|
|
65
|
+
expect(target.textContent).toContain('-2');
|
|
66
|
+
cleanup();
|
|
67
|
+
});
|
|
52
68
|
});
|
|
@@ -3,35 +3,15 @@ import type { Snippet } from 'svelte';
|
|
|
3
3
|
import type { IconSource } from './Icon.svelte';
|
|
4
4
|
export declare const emptyStateVariants: import("tailwind-variants").TVReturnType<{
|
|
5
5
|
size: {
|
|
6
|
-
sm:
|
|
7
|
-
md:
|
|
8
|
-
lg:
|
|
6
|
+
sm: string;
|
|
7
|
+
md: string;
|
|
8
|
+
lg: string;
|
|
9
9
|
};
|
|
10
10
|
bordered: {
|
|
11
|
-
true:
|
|
12
|
-
false:
|
|
11
|
+
true: string;
|
|
12
|
+
false: string;
|
|
13
13
|
};
|
|
14
|
-
}, undefined, "flex flex-col items-center justify-center text-center p-8 rounded-2xl bg-white dark:bg-neutral-900/50",
|
|
15
|
-
size: {
|
|
16
|
-
sm: "py-6 px-4 gap-2";
|
|
17
|
-
md: "py-10 px-6 gap-3";
|
|
18
|
-
lg: "py-16 px-8 gap-4";
|
|
19
|
-
};
|
|
20
|
-
bordered: {
|
|
21
|
-
true: "border border-dashed border-neutral-300 dark:border-neutral-800";
|
|
22
|
-
false: "border-0";
|
|
23
|
-
};
|
|
24
|
-
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
25
|
-
size: {
|
|
26
|
-
sm: "py-6 px-4 gap-2";
|
|
27
|
-
md: "py-10 px-6 gap-3";
|
|
28
|
-
lg: "py-16 px-8 gap-4";
|
|
29
|
-
};
|
|
30
|
-
bordered: {
|
|
31
|
-
true: "border border-dashed border-neutral-300 dark:border-neutral-800";
|
|
32
|
-
false: "border-0";
|
|
33
|
-
};
|
|
34
|
-
}, undefined>>;
|
|
14
|
+
}, undefined, "flex flex-col items-center justify-center text-center p-8 rounded-2xl bg-white dark:bg-neutral-900/50", undefined, undefined, undefined>;
|
|
35
15
|
export type EmptyStateProps = VariantProps<typeof emptyStateVariants> & {
|
|
36
16
|
title?: string;
|
|
37
17
|
description?: string;
|