@aiready/components 0.1.22 → 0.1.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/components",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Unified shared components library (UI, charts, hooks, utilities) for AIReady",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -62,8 +62,8 @@
62
62
  "clsx": "^2.1.1",
63
63
  "d3": "^7.9.0",
64
64
  "d3-force": "^3.0.0",
65
- "tailwind-merge": "^2.6.1",
66
- "@aiready/core": "0.9.22"
65
+ "tailwind-merge": "^3.0.0",
66
+ "@aiready/core": "0.9.25"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@testing-library/jest-dom": "^6.6.5",
@@ -74,7 +74,7 @@
74
74
  "tailwindcss": "^4.1.14",
75
75
  "tsup": "^8.3.5",
76
76
  "typescript": "^5.7.2",
77
- "vitest": "^2.1.8"
77
+ "vitest": "^4.0.0"
78
78
  },
79
79
  "scripts": {
80
80
  "dev": "tsup --watch",
@@ -128,8 +128,8 @@ export const ForceDirectedGraph = forwardRef<ForceDirectedGraphHandle, ForceDire
128
128
  const nodes = React.useMemo(() => {
129
129
  if (!initialNodes || !initialNodes.length) return initialNodes;
130
130
 
131
- const cx = width / 2;
132
- const cy = height / 2;
131
+ const centerX = width / 2;
132
+ const centerY = height / 2;
133
133
 
134
134
  // For force layout, use random positions but don't animate
135
135
  if (layout === 'force') {
@@ -145,8 +145,8 @@ export const ForceDirectedGraph = forwardRef<ForceDirectedGraphHandle, ForceDire
145
145
  const radius = Math.min(width, height) * 0.35;
146
146
  return initialNodes.map((n: any, i: number) => ({
147
147
  ...n,
148
- x: cx + Math.cos((2 * Math.PI * i) / initialNodes.length) * radius,
149
- y: cy + Math.sin((2 * Math.PI * i) / initialNodes.length) * radius,
148
+ x: centerX + Math.cos((2 * Math.PI * i) / initialNodes.length) * radius,
149
+ y: centerY + Math.sin((2 * Math.PI * i) / initialNodes.length) * radius,
150
150
  }));
151
151
  }
152
152
 
@@ -188,16 +188,16 @@ export const ForceDirectedGraph = forwardRef<ForceDirectedGraphHandle, ForceDire
188
188
  if (!nodes || nodes.length === 0) return;
189
189
 
190
190
  const applyLayout = () => {
191
- const cx = width / 2;
192
- const cy = height / 2;
191
+ const centerX = width / 2;
192
+ const centerY = height / 2;
193
193
 
194
194
  if (layout === 'circular') {
195
195
  // Place all nodes in a circle
196
196
  const radius = Math.min(width, height) * 0.35;
197
197
  nodes.forEach((node, i) => {
198
198
  const angle = (2 * Math.PI * i) / nodes.length;
199
- node.fx = cx + Math.cos(angle) * radius;
200
- node.fy = cy + Math.sin(angle) * radius;
199
+ node.fx = centerX + Math.cos(angle) * radius;
200
+ node.fy = centerY + Math.sin(angle) * radius;
201
201
  });
202
202
  } else if (layout === 'hierarchical') {
203
203
  // Place packages in rows, files within packages in columns
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
 
3
+ import { getRating as getCoreRating } from '@aiready/core/client';
3
4
  import { cn } from '../utils/cn';
4
5
 
5
6
  export type ScoreRating = 'excellent' | 'good' | 'fair' | 'needs-work' | 'critical';
@@ -21,12 +22,17 @@ const ratingConfig: Record<ScoreRating, { color: string; bgColor: string; label:
21
22
  critical: { color: 'bg-red-500', bgColor: 'bg-red-100', label: 'Critical' },
22
23
  };
23
24
 
25
+ // Convert Title Case rating from core to lowercase for component use
24
26
  function getRating(score: number): ScoreRating {
25
- if (score >= 90) return 'excellent';
26
- if (score >= 75) return 'good';
27
- if (score >= 60) return 'fair';
28
- if (score >= 40) return 'needs-work';
29
- return 'critical';
27
+ const coreRating = getCoreRating(score);
28
+ const ratingMap: Record<string, ScoreRating> = {
29
+ 'Excellent': 'excellent',
30
+ 'Good': 'good',
31
+ 'Fair': 'fair',
32
+ 'Needs Work': 'needs-work',
33
+ 'Critical': 'critical',
34
+ };
35
+ return ratingMap[coreRating] || 'critical';
30
36
  }
31
37
 
32
38
  const sizeConfig = {
@@ -115,4 +121,4 @@ export function ScoreCard({ score, title, breakdown, className }: ScoreCardProps
115
121
  )}
116
122
  </div>
117
123
  );
118
- }
124
+ }
package/src/index.ts CHANGED
@@ -53,6 +53,7 @@ export { ThemeProvider, useTheme, type Theme, type EffectiveTheme } from './them
53
53
  export { cn } from './utils/cn';
54
54
  export * from './utils/colors';
55
55
  export * from './utils/formatters';
56
+ export * from './utils/score';
56
57
 
57
58
  // Hooks
58
59
  export { useDebounce } from './hooks/useDebounce';
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Score utility functions for AI readiness scoring
3
+ * Provides color, background, glow, and label helpers for score display
4
+ */
5
+
6
+ /**
7
+ * Get the Tailwind color class for a score
8
+ */
9
+ export function scoreColor(score: number | null | undefined): string {
10
+ if (score == null) return 'text-slate-400';
11
+ if (score >= 75) return 'text-emerald-400';
12
+ if (score >= 50) return 'text-amber-400';
13
+ return 'text-red-400';
14
+ }
15
+
16
+ /**
17
+ * Get the Tailwind background/border class for a score
18
+ */
19
+ export function scoreBg(score: number | null | undefined): string {
20
+ if (score == null) return 'bg-slate-800/50 border-slate-700';
21
+ if (score >= 75) return 'bg-emerald-900/30 border-emerald-500/30';
22
+ if (score >= 50) return 'bg-amber-900/30 border-amber-500/30';
23
+ return 'bg-red-900/30 border-red-500/30';
24
+ }
25
+
26
+ /**
27
+ * Get the display label for a score
28
+ */
29
+ export function scoreLabel(score: number | null | undefined): string {
30
+ if (score == null) return 'Not analyzed';
31
+ if (score >= 75) return 'AI-Ready';
32
+ if (score >= 50) return 'Needs Improvement';
33
+ return 'Critical Issues';
34
+ }
35
+
36
+ /**
37
+ * Get the Tailwind shadow glow class for a score
38
+ */
39
+ export function scoreGlow(score: number | null | undefined): string {
40
+ if (score == null) return '';
41
+ if (score >= 75) return 'shadow-emerald-500/20';
42
+ if (score >= 50) return 'shadow-amber-500/20';
43
+ return 'shadow-red-500/20';
44
+ }
45
+
46
+ /**
47
+ * Get rating from score (for use with ScoreBar component)
48
+ */
49
+ export function getScoreRating(score: number | null | undefined): 'excellent' | 'good' | 'fair' | 'needs-work' | 'critical' {
50
+ if (score == null) return 'critical';
51
+ if (score >= 90) return 'excellent';
52
+ if (score >= 75) return 'good';
53
+ if (score >= 60) return 'fair';
54
+ if (score >= 40) return 'needs-work';
55
+ return 'critical';
56
+ }