@aiready/components 0.11.11 → 0.11.15

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.11.11",
3
+ "version": "0.11.15",
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,10 @@
62
62
  "clsx": "^2.1.1",
63
63
  "d3": "^7.9.0",
64
64
  "d3-force": "^3.0.0",
65
+ "framer-motion": "^12.35.0",
66
+ "lucide-react": "^0.577.0",
65
67
  "tailwind-merge": "^3.0.0",
66
- "@aiready/core": "0.21.11"
68
+ "@aiready/core": "0.21.14"
67
69
  },
68
70
  "devDependencies": {
69
71
  "@testing-library/jest-dom": "^6.6.5",
@@ -344,10 +344,7 @@ export const ForceDirectedGraph = forwardRef<
344
344
  svg
345
345
  .transition()
346
346
  .duration(300)
347
- .call(
348
- d3.zoom<SVGSVGElement, unknown>().transform as any,
349
- newTransform
350
- );
347
+ .call((d3 as any).zoom().transform as any, newTransform);
351
348
  setTransform(newTransform);
352
349
  }
353
350
  },
@@ -384,10 +381,10 @@ export const ForceDirectedGraph = forwardRef<
384
381
  const svg = d3.select(svgRef.current);
385
382
  const g = d3.select(gRef.current);
386
383
 
387
- const zoom = d3
388
- .zoom<SVGSVGElement, unknown>()
384
+ const zoom = (d3 as any)
385
+ .zoom()
389
386
  .scaleExtent([0.1, 10])
390
- .on('zoom', (event) => {
387
+ .on('zoom', (event: any) => {
391
388
  g.attr('transform', event.transform);
392
389
  transformRef.current = event.transform;
393
390
  setTransform(event.transform);
@@ -406,9 +403,7 @@ export const ForceDirectedGraph = forwardRef<
406
403
  if (!gRef.current) return;
407
404
  try {
408
405
  const g = d3.select(gRef.current);
409
- g.selectAll<SVGGElement, any>('g.node').each(function (
410
- this: SVGGElement
411
- ) {
406
+ g.selectAll('g.node').each(function (this: any) {
412
407
  const datum = d3.select(this).datum() as any;
413
408
  if (!datum) return;
414
409
  d3.select(this).attr(
@@ -417,9 +412,7 @@ export const ForceDirectedGraph = forwardRef<
417
412
  );
418
413
  });
419
414
 
420
- g.selectAll<SVGLineElement, any>('line').each(function (
421
- this: SVGLineElement
422
- ) {
415
+ g.selectAll('line').each(function (this: any) {
423
416
  const l = d3.select(this).datum() as any;
424
417
  if (!l) return;
425
418
  const s: any =
@@ -513,9 +506,9 @@ export const ForceDirectedGraph = forwardRef<
513
506
  useEffect(() => {
514
507
  if (!gRef.current || !enableDrag) return;
515
508
  const g = d3.select(gRef.current);
516
- const dragBehavior = d3
517
- .drag<SVGGElement, unknown>()
518
- .on('start', function (event) {
509
+ const dragBehavior = (d3 as any)
510
+ .drag()
511
+ .on('start', function (this: any, event: any) {
519
512
  try {
520
513
  const target =
521
514
  (event.sourceEvent && (event.sourceEvent.target as Element)) ||
@@ -538,7 +531,7 @@ export const ForceDirectedGraph = forwardRef<
538
531
  void e;
539
532
  }
540
533
  })
541
- .on('drag', function (event) {
534
+ .on('drag', function (this: any, event: any) {
542
535
  if (!dragActiveRef.current || !dragNodeRef.current) return;
543
536
  const svg = svgRef.current;
544
537
  if (!svg) return;
@@ -1,6 +1,8 @@
1
1
  'use client';
2
2
 
3
3
  import React, { useState, useCallback, useMemo } from 'react';
4
+ import { motion, AnimatePresence } from 'framer-motion';
5
+ import { cn } from '../utils/cn';
4
6
 
5
7
  export interface CodeBlockProps {
6
8
  children: React.ReactNode;
@@ -8,17 +10,15 @@ export interface CodeBlockProps {
8
10
  showCopy?: boolean;
9
11
  showHeader?: boolean;
10
12
  className?: string;
13
+ variant?: 'default' | 'glass';
11
14
  }
12
15
 
13
16
  // Dedent helper - removes common leading indentation
14
17
  function dedentCode(code: string): string {
15
- // Normalize tabs to two spaces
16
18
  const normalized = code.replace(/\t/g, ' ').replace(/[ \t]+$/gm, '');
17
-
18
19
  const lines = normalized.split('\n');
19
20
  if (lines.length <= 1) return normalized.trim();
20
21
 
21
- // Remove leading/trailing empty lines
22
22
  let start = 0;
23
23
  while (start < lines.length && lines[start].trim() === '') start++;
24
24
  let end = lines.length - 1;
@@ -27,27 +27,21 @@ function dedentCode(code: string): string {
27
27
  if (start > end) return '';
28
28
  const relevantLines = lines.slice(start, end + 1);
29
29
 
30
- // Find minimum indent across non-empty lines
31
30
  const nonEmpty = relevantLines.filter((l) => l.trim() !== '');
32
31
  const minIndent = nonEmpty.reduce((min, line) => {
33
32
  const m = line.match(/^\s*/)?.[0].length ?? 0;
34
33
  return Math.min(min, m);
35
34
  }, Infinity);
36
35
 
37
- // Remove common indentation
38
- const dedented =
39
- minIndent === Infinity || minIndent === 0
40
- ? relevantLines.join('\n')
41
- : relevantLines
42
- .map((l) =>
43
- l.startsWith(' '.repeat(minIndent)) ? l.slice(minIndent) : l
44
- )
45
- .join('\n');
46
-
47
- return dedented;
36
+ return minIndent === Infinity || minIndent === 0
37
+ ? relevantLines.join('\n')
38
+ : relevantLines
39
+ .map((l) =>
40
+ l.startsWith(' '.repeat(minIndent)) ? l.slice(minIndent) : l
41
+ )
42
+ .join('\n');
48
43
  }
49
44
 
50
- // Simple Copy Button
51
45
  function CopyButton({ code }: { code: string }) {
52
46
  const [copied, setCopied] = useState(false);
53
47
 
@@ -57,7 +51,6 @@ function CopyButton({ code }: { code: string }) {
57
51
  setCopied(true);
58
52
  setTimeout(() => setCopied(false), 2000);
59
53
  } catch {
60
- // Fallback for older browsers
61
54
  const textarea = document.createElement('textarea');
62
55
  textarea.value = code;
63
56
  textarea.style.position = 'fixed';
@@ -74,38 +67,30 @@ function CopyButton({ code }: { code: string }) {
74
67
  return (
75
68
  <button
76
69
  onClick={handleCopy}
77
- className="rounded-md p-1.5 text-slate-400 hover:text-slate-200 hover:bg-slate-700/50 transition-colors"
78
- title={copied ? 'Copied!' : 'Copy code'}
70
+ className="flex items-center gap-1.5 rounded-md px-2 py-1 text-[10px] font-bold uppercase tracking-wider text-slate-400 hover:bg-slate-700/50 hover:text-cyan-400 transition-all"
79
71
  >
80
- {copied ? (
81
- <svg
82
- className="h-4 w-4"
83
- fill="none"
84
- viewBox="0 0 24 24"
85
- strokeWidth="1.5"
86
- stroke="currentColor"
87
- >
88
- <path
89
- strokeLinecap="round"
90
- strokeLinejoin="round"
91
- d="M4.5 12.75l6 6 9-13.5"
92
- />
93
- </svg>
94
- ) : (
95
- <svg
96
- className="h-4 w-4"
97
- fill="none"
98
- viewBox="0 0 24 24"
99
- strokeWidth="1.5"
100
- stroke="currentColor"
101
- >
102
- <path
103
- strokeLinecap="round"
104
- strokeLinejoin="round"
105
- d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184"
106
- />
107
- </svg>
108
- )}
72
+ <AnimatePresence mode="wait">
73
+ {copied ? (
74
+ <motion.span
75
+ key="copied"
76
+ initial={{ opacity: 0, y: 5 }}
77
+ animate={{ opacity: 1, y: 0 }}
78
+ exit={{ opacity: 0, y: -5 }}
79
+ className="text-cyan-400"
80
+ >
81
+ Copied!
82
+ </motion.span>
83
+ ) : (
84
+ <motion.span
85
+ key="copy"
86
+ initial={{ opacity: 0, y: 5 }}
87
+ animate={{ opacity: 1, y: 0 }}
88
+ exit={{ opacity: 0, y: -5 }}
89
+ >
90
+ Copy
91
+ </motion.span>
92
+ )}
93
+ </AnimatePresence>
109
94
  </button>
110
95
  );
111
96
  }
@@ -116,13 +101,10 @@ export function CodeBlock({
116
101
  showCopy = true,
117
102
  showHeader = true,
118
103
  className = '',
104
+ variant = 'glass',
119
105
  }: CodeBlockProps) {
120
- // Get code string from children
121
106
  const codeString = useMemo(() => {
122
- if (typeof children === 'string') {
123
- return dedentCode(children);
124
- }
125
- // Handle template literal children
107
+ if (typeof children === 'string') return dedentCode(children);
126
108
  try {
127
109
  const raw = React.Children.toArray(children)
128
110
  .map((c) =>
@@ -137,18 +119,30 @@ export function CodeBlock({
137
119
 
138
120
  return (
139
121
  <div
140
- className={`group relative my-4 overflow-hidden rounded-xl border border-slate-700 bg-slate-900 shadow-lg ${className}`}
122
+ className={cn(
123
+ 'group relative my-6 overflow-hidden rounded-2xl border transition-all',
124
+ variant === 'glass'
125
+ ? 'border-indigo-500/20 bg-slate-950/40 backdrop-blur-md shadow-2xl'
126
+ : 'border-slate-700 bg-slate-900 shadow-lg',
127
+ className
128
+ )}
141
129
  >
142
- {/* Header bar */}
143
130
  {showHeader && (
144
- <div className="flex items-center justify-between border-b border-slate-700 bg-slate-800/50 px-4 py-2">
131
+ <div
132
+ className={cn(
133
+ 'flex items-center justify-between px-4 py-2 border-b',
134
+ variant === 'glass'
135
+ ? 'border-indigo-500/10 bg-slate-900/20'
136
+ : 'border-slate-800 bg-slate-800/50'
137
+ )}
138
+ >
145
139
  <div className="flex items-center gap-2">
146
140
  <div className="flex gap-1.5">
147
- <div className="h-3 w-3 rounded-full bg-red-500/50" />
148
- <div className="h-3 w-3 rounded-full bg-amber-500/50" />
149
- <div className="h-3 w-3 rounded-full bg-emerald-500/50" />
141
+ <div className="h-2.5 w-2.5 rounded-full bg-red-500/20 border border-red-500/40" />
142
+ <div className="h-2.5 w-2.5 rounded-full bg-amber-500/20 border border-amber-500/40" />
143
+ <div className="h-2.5 w-2.5 rounded-full bg-emerald-500/20 border border-emerald-500/40" />
150
144
  </div>
151
- <span className="ml-2 text-xs font-semibold uppercase tracking-wider text-slate-500 font-mono">
145
+ <span className="ml-2 text-[10px] font-bold uppercase tracking-widest text-slate-500 font-mono">
152
146
  {language}
153
147
  </span>
154
148
  </div>
@@ -156,8 +150,7 @@ export function CodeBlock({
156
150
  </div>
157
151
  )}
158
152
 
159
- {/* Code body */}
160
- <pre className="overflow-x-auto p-4 text-sm leading-relaxed">
153
+ <pre className="overflow-x-auto p-4 text-sm leading-relaxed scrollbar-thin scrollbar-thumb-slate-700">
161
154
  <code className="font-mono block whitespace-pre text-slate-300">
162
155
  {codeString}
163
156
  </code>
@@ -166,7 +159,6 @@ export function CodeBlock({
166
159
  );
167
160
  }
168
161
 
169
- // Inline code component
170
162
  export function InlineCode({
171
163
  children,
172
164
  className = '',
@@ -176,7 +168,10 @@ export function InlineCode({
176
168
  }) {
177
169
  return (
178
170
  <code
179
- className={`rounded-md bg-slate-100 px-1.5 py-0.5 text-sm font-mono text-slate-800 ${className}`}
171
+ className={cn(
172
+ 'rounded-md bg-slate-800/50 border border-slate-700/50 px-1.5 py-0.5 text-xs font-mono text-cyan-400',
173
+ className
174
+ )}
180
175
  >
181
176
  {children}
182
177
  </code>
@@ -3,7 +3,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
3
3
  import { cn } from '../utils/cn';
4
4
 
5
5
  const buttonVariants = cva(
6
- 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
6
+ 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
7
7
  {
8
8
  variants: {
9
9
  variant: {
@@ -16,12 +16,20 @@ const buttonVariants = cva(
16
16
  'bg-secondary text-secondary-foreground hover:bg-secondary/80',
17
17
  ghost: 'hover:bg-accent hover:text-accent-foreground',
18
18
  link: 'text-primary underline-offset-4 hover:underline',
19
+ // Platform specific high-polish variants
20
+ glow: 'bg-gradient-to-r from-cyan-600 to-blue-600 text-white shadow-lg shadow-cyan-500/20 hover:shadow-cyan-500/40 hover:scale-[1.02] active:scale-[0.98]',
21
+ glass:
22
+ 'bg-slate-800/50 backdrop-blur-sm border border-slate-700 text-slate-200 hover:bg-slate-700/50 hover:text-white',
23
+ accent:
24
+ 'bg-cyan-500/10 text-cyan-400 border border-cyan-500/20 hover:bg-cyan-500/20',
19
25
  },
20
26
  size: {
21
27
  default: 'h-10 px-4 py-2',
22
28
  sm: 'h-9 rounded-md px-3',
23
29
  lg: 'h-11 rounded-md px-8',
24
30
  icon: 'h-10 w-10',
31
+ // Extra sizes for dashboard use
32
+ xs: 'h-7 rounded-md px-2 text-[10px] font-bold uppercase tracking-wider',
25
33
  },
26
34
  },
27
35
  defaultVariants: {
@@ -75,6 +75,45 @@ const CardFooter = React.forwardRef<
75
75
  ));
76
76
  CardFooter.displayName = 'CardFooter';
77
77
 
78
+ // GlassCard - Highly polished platform style
79
+ const GlassCard = React.forwardRef<
80
+ HTMLDivElement,
81
+ React.HTMLAttributes<HTMLDivElement>
82
+ >(({ className, ...props }, ref) => (
83
+ <div
84
+ ref={ref}
85
+ className={cn(
86
+ 'rounded-2xl border border-indigo-500/20 bg-slate-900/40 backdrop-blur-md shadow-xl transition-all hover:border-indigo-500/30',
87
+ className
88
+ )}
89
+ {...props}
90
+ />
91
+ ));
92
+ GlassCard.displayName = 'GlassCard';
93
+
94
+ const GlassCardHeader = React.forwardRef<
95
+ HTMLDivElement,
96
+ React.HTMLAttributes<HTMLDivElement>
97
+ >(({ className, ...props }, ref) => (
98
+ <div
99
+ ref={ref}
100
+ className={cn(
101
+ 'flex flex-col space-y-1.5 p-6 border-b border-indigo-500/10',
102
+ className
103
+ )}
104
+ {...props}
105
+ />
106
+ ));
107
+ GlassCardHeader.displayName = 'GlassCardHeader';
108
+
109
+ const GlassCardContent = React.forwardRef<
110
+ HTMLDivElement,
111
+ React.HTMLAttributes<HTMLDivElement>
112
+ >(({ className, ...props }, ref) => (
113
+ <div ref={ref} className={cn('p-6', className)} {...props} />
114
+ ));
115
+ GlassCardContent.displayName = 'GlassCardContent';
116
+
78
117
  export {
79
118
  Card,
80
119
  CardHeader,
@@ -82,4 +121,7 @@ export {
82
121
  CardTitle,
83
122
  CardDescription,
84
123
  CardContent,
124
+ GlassCard,
125
+ GlassCardHeader,
126
+ GlassCardContent,
85
127
  };