@clypra/ui 1.0.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/.releaserc.json +16 -0
- package/package.json +47 -0
- package/src/components/GraphInspector/GraphInspector.tsx +91 -0
- package/src/components/GraphInspector/index.ts +2 -0
- package/src/components/PassInspector/PassInspector.tsx +128 -0
- package/src/components/PassInspector/index.ts +2 -0
- package/src/components/PerformanceMonitor/PerformanceMonitor.tsx +129 -0
- package/src/components/PerformanceMonitor/index.ts +2 -0
- package/src/components/PresetManager/PresetManager.tsx +420 -0
- package/src/components/PresetManager/index.ts +2 -0
- package/src/components/PreviewCanvas/PreviewCanvas.tsx +168 -0
- package/src/components/PreviewCanvas/index.ts +2 -0
- package/src/components/ResourceInspector/ResourceInspector.tsx +126 -0
- package/src/components/ResourceInspector/index.ts +2 -0
- package/src/components/Timeline/Timeline.tsx +291 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/ValidationPanel/ValidationPanel.tsx +428 -0
- package/src/components/ValidationPanel/index.ts +2 -0
- package/src/index.ts +35 -0
- package/tsconfig.json +22 -0
- package/tsup.config.ts +14 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ValidationPanel Component
|
|
3
|
+
*
|
|
4
|
+
* Shows errors and warnings from effect validation.
|
|
5
|
+
* Categorized by type with actionable suggestions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useState } from "react";
|
|
9
|
+
|
|
10
|
+
export type ValidationSeverity = "error" | "warning" | "info";
|
|
11
|
+
|
|
12
|
+
export interface ValidationIssue {
|
|
13
|
+
id: string;
|
|
14
|
+
severity: ValidationSeverity;
|
|
15
|
+
category: string;
|
|
16
|
+
message: string;
|
|
17
|
+
details?: string;
|
|
18
|
+
suggestion?: string;
|
|
19
|
+
location?: {
|
|
20
|
+
node?: string;
|
|
21
|
+
pass?: number;
|
|
22
|
+
line?: number;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ValidationPanelProps {
|
|
27
|
+
/** Validation issues to display */
|
|
28
|
+
issues: ValidationIssue[];
|
|
29
|
+
/** Callback when an issue is clicked */
|
|
30
|
+
onIssueClick?: (issue: ValidationIssue) => void;
|
|
31
|
+
/** Show only specific severity levels */
|
|
32
|
+
severityFilter?: ValidationSeverity[];
|
|
33
|
+
/** Show only specific categories */
|
|
34
|
+
categoryFilter?: string[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ValidationPanel({ issues, onIssueClick, severityFilter, categoryFilter }: ValidationPanelProps) {
|
|
38
|
+
const [expandedIssues, setExpandedIssues] = useState<Set<string>>(new Set());
|
|
39
|
+
const [activeSeverities, setActiveSeverities] = useState<Set<ValidationSeverity>>(new Set(["error", "warning", "info"]));
|
|
40
|
+
const [activeCategories, setActiveCategories] = useState<Set<string>>(new Set());
|
|
41
|
+
|
|
42
|
+
// Get all unique categories
|
|
43
|
+
const allCategories = Array.from(new Set(issues.map((i) => i.category))).sort();
|
|
44
|
+
|
|
45
|
+
// Initialize active categories
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
if (activeCategories.size === 0 && allCategories.length > 0) {
|
|
48
|
+
setActiveCategories(new Set(allCategories));
|
|
49
|
+
}
|
|
50
|
+
}, [allCategories.length]);
|
|
51
|
+
|
|
52
|
+
// Apply filters
|
|
53
|
+
const filteredIssues = issues.filter((issue) => {
|
|
54
|
+
const severityMatch = !severityFilter || severityFilter.length === 0 || severityFilter.includes(issue.severity) || activeSeverities.has(issue.severity);
|
|
55
|
+
|
|
56
|
+
const categoryMatch = !categoryFilter || categoryFilter.length === 0 || categoryFilter.includes(issue.category) || activeCategories.has(issue.category);
|
|
57
|
+
|
|
58
|
+
return severityMatch && categoryMatch;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Count by severity
|
|
62
|
+
const counts = {
|
|
63
|
+
error: issues.filter((i) => i.severity === "error").length,
|
|
64
|
+
warning: issues.filter((i) => i.severity === "warning").length,
|
|
65
|
+
info: issues.filter((i) => i.severity === "info").length,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const toggleExpanded = (issueId: string) => {
|
|
69
|
+
const newExpanded = new Set(expandedIssues);
|
|
70
|
+
if (newExpanded.has(issueId)) {
|
|
71
|
+
newExpanded.delete(issueId);
|
|
72
|
+
} else {
|
|
73
|
+
newExpanded.add(issueId);
|
|
74
|
+
}
|
|
75
|
+
setExpandedIssues(newExpanded);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const toggleSeverity = (severity: ValidationSeverity) => {
|
|
79
|
+
const newSeverities = new Set(activeSeverities);
|
|
80
|
+
if (newSeverities.has(severity)) {
|
|
81
|
+
newSeverities.delete(severity);
|
|
82
|
+
} else {
|
|
83
|
+
newSeverities.add(severity);
|
|
84
|
+
}
|
|
85
|
+
setActiveSeverities(newSeverities);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const toggleCategory = (category: string) => {
|
|
89
|
+
const newCategories = new Set(activeCategories);
|
|
90
|
+
if (newCategories.has(category)) {
|
|
91
|
+
newCategories.delete(category);
|
|
92
|
+
} else {
|
|
93
|
+
newCategories.add(category);
|
|
94
|
+
}
|
|
95
|
+
setActiveCategories(newCategories);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const getSeverityColor = (severity: ValidationSeverity) => {
|
|
99
|
+
switch (severity) {
|
|
100
|
+
case "error":
|
|
101
|
+
return { bg: "#7f1d1d", border: "#ef4444", text: "#fca5a5" };
|
|
102
|
+
case "warning":
|
|
103
|
+
return { bg: "#713f12", border: "#f59e0b", text: "#fcd34d" };
|
|
104
|
+
case "info":
|
|
105
|
+
return { bg: "#1e3a8a", border: "#3b82f6", text: "#93c5fd" };
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const getSeverityIcon = (severity: ValidationSeverity) => {
|
|
110
|
+
switch (severity) {
|
|
111
|
+
case "error":
|
|
112
|
+
return "✖";
|
|
113
|
+
case "warning":
|
|
114
|
+
return "âš ";
|
|
115
|
+
case "info":
|
|
116
|
+
return "ℹ";
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<div
|
|
122
|
+
style={{
|
|
123
|
+
padding: "16px",
|
|
124
|
+
background: "#0f172a",
|
|
125
|
+
borderRadius: "8px",
|
|
126
|
+
border: "1px solid #334155",
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
129
|
+
{/* Header */}
|
|
130
|
+
<div
|
|
131
|
+
style={{
|
|
132
|
+
display: "flex",
|
|
133
|
+
justifyContent: "space-between",
|
|
134
|
+
alignItems: "center",
|
|
135
|
+
marginBottom: "16px",
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
<h3 style={{ margin: 0, color: "#f1f5f9", fontSize: "16px" }}>Validation Results</h3>
|
|
139
|
+
<div
|
|
140
|
+
style={{
|
|
141
|
+
display: "flex",
|
|
142
|
+
gap: "12px",
|
|
143
|
+
fontSize: "14px",
|
|
144
|
+
fontWeight: 600,
|
|
145
|
+
}}
|
|
146
|
+
>
|
|
147
|
+
<button
|
|
148
|
+
onClick={() => toggleSeverity("error")}
|
|
149
|
+
style={{
|
|
150
|
+
padding: "4px 10px",
|
|
151
|
+
background: activeSeverities.has("error") ? "#7f1d1d" : "#334155",
|
|
152
|
+
color: activeSeverities.has("error") ? "#fca5a5" : "#94a3b8",
|
|
153
|
+
border: "none",
|
|
154
|
+
borderRadius: "4px",
|
|
155
|
+
cursor: "pointer",
|
|
156
|
+
}}
|
|
157
|
+
>
|
|
158
|
+
✖ {counts.error}
|
|
159
|
+
</button>
|
|
160
|
+
<button
|
|
161
|
+
onClick={() => toggleSeverity("warning")}
|
|
162
|
+
style={{
|
|
163
|
+
padding: "4px 10px",
|
|
164
|
+
background: activeSeverities.has("warning") ? "#713f12" : "#334155",
|
|
165
|
+
color: activeSeverities.has("warning") ? "#fcd34d" : "#94a3b8",
|
|
166
|
+
border: "none",
|
|
167
|
+
borderRadius: "4px",
|
|
168
|
+
cursor: "pointer",
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
âš {counts.warning}
|
|
172
|
+
</button>
|
|
173
|
+
<button
|
|
174
|
+
onClick={() => toggleSeverity("info")}
|
|
175
|
+
style={{
|
|
176
|
+
padding: "4px 10px",
|
|
177
|
+
background: activeSeverities.has("info") ? "#1e3a8a" : "#334155",
|
|
178
|
+
color: activeSeverities.has("info") ? "#93c5fd" : "#94a3b8",
|
|
179
|
+
border: "none",
|
|
180
|
+
borderRadius: "4px",
|
|
181
|
+
cursor: "pointer",
|
|
182
|
+
}}
|
|
183
|
+
>
|
|
184
|
+
ℹ {counts.info}
|
|
185
|
+
</button>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
{/* Category filters */}
|
|
190
|
+
{allCategories.length > 0 && (
|
|
191
|
+
<div style={{ marginBottom: "16px" }}>
|
|
192
|
+
<div
|
|
193
|
+
style={{
|
|
194
|
+
fontSize: "12px",
|
|
195
|
+
color: "#94a3b8",
|
|
196
|
+
marginBottom: "8px",
|
|
197
|
+
fontWeight: 600,
|
|
198
|
+
}}
|
|
199
|
+
>
|
|
200
|
+
Categories:
|
|
201
|
+
</div>
|
|
202
|
+
<div style={{ display: "flex", gap: "6px", flexWrap: "wrap" }}>
|
|
203
|
+
{allCategories.map((category) => (
|
|
204
|
+
<button
|
|
205
|
+
key={category}
|
|
206
|
+
onClick={() => toggleCategory(category)}
|
|
207
|
+
style={{
|
|
208
|
+
padding: "4px 10px",
|
|
209
|
+
background: activeCategories.has(category) ? "#3b82f6" : "#334155",
|
|
210
|
+
color: "white",
|
|
211
|
+
border: "none",
|
|
212
|
+
borderRadius: "4px",
|
|
213
|
+
cursor: "pointer",
|
|
214
|
+
fontSize: "12px",
|
|
215
|
+
}}
|
|
216
|
+
>
|
|
217
|
+
{category}
|
|
218
|
+
</button>
|
|
219
|
+
))}
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
)}
|
|
223
|
+
|
|
224
|
+
{/* Issues list */}
|
|
225
|
+
<div style={{ maxHeight: "500px", overflowY: "auto" }}>
|
|
226
|
+
{filteredIssues.length === 0 ? (
|
|
227
|
+
<div
|
|
228
|
+
style={{
|
|
229
|
+
padding: "48px 32px",
|
|
230
|
+
textAlign: "center",
|
|
231
|
+
color: "#64748b",
|
|
232
|
+
fontSize: "14px",
|
|
233
|
+
}}
|
|
234
|
+
>
|
|
235
|
+
{issues.length === 0 ? (
|
|
236
|
+
<div>
|
|
237
|
+
<div style={{ fontSize: "32px", marginBottom: "12px" }}>✓</div>
|
|
238
|
+
<div style={{ color: "#10b981", fontWeight: 600, fontSize: "16px" }}>No validation issues</div>
|
|
239
|
+
<div style={{ marginTop: "8px" }}>Everything looks good!</div>
|
|
240
|
+
</div>
|
|
241
|
+
) : (
|
|
242
|
+
<div>No issues match your filters</div>
|
|
243
|
+
)}
|
|
244
|
+
</div>
|
|
245
|
+
) : (
|
|
246
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
|
247
|
+
{filteredIssues.map((issue) => {
|
|
248
|
+
const colors = getSeverityColor(issue.severity);
|
|
249
|
+
const icon = getSeverityIcon(issue.severity);
|
|
250
|
+
const isExpanded = expandedIssues.has(issue.id);
|
|
251
|
+
|
|
252
|
+
return (
|
|
253
|
+
<div
|
|
254
|
+
key={issue.id}
|
|
255
|
+
style={{
|
|
256
|
+
padding: "12px",
|
|
257
|
+
background: "#1e293b",
|
|
258
|
+
border: `1px solid ${colors.border}`,
|
|
259
|
+
borderLeft: `4px solid ${colors.border}`,
|
|
260
|
+
borderRadius: "6px",
|
|
261
|
+
cursor: "pointer",
|
|
262
|
+
}}
|
|
263
|
+
onClick={() => {
|
|
264
|
+
toggleExpanded(issue.id);
|
|
265
|
+
onIssueClick?.(issue);
|
|
266
|
+
}}
|
|
267
|
+
>
|
|
268
|
+
{/* Issue header */}
|
|
269
|
+
<div
|
|
270
|
+
style={{
|
|
271
|
+
display: "flex",
|
|
272
|
+
alignItems: "start",
|
|
273
|
+
gap: "10px",
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
<span
|
|
277
|
+
style={{
|
|
278
|
+
fontSize: "16px",
|
|
279
|
+
color: colors.text,
|
|
280
|
+
fontWeight: 600,
|
|
281
|
+
marginTop: "2px",
|
|
282
|
+
}}
|
|
283
|
+
>
|
|
284
|
+
{icon}
|
|
285
|
+
</span>
|
|
286
|
+
<div style={{ flex: 1 }}>
|
|
287
|
+
<div
|
|
288
|
+
style={{
|
|
289
|
+
display: "flex",
|
|
290
|
+
alignItems: "center",
|
|
291
|
+
gap: "8px",
|
|
292
|
+
marginBottom: "6px",
|
|
293
|
+
}}
|
|
294
|
+
>
|
|
295
|
+
<span
|
|
296
|
+
style={{
|
|
297
|
+
fontSize: "12px",
|
|
298
|
+
fontWeight: 600,
|
|
299
|
+
padding: "2px 6px",
|
|
300
|
+
background: colors.bg,
|
|
301
|
+
color: colors.text,
|
|
302
|
+
borderRadius: "4px",
|
|
303
|
+
}}
|
|
304
|
+
>
|
|
305
|
+
{issue.category}
|
|
306
|
+
</span>
|
|
307
|
+
{issue.location && (
|
|
308
|
+
<span style={{ fontSize: "12px", color: "#64748b" }}>
|
|
309
|
+
{issue.location.node && `Node: ${issue.location.node}`}
|
|
310
|
+
{issue.location.pass !== undefined && ` • Pass ${issue.location.pass}`}
|
|
311
|
+
{issue.location.line !== undefined && ` • Line ${issue.location.line}`}
|
|
312
|
+
</span>
|
|
313
|
+
)}
|
|
314
|
+
</div>
|
|
315
|
+
<div
|
|
316
|
+
style={{
|
|
317
|
+
color: "#f1f5f9",
|
|
318
|
+
fontSize: "14px",
|
|
319
|
+
fontWeight: 500,
|
|
320
|
+
marginBottom: isExpanded ? "8px" : 0,
|
|
321
|
+
}}
|
|
322
|
+
>
|
|
323
|
+
{issue.message}
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
{/* Expanded details */}
|
|
327
|
+
{isExpanded && (
|
|
328
|
+
<div style={{ marginTop: "12px" }}>
|
|
329
|
+
{issue.details && (
|
|
330
|
+
<div
|
|
331
|
+
style={{
|
|
332
|
+
padding: "10px",
|
|
333
|
+
background: "#0f172a",
|
|
334
|
+
borderRadius: "4px",
|
|
335
|
+
marginBottom: "10px",
|
|
336
|
+
}}
|
|
337
|
+
>
|
|
338
|
+
<div
|
|
339
|
+
style={{
|
|
340
|
+
fontSize: "12px",
|
|
341
|
+
fontWeight: 600,
|
|
342
|
+
color: "#94a3b8",
|
|
343
|
+
marginBottom: "6px",
|
|
344
|
+
}}
|
|
345
|
+
>
|
|
346
|
+
Details:
|
|
347
|
+
</div>
|
|
348
|
+
<div
|
|
349
|
+
style={{
|
|
350
|
+
fontSize: "13px",
|
|
351
|
+
color: "#cbd5e1",
|
|
352
|
+
fontFamily: "monospace",
|
|
353
|
+
whiteSpace: "pre-wrap",
|
|
354
|
+
}}
|
|
355
|
+
>
|
|
356
|
+
{issue.details}
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
)}
|
|
360
|
+
{issue.suggestion && (
|
|
361
|
+
<div
|
|
362
|
+
style={{
|
|
363
|
+
padding: "10px",
|
|
364
|
+
background: "#064e3b",
|
|
365
|
+
border: "1px solid #10b981",
|
|
366
|
+
borderRadius: "4px",
|
|
367
|
+
}}
|
|
368
|
+
>
|
|
369
|
+
<div
|
|
370
|
+
style={{
|
|
371
|
+
fontSize: "12px",
|
|
372
|
+
fontWeight: 600,
|
|
373
|
+
color: "#6ee7b7",
|
|
374
|
+
marginBottom: "6px",
|
|
375
|
+
}}
|
|
376
|
+
>
|
|
377
|
+
💡 Suggestion:
|
|
378
|
+
</div>
|
|
379
|
+
<div
|
|
380
|
+
style={{
|
|
381
|
+
fontSize: "13px",
|
|
382
|
+
color: "#d1fae5",
|
|
383
|
+
}}
|
|
384
|
+
>
|
|
385
|
+
{issue.suggestion}
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
)}
|
|
389
|
+
</div>
|
|
390
|
+
)}
|
|
391
|
+
</div>
|
|
392
|
+
<span
|
|
393
|
+
style={{
|
|
394
|
+
fontSize: "12px",
|
|
395
|
+
color: "#64748b",
|
|
396
|
+
transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
|
|
397
|
+
transition: "transform 0.2s",
|
|
398
|
+
}}
|
|
399
|
+
>
|
|
400
|
+
â–¼
|
|
401
|
+
</span>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
);
|
|
405
|
+
})}
|
|
406
|
+
</div>
|
|
407
|
+
)}
|
|
408
|
+
</div>
|
|
409
|
+
|
|
410
|
+
{/* Summary footer */}
|
|
411
|
+
{filteredIssues.length > 0 && (
|
|
412
|
+
<div
|
|
413
|
+
style={{
|
|
414
|
+
marginTop: "16px",
|
|
415
|
+
paddingTop: "16px",
|
|
416
|
+
borderTop: "1px solid #334155",
|
|
417
|
+
fontSize: "13px",
|
|
418
|
+
color: "#94a3b8",
|
|
419
|
+
textAlign: "center",
|
|
420
|
+
}}
|
|
421
|
+
>
|
|
422
|
+
Showing {filteredIssues.length} of {issues.length} issue
|
|
423
|
+
{issues.length !== 1 ? "s" : ""}
|
|
424
|
+
</div>
|
|
425
|
+
)}
|
|
426
|
+
</div>
|
|
427
|
+
);
|
|
428
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clypra/ui
|
|
3
|
+
*
|
|
4
|
+
* Shared UI components for all Clypra Studio Labs.
|
|
5
|
+
* These components provide common developer tools: graph inspection,
|
|
6
|
+
* performance monitoring, resource visualization, and parameter editing.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Week 3 Components - Developer Panels
|
|
10
|
+
export { GraphInspector } from "./components/GraphInspector";
|
|
11
|
+
export type { GraphInspectorProps } from "./components/GraphInspector";
|
|
12
|
+
|
|
13
|
+
export { PassInspector } from "./components/PassInspector";
|
|
14
|
+
export type { PassInspectorProps } from "./components/PassInspector";
|
|
15
|
+
|
|
16
|
+
export { ResourceInspector } from "./components/ResourceInspector";
|
|
17
|
+
export type { ResourceInspectorProps } from "./components/ResourceInspector";
|
|
18
|
+
|
|
19
|
+
export { PerformanceMonitor } from "./components/PerformanceMonitor";
|
|
20
|
+
export type { PerformanceMonitorProps, PerformanceMetrics } from "./components/PerformanceMonitor";
|
|
21
|
+
|
|
22
|
+
// Week 4 Components - Preview & Timeline
|
|
23
|
+
export { PreviewCanvas } from "./components/PreviewCanvas";
|
|
24
|
+
export type { PreviewCanvasProps } from "./components/PreviewCanvas";
|
|
25
|
+
|
|
26
|
+
export { Timeline } from "./components/Timeline";
|
|
27
|
+
export type { TimelineProps } from "./components/Timeline";
|
|
28
|
+
|
|
29
|
+
export { PresetManager } from "./components/PresetManager";
|
|
30
|
+
export type { PresetManagerProps, Preset } from "./components/PresetManager";
|
|
31
|
+
|
|
32
|
+
export { ValidationPanel } from "./components/ValidationPanel";
|
|
33
|
+
export type { ValidationPanelProps, ValidationIssue, ValidationSeverity } from "./components/ValidationPanel";
|
|
34
|
+
|
|
35
|
+
export const UI_VERSION = "1.0.0";
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2022", "DOM"],
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"allowJs": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"declarationMap": true,
|
|
15
|
+
"sourceMap": true,
|
|
16
|
+
"outDir": "./dist",
|
|
17
|
+
"rootDir": "./src",
|
|
18
|
+
"jsx": "react-jsx"
|
|
19
|
+
},
|
|
20
|
+
"include": ["src/**/*"],
|
|
21
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
|
|
22
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: {
|
|
5
|
+
index: "src/index.ts",
|
|
6
|
+
},
|
|
7
|
+
format: ["esm"],
|
|
8
|
+
dts: true,
|
|
9
|
+
sourcemap: true,
|
|
10
|
+
clean: true,
|
|
11
|
+
external: ["react", "react-dom"],
|
|
12
|
+
splitting: false,
|
|
13
|
+
treeshake: true,
|
|
14
|
+
});
|