@stackwright-pro/display-components 0.1.0 → 0.1.2-alpha.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/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
2
3
 
3
4
  type TrendDirection = 'up' | 'down' | 'stable';
4
5
  type StatusVariant = 'operational' | 'degraded' | 'outage' | 'maintenance';
@@ -87,10 +88,12 @@ declare const Sparkline: ({ data, width, height, color, fill, }: SparklineProps)
87
88
 
88
89
  declare const ActivityFeed: ({ items, maxItems }: ActivityFeedProps) => react_jsx_runtime.JSX.Element;
89
90
 
90
- declare const DashboardGrid: ({ columns, cards, gap, }: DashboardGridProps) => react_jsx_runtime.JSX.Element;
91
+ declare const DashboardGrid: ({ columns, cards, gap }: DashboardGridProps) => react_jsx_runtime.JSX.Element;
91
92
 
92
93
  declare function DataTable<T extends object>({ data, columns, loading, emptyMessage, onRowClick, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
93
94
 
94
95
  declare const JsonViewer: ({ data, collapsible, maxHeight }: JsonViewerProps) => react_jsx_runtime.JSX.Element;
95
96
 
96
- export { ActivityFeed, type ActivityFeedProps, type ActivityItem, type ColumnDef, DashboardGrid, type DashboardGridProps, DataTable, type DataTableProps, JsonViewer, type JsonViewerProps, MetricCard, type MetricCardProps, STATUS_COLORS, Sparkline, type SparklineProps, StatBar, type StatBarProps, StatusBadge, type StatusBadgeProps, type StatusVariant, THEME_COLORS, type TrendDirection };
97
+ declare function registerDisplayComponents(): void;
98
+
99
+ export { ActivityFeed, type ActivityFeedProps, type ActivityItem, type ColumnDef, DashboardGrid, type DashboardGridProps, DataTable, type DataTableProps, JsonViewer, type JsonViewerProps, MetricCard, type MetricCardProps, STATUS_COLORS, Sparkline, type SparklineProps, StatBar, type StatBarProps, StatusBadge, type StatusBadgeProps, type StatusVariant, THEME_COLORS, type TrendDirection, registerDisplayComponents };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
2
3
 
3
4
  type TrendDirection = 'up' | 'down' | 'stable';
4
5
  type StatusVariant = 'operational' | 'degraded' | 'outage' | 'maintenance';
@@ -87,10 +88,12 @@ declare const Sparkline: ({ data, width, height, color, fill, }: SparklineProps)
87
88
 
88
89
  declare const ActivityFeed: ({ items, maxItems }: ActivityFeedProps) => react_jsx_runtime.JSX.Element;
89
90
 
90
- declare const DashboardGrid: ({ columns, cards, gap, }: DashboardGridProps) => react_jsx_runtime.JSX.Element;
91
+ declare const DashboardGrid: ({ columns, cards, gap }: DashboardGridProps) => react_jsx_runtime.JSX.Element;
91
92
 
92
93
  declare function DataTable<T extends object>({ data, columns, loading, emptyMessage, onRowClick, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
93
94
 
94
95
  declare const JsonViewer: ({ data, collapsible, maxHeight }: JsonViewerProps) => react_jsx_runtime.JSX.Element;
95
96
 
96
- export { ActivityFeed, type ActivityFeedProps, type ActivityItem, type ColumnDef, DashboardGrid, type DashboardGridProps, DataTable, type DataTableProps, JsonViewer, type JsonViewerProps, MetricCard, type MetricCardProps, STATUS_COLORS, Sparkline, type SparklineProps, StatBar, type StatBarProps, StatusBadge, type StatusBadgeProps, type StatusVariant, THEME_COLORS, type TrendDirection };
97
+ declare function registerDisplayComponents(): void;
98
+
99
+ export { ActivityFeed, type ActivityFeedProps, type ActivityItem, type ColumnDef, DashboardGrid, type DashboardGridProps, DataTable, type DataTableProps, JsonViewer, type JsonViewerProps, MetricCard, type MetricCardProps, STATUS_COLORS, Sparkline, type SparklineProps, StatBar, type StatBarProps, StatusBadge, type StatusBadgeProps, type StatusVariant, THEME_COLORS, type TrendDirection, registerDisplayComponents };
package/dist/index.js CHANGED
@@ -457,10 +457,7 @@ var formatTimestamp = (timestamp) => {
457
457
  if (diffDays < 7) return `${diffDays}d ago`;
458
458
  return date.toLocaleDateString();
459
459
  };
460
- var ActivityFeedItem = ({
461
- item,
462
- index
463
- }) => {
460
+ var ActivityFeedItem = ({ item, index }) => {
464
461
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
465
462
  _react.motion.div,
466
463
  {
@@ -549,11 +546,7 @@ var ActivityFeed = ({ items, maxItems }) => {
549
546
  // src/components/DashboardGrid.tsx
550
547
 
551
548
 
552
- var DashboardGrid = ({
553
- columns = 3,
554
- cards,
555
- gap = 24
556
- }) => {
549
+ var DashboardGrid = ({ columns = 3, cards, gap = 24 }) => {
557
550
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
558
551
  "div",
559
552
  {
@@ -653,7 +646,13 @@ function DataTable({
653
646
  {
654
647
  animate: { rotate: 360 },
655
648
  transition: { duration: 1, repeat: Infinity, ease: "linear" },
656
- style: { width: "24px", height: "24px", border: "3px solid #E5E7EB", borderTopColor: THEME_COLORS.primary, borderRadius: "50%" }
649
+ style: {
650
+ width: "24px",
651
+ height: "24px",
652
+ border: "3px solid #E5E7EB",
653
+ borderTopColor: THEME_COLORS.primary,
654
+ borderRadius: "50%"
655
+ }
657
656
  }
658
657
  )
659
658
  }
@@ -759,7 +758,7 @@ var JsonNode = ({
759
758
  }) => {
760
759
  const [expanded, setExpanded] = _react3.useState.call(void 0, depth < 2);
761
760
  const indent = depth * 16;
762
- const renderValue = (value, key) => {
761
+ const renderValue = (value, _key) => {
763
762
  if (value === null) {
764
763
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { color: syntaxColors.null }, children: "null" });
765
764
  }
@@ -810,7 +809,8 @@ var JsonNode = ({
810
809
  k,
811
810
  '"'
812
811
  ] }),
813
- ": ",
812
+ ":",
813
+ " ",
814
814
  renderValue(v, k),
815
815
  i < entries.length - 1 && ","
816
816
  ] }, k))
@@ -822,8 +822,6 @@ var JsonNode = ({
822
822
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: String(value) });
823
823
  };
824
824
  if (collapsible && depth > 0 && typeof data === "object" && data !== null) {
825
- const entries = Object.entries(data);
826
- const isExpandable = entries.length > 0 || Array.isArray(data);
827
825
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { marginLeft: indent }, children: [
828
826
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
829
827
  _react.motion.button,
@@ -843,7 +841,16 @@ var JsonNode = ({
843
841
  gap: "4px"
844
842
  },
845
843
  children: [
846
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { transition: "transform 0.2s", transform: expanded ? "rotate(90deg)" : "rotate(0deg)" }, children: "\u25B6" }),
844
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
845
+ "span",
846
+ {
847
+ style: {
848
+ transition: "transform 0.2s",
849
+ transform: expanded ? "rotate(90deg)" : "rotate(0deg)"
850
+ },
851
+ children: "\u25B6"
852
+ }
853
+ ),
847
854
  expanded ? "collapse" : "expand"
848
855
  ]
849
856
  }
@@ -854,7 +861,10 @@ var JsonNode = ({
854
861
  initial: { height: 0, opacity: 0 },
855
862
  animate: { height: "auto", opacity: 1 },
856
863
  exit: { height: 0, opacity: 0 },
857
- style: { overflow: maxHeight ? expanded ? "auto" : "hidden" : void 0, maxHeight },
864
+ style: {
865
+ overflow: maxHeight ? expanded ? "auto" : "hidden" : void 0,
866
+ maxHeight
867
+ },
858
868
  children: renderValue(data)
859
869
  }
860
870
  ) })
@@ -916,6 +926,20 @@ var JsonViewer = ({ data, collapsible = true, maxHeight }) => {
916
926
  );
917
927
  };
918
928
 
929
+ // src/registration.ts
930
+ var _core = require('@stackwright/core');
931
+ function registerDisplayComponents() {
932
+ _core.registerComponent.call(void 0, "metric_card", MetricCard);
933
+ _core.registerComponent.call(void 0, "status_badge", StatusBadge);
934
+ _core.registerComponent.call(void 0, "stat_bar", StatBar);
935
+ _core.registerComponent.call(void 0, "sparkline", Sparkline);
936
+ _core.registerComponent.call(void 0, "activity_feed", ActivityFeed);
937
+ _core.registerComponent.call(void 0, "dashboard_grid", DashboardGrid);
938
+ _core.registerComponent.call(void 0, "data_table", DataTable);
939
+ _core.registerComponent.call(void 0, "json_viewer", JsonViewer);
940
+ }
941
+
942
+
919
943
 
920
944
 
921
945
 
@@ -926,5 +950,5 @@ var JsonViewer = ({ data, collapsible = true, maxHeight }) => {
926
950
 
927
951
 
928
952
 
929
- exports.ActivityFeed = ActivityFeed; exports.DashboardGrid = DashboardGrid; exports.DataTable = DataTable; exports.JsonViewer = JsonViewer; exports.MetricCard = MetricCard; exports.STATUS_COLORS = STATUS_COLORS; exports.Sparkline = Sparkline; exports.StatBar = StatBar; exports.StatusBadge = StatusBadge; exports.THEME_COLORS = THEME_COLORS;
953
+ exports.ActivityFeed = ActivityFeed; exports.DashboardGrid = DashboardGrid; exports.DataTable = DataTable; exports.JsonViewer = JsonViewer; exports.MetricCard = MetricCard; exports.STATUS_COLORS = STATUS_COLORS; exports.Sparkline = Sparkline; exports.StatBar = StatBar; exports.StatusBadge = StatusBadge; exports.THEME_COLORS = THEME_COLORS; exports.registerDisplayComponents = registerDisplayComponents;
930
954
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/charles/git/peraspera/stackwright-pro/packages/display-components/dist/index.js","../src/components/MetricCard.tsx","../src/types/index.ts","../src/components/StatusBadge.tsx","../src/components/StatBar.tsx","../src/components/Sparkline.tsx","../src/components/ActivityFeed.tsx","../src/components/DashboardGrid.tsx","../src/components/DataTable.tsx","../src/components/JsonViewer.tsx"],"names":["jsxs","jsx","useState"],"mappings":"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","file":"/home/charles/git/peraspera/stackwright-pro/packages/display-components/dist/index.js","sourcesContent":[null,"import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { MetricCardProps, TrendDirection } from '../types';\n\n// Trend arrow icons\nconst TrendArrow = ({ direction }: { direction: TrendDirection }) => {\n const color =\n direction === 'up'\n ? THEME_COLORS.success\n : direction === 'down'\n ? THEME_COLORS.error\n : THEME_COLORS.textSecondary;\n\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transform: direction === 'down' ? 'rotate(180deg)' : undefined,\n }}\n >\n <path d=\"M12 19V5M5 12l7-7 7 7\" />\n </svg>\n );\n};\n\n// Animated number counter\nconst AnimatedNumber = ({ value }: { value: number }) => {\n return (\n <motion.span\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, ease: 'easeOut' }}\n >\n {value.toLocaleString()}\n </motion.span>\n );\n};\n\nexport const MetricCard = ({\n label,\n value,\n trend,\n trendValue,\n color = THEME_COLORS.primary,\n icon,\n}: MetricCardProps) => {\n return (\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n whileHover={{ scale: 1.02, boxShadow: '0 4px 20px rgba(0,0,0,0.1)' }}\n transition={{ duration: 0.3 }}\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '24px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n position: 'relative',\n overflow: 'hidden',\n }}\n >\n {/* Accent bar */}\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '4px',\n backgroundColor: color,\n }}\n />\n\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>\n <div style={{ flex: 1 }}>\n {/* Label */}\n <p\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n margin: '0 0 8px 0',\n fontWeight: 500,\n }}\n >\n {label}\n </p>\n\n {/* Value */}\n <p\n style={{\n fontSize: '36px',\n fontWeight: 700,\n color: THEME_COLORS.text,\n margin: 0,\n lineHeight: 1,\n }}\n >\n <AnimatedNumber value={value} />\n </p>\n\n {/* Trend */}\n {trend && trendValue && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n marginTop: '12px',\n }}\n >\n <TrendArrow direction={trend} />\n <span\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {trendValue}\n </span>\n </div>\n )}\n </div>\n\n {/* Icon */}\n {icon && (\n <div\n style={{\n width: '48px',\n height: '48px',\n borderRadius: '12px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: color,\n }}\n >\n {icon}\n </div>\n )}\n </div>\n </motion.div>\n );\n};\n\nexport default MetricCard;\n","// Trend direction for metrics\nexport type TrendDirection = 'up' | 'down' | 'stable';\n\n// Status badge variants\nexport type StatusVariant = 'operational' | 'degraded' | 'outage' | 'maintenance';\n\n// Metric card props\nexport interface MetricCardProps {\n label: string;\n value: number;\n trend?: TrendDirection;\n trendValue?: string;\n color?: string;\n icon?: React.ReactNode;\n}\n\n// Status badge props\nexport interface StatusBadgeProps {\n status: StatusVariant;\n label: string;\n pulse?: boolean;\n}\n\n// Stat bar props\nexport interface StatBarProps {\n current: number;\n max: number;\n label?: string;\n color?: string;\n showPercentage?: boolean;\n}\n\n// Sparkline props\nexport interface SparklineProps {\n data: number[];\n width?: number;\n height?: number;\n color?: string;\n fill?: boolean;\n}\n\n// Activity feed item\nexport interface ActivityItem {\n id: string;\n type: 'success' | 'warning' | 'error' | 'info';\n title: string;\n description?: string;\n timestamp: Date | string;\n}\n\n// Activity feed props\nexport interface ActivityFeedProps {\n items: ActivityItem[];\n maxItems?: number;\n}\n\n// Dashboard grid props\nexport interface DashboardGridProps {\n columns?: 1 | 2 | 3 | 4;\n cards: React.ReactNode[];\n gap?: number;\n}\n\n// Column definition for data table\nexport interface ColumnDef<T> {\n field: keyof T;\n header: string;\n type?: 'text' | 'badge' | 'date' | 'number';\n sortable?: boolean;\n filterable?: boolean;\n}\n\n// Data table props\nexport interface DataTableProps<T> {\n data: T[];\n columns: ColumnDef<T>[];\n loading?: boolean;\n emptyMessage?: string;\n onRowClick?: (row: T) => void;\n}\n\n// JSON viewer props\nexport interface JsonViewerProps {\n data: unknown;\n collapsible?: boolean;\n maxHeight?: string;\n}\n\n// Theme colors for Stackwright Pro\nexport const THEME_COLORS = {\n primary: '#0066CC',\n success: '#10B981',\n warning: '#F59E0B',\n error: '#EF4444',\n info: '#3B82F6',\n background: '#FFFFFF',\n surface: '#F3F4F6',\n text: '#111827',\n textSecondary: '#6B7280',\n} as const;\n\n// Status colors\nexport const STATUS_COLORS: Record<StatusVariant, string> = {\n operational: '#10B981',\n degraded: '#F59E0B',\n outage: '#EF4444',\n maintenance: '#6B7280',\n};\n","import { motion } from 'motion/react';\nimport { STATUS_COLORS } from '../types';\nimport type { StatusBadgeProps } from '../types';\n\nexport const StatusBadge = ({ status, label, pulse = false }: StatusBadgeProps) => {\n const color = STATUS_COLORS[status];\n\n return (\n <div\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 12px',\n borderRadius: '9999px',\n backgroundColor: `${color}15`,\n border: `1px solid ${color}30`,\n }}\n >\n {/* Pulsing dot */}\n {pulse && (\n <motion.div\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.6, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: 'easeInOut',\n }}\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n boxShadow: `0 0 8px ${color}`,\n }}\n />\n )}\n\n {/* Static dot */}\n {!pulse && (\n <div\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n }}\n />\n )}\n\n {/* Label */}\n <span\n style={{\n fontSize: '13px',\n fontWeight: 600,\n color: color,\n textTransform: 'capitalize',\n }}\n >\n {label}\n </span>\n </div>\n );\n};\n\nexport default StatusBadge;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { StatBarProps } from '../types';\n\nexport const StatBar = ({\n current,\n max,\n label,\n color = THEME_COLORS.primary,\n showPercentage = true,\n}: StatBarProps) => {\n const percentage = Math.min(100, Math.round((current / max) * 100));\n\n return (\n <div style={{ width: '100%' }}>\n {/* Label and percentage */}\n {(label || showPercentage) && (\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '8px',\n }}\n >\n {label && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.text,\n fontWeight: 500,\n }}\n >\n {label}\n </span>\n )}\n {showPercentage && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n fontWeight: 600,\n }}\n >\n {percentage}%\n </span>\n )}\n </div>\n )}\n\n {/* Progress bar */}\n <div\n style={{\n width: '100%',\n height: '8px',\n backgroundColor: `${color}20`,\n borderRadius: '4px',\n overflow: 'hidden',\n }}\n >\n <motion.div\n initial={{ width: 0 }}\n animate={{ width: `${percentage}%` }}\n transition={{ duration: 0.8, ease: 'easeOut' }}\n style={{\n height: '100%',\n backgroundColor: color,\n borderRadius: '4px',\n }}\n />\n </div>\n\n {/* Current/Max values */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginTop: '4px',\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <span>{current.toLocaleString()}</span>\n <span>{max.toLocaleString()}</span>\n </div>\n </div>\n );\n};\n\nexport default StatBar;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { SparklineProps } from '../types';\n\nexport const Sparkline = ({\n data,\n width = 100,\n height = 30,\n color = THEME_COLORS.primary,\n fill = false,\n}: SparklineProps) => {\n if (!data || data.length < 2) {\n return null;\n }\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const range = max - min || 1;\n\n // Generate points\n const points = data.map((value, index) => {\n const x = (index / (data.length - 1)) * width;\n const y = height - ((value - min) / range) * height;\n return `${x},${y}`;\n });\n\n const pathD = `M ${points.join(' L ')}`;\n const fillPath = `${pathD} L ${width},${height} L 0,${height} Z`;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n style={{ overflow: 'visible' }}\n >\n <defs>\n <linearGradient id={`gradient-${color.replace('#', '')}`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.3} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n </defs>\n\n {/* Fill area */}\n {fill && (\n <motion.path\n d={fillPath}\n fill={`url(#gradient-${color.replace('#', '')})`}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.5 }}\n />\n )}\n\n {/* Line */}\n <motion.path\n d={pathD}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={{ duration: 1, ease: 'easeOut' }}\n />\n\n {/* End dot */}\n <motion.circle\n cx={width}\n cy={height - ((data[data.length - 1] - min) / range) * height}\n r=\"3\"\n fill={color}\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={{ delay: 0.9, duration: 0.2 }}\n />\n </svg>\n );\n};\n\nexport default Sparkline;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { ActivityFeedProps, ActivityItem } from '../types';\n\n// Icon components for each activity type\nconst ActivityIcon = ({ type }: { type: ActivityItem['type'] }) => {\n const color =\n type === 'success'\n ? THEME_COLORS.success\n : type === 'warning'\n ? THEME_COLORS.warning\n : type === 'error'\n ? THEME_COLORS.error\n : THEME_COLORS.info;\n\n const iconPaths: Record<ActivityItem['type'], string> = {\n success: 'M20 6L9 17l-5-5',\n warning: 'M12 9v4M12 17h.01',\n error: 'M18 6L6 18M6 6l12 12',\n info: 'M12 16v-4M12 8h.01',\n };\n\n return (\n <div\n style={{\n width: '32px',\n height: '32px',\n borderRadius: '8px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d={iconPaths[type]} />\n </svg>\n </div>\n );\n};\n\n// Format timestamp to relative time\nconst formatTimestamp = (timestamp: Date | string): string => {\n const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n};\n\n// Single activity item\nconst ActivityFeedItem = ({\n item,\n index,\n}: {\n item: ActivityItem;\n index: number;\n}) => {\n return (\n <motion.div\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ delay: index * 0.1, duration: 0.3 }}\n style={{\n display: 'flex',\n gap: '12px',\n padding: '12px 0',\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n <ActivityIcon type={item.type} />\n <div style={{ flex: 1 }}>\n <p\n style={{\n fontSize: '14px',\n fontWeight: 500,\n color: THEME_COLORS.text,\n margin: 0,\n }}\n >\n {item.title}\n </p>\n {item.description && (\n <p\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n margin: '4px 0 0 0',\n }}\n >\n {item.description}\n </p>\n )}\n </div>\n <span\n style={{\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n whiteSpace: 'nowrap',\n }}\n >\n {formatTimestamp(item.timestamp)}\n </span>\n </motion.div>\n );\n};\n\nexport const ActivityFeed = ({ items, maxItems }: ActivityFeedProps) => {\n const displayItems = maxItems ? items.slice(0, maxItems) : items;\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '20px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <h3\n style={{\n fontSize: '16px',\n fontWeight: 600,\n color: THEME_COLORS.text,\n margin: '0 0 16px 0',\n }}\n >\n Recent Activity\n </h3>\n <div>\n {displayItems.map((item, index) => (\n <ActivityFeedItem key={item.id} item={item} index={index} />\n ))}\n </div>\n </div>\n );\n};\n\nexport default ActivityFeed;\n","import { motion } from 'motion/react';\nimport type { DashboardGridProps } from '../types';\n\nexport const DashboardGrid = ({\n columns = 3,\n cards,\n gap = 24,\n}: DashboardGridProps) => {\n return (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${columns}, 1fr)`,\n gap: `${gap}px`,\n width: '100%',\n }}\n >\n {cards.map((card, index) => (\n <motion.div\n key={index}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: index * 0.1, duration: 0.4 }}\n >\n {card}\n </motion.div>\n ))}\n </div>\n );\n};\n\nexport default DashboardGrid;\n","import {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type ColumnDef as TanstackColumnDef,\n} from '@tanstack/react-table';\nimport { motion } from 'motion/react';\nimport { useState } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { DataTableProps, ColumnDef } from '../types';\n\nexport function DataTable<T extends object>({\n data,\n columns,\n loading = false,\n emptyMessage = 'No data available',\n onRowClick,\n}: DataTableProps<T>) {\n const [sorting, setSorting] = useState<SortingState>([]);\n\n // Convert ColumnDef to tanstack columns using accessors\n const tableColumns: TanstackColumnDef<T>[] = columns.map((col) => ({\n id: String(col.field),\n accessorKey: String(col.field) as keyof T,\n header: col.header,\n cell: (info) => {\n const value = info.getValue();\n \n // Format based on type\n if (col.type === 'date' && value) {\n return new Date(value as string | Date).toLocaleDateString();\n }\n if (col.type === 'number') {\n return (value as number).toLocaleString();\n }\n if (col.type === 'badge') {\n const badgeColor =\n value === 'available' || value === 'operational'\n ? THEME_COLORS.success\n : value === 'pending'\n ? THEME_COLORS.warning\n : THEME_COLORS.error;\n return (\n <span\n style={{\n padding: '4px 8px',\n borderRadius: '4px',\n backgroundColor: `${badgeColor}15`,\n color: badgeColor,\n fontSize: '12px',\n fontWeight: 500,\n }}\n >\n {String(value)}\n </span>\n );\n }\n return String(value ?? '');\n },\n sortingFn: col.sortable ? 'alphanumeric' : undefined,\n enableSorting: col.sortable ?? false,\n }));\n\n const table = useReactTable({\n data,\n columns: tableColumns,\n state: { sorting },\n onSortingChange: setSorting,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n });\n\n if (loading) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <motion.div\n animate={{ rotate: 360 }}\n transition={{ duration: 1, repeat: Infinity, ease: 'linear' }}\n style={{ width: '24px', height: '24px', border: '3px solid #E5E7EB', borderTopColor: THEME_COLORS.primary, borderRadius: '50%' }}\n />\n </div>\n );\n }\n\n if (data.length === 0) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n overflow: 'hidden',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <div style={{ overflowX: 'auto' }}>\n <table style={{ width: '100%', borderCollapse: 'collapse' }}>\n <thead>\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n onClick={header.column.getToggleSortingHandler()}\n style={{\n padding: '12px 16px',\n textAlign: 'left',\n fontSize: '12px',\n fontWeight: 600,\n color: THEME_COLORS.textSecondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n backgroundColor: THEME_COLORS.surface,\n borderBottom: '1px solid #E5E7EB',\n cursor: columns.find(c => c.field === header.column.id)?.sortable ? 'pointer' : 'default',\n userSelect: 'none',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n {flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getIsSorted() && (\n <span>{header.column.getIsSorted() === 'asc' ? '↑' : '↓'}</span>\n )}\n </div>\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.map((row) => (\n <motion.tr\n key={row.id}\n whileHover={{ backgroundColor: '#F9FAFB' }}\n onClick={() => onRowClick?.(row.original)}\n style={{\n cursor: onRowClick ? 'pointer' : 'default',\n transition: 'background-color 0.15s',\n }}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n style={{\n padding: '12px 16px',\n fontSize: '14px',\n color: THEME_COLORS.text,\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </motion.tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\nexport default DataTable;\n","import { motion, AnimatePresence } from 'motion/react';\nimport { useState } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { JsonViewerProps } from '../types';\n\n// Syntax highlighting colors\nconst syntaxColors = {\n key: '#0066CC',\n string: '#10B981',\n number: '#F59E0B',\n boolean: '#8B5CF6',\n null: '#6B7280',\n bracket: '#111827',\n};\n\n// Recursive renderer for JSON\nconst JsonNode = ({\n data,\n depth = 0,\n collapsible,\n maxHeight,\n}: {\n data: unknown;\n depth?: number;\n collapsible?: boolean;\n maxHeight?: string;\n}) => {\n const [expanded, setExpanded] = useState(depth < 2);\n\n const indent = depth * 16;\n\n const renderValue = (value: unknown, key?: string): JSX.Element => {\n if (value === null) {\n return <span style={{ color: syntaxColors.null }}>null</span>;\n }\n if (typeof value === 'boolean') {\n return <span style={{ color: syntaxColors.boolean }}>{String(value)}</span>;\n }\n if (typeof value === 'number') {\n return <span style={{ color: syntaxColors.number }}>{value}</span>;\n }\n if (typeof value === 'string') {\n return <span style={{ color: syntaxColors.string }}>\"{value}\"</span>;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return <span style={{ color: syntaxColors.bracket }}>[]</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n [{' '}\n {expanded ? (\n <>\n {value.map((item, i) => (\n <span key={i}>\n {renderValue(item)}\n {i < value.length - 1 && ', '}\n </span>\n ))}\n </>\n ) : (\n <span style={{ color: syntaxColors.null }}>...{value.length} items</span>\n )}{' '}\n ]\n </span>\n );\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return <span style={{ color: syntaxColors.bracket }}>{'{}'}</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n {expanded ? '{ ' : '{ ... '}\n {expanded && (\n <motion.div\n initial={false}\n animate={{ height: 'auto', opacity: 1 }}\n style={{ paddingLeft: 16 }}\n >\n {entries.map(([k, v], i) => (\n <div key={k}>\n <span style={{ color: syntaxColors.key }}>\"{k}\"</span>: {renderValue(v, k)}\n {i < entries.length - 1 && ','}\n </div>\n ))}\n </motion.div>\n )}\n {expanded ? '}' : '}'}\n </span>\n );\n }\n return <span>{String(value)}</span>;\n };\n\n if (collapsible && depth > 0 && typeof data === 'object' && data !== null) {\n const entries = Object.entries(data as Record<string, unknown>);\n const isExpandable = entries.length > 0 || Array.isArray(data);\n\n return (\n <div style={{ marginLeft: indent }}>\n <motion.button\n onClick={() => setExpanded(!expanded)}\n whileHover={{ scale: 1.02 }}\n style={{\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '2px 4px',\n fontFamily: 'monospace',\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <span style={{ transition: 'transform 0.2s', transform: expanded ? 'rotate(90deg)' : 'rotate(0deg)' }}>\n ▶\n </span>\n {expanded ? 'collapse' : 'expand'}\n </motion.button>\n <AnimatePresence>\n {expanded && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n style={{ overflow: maxHeight ? (expanded ? 'auto' : 'hidden') : undefined, maxHeight }}\n >\n {renderValue(data)}\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n\n return <div style={{ marginLeft: indent }}>{renderValue(data)}</div>;\n};\n\n// Copy to clipboard\nconst CopyButton = ({ data }: { data: unknown }) => {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(JSON.stringify(data, null, 2));\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <motion.button\n onClick={handleCopy}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n style={{\n position: 'absolute',\n top: '12px',\n right: '12px',\n padding: '6px 12px',\n backgroundColor: copied ? THEME_COLORS.success : THEME_COLORS.surface,\n color: copied ? 'white' : THEME_COLORS.text,\n border: 'none',\n borderRadius: '6px',\n fontSize: '12px',\n fontWeight: 500,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </motion.button>\n );\n};\n\nexport const JsonViewer = ({ data, collapsible = true, maxHeight }: JsonViewerProps) => {\n return (\n <div\n style={{\n position: 'relative',\n backgroundColor: '#F8FAFC',\n borderRadius: '8px',\n padding: '16px',\n fontFamily: 'monospace',\n fontSize: '13px',\n lineHeight: 1.6,\n overflow: maxHeight ? 'hidden' : undefined,\n maxHeight: maxHeight,\n }}\n >\n <CopyButton data={data} />\n <JsonNode data={data} collapsible={collapsible} maxHeight={maxHeight} />\n </div>\n );\n};\n\nexport default JsonViewer;\n"]}
1
+ {"version":3,"sources":["/home/charles/git/peraspera/stackwright-pro/packages/display-components/dist/index.js","../src/components/MetricCard.tsx","../src/types/index.ts","../src/components/StatusBadge.tsx","../src/components/StatBar.tsx","../src/components/Sparkline.tsx","../src/components/ActivityFeed.tsx","../src/components/DashboardGrid.tsx","../src/components/DataTable.tsx","../src/components/JsonViewer.tsx","../src/registration.ts"],"names":["jsxs","jsx","useState"],"mappings":"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","file":"/home/charles/git/peraspera/stackwright-pro/packages/display-components/dist/index.js","sourcesContent":[null,"import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { MetricCardProps, TrendDirection } from '../types';\n\n// Trend arrow icons\nconst TrendArrow = ({ direction }: { direction: TrendDirection }) => {\n const color =\n direction === 'up'\n ? THEME_COLORS.success\n : direction === 'down'\n ? THEME_COLORS.error\n : THEME_COLORS.textSecondary;\n\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transform: direction === 'down' ? 'rotate(180deg)' : undefined,\n }}\n >\n <path d=\"M12 19V5M5 12l7-7 7 7\" />\n </svg>\n );\n};\n\n// Animated number counter\nconst AnimatedNumber = ({ value }: { value: number }) => {\n return (\n <motion.span\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, ease: 'easeOut' }}\n >\n {value.toLocaleString()}\n </motion.span>\n );\n};\n\nexport const MetricCard = ({\n label,\n value,\n trend,\n trendValue,\n color = THEME_COLORS.primary,\n icon,\n}: MetricCardProps) => {\n return (\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n whileHover={{ scale: 1.02, boxShadow: '0 4px 20px rgba(0,0,0,0.1)' }}\n transition={{ duration: 0.3 }}\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '24px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n position: 'relative',\n overflow: 'hidden',\n }}\n >\n {/* Accent bar */}\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '4px',\n backgroundColor: color,\n }}\n />\n\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>\n <div style={{ flex: 1 }}>\n {/* Label */}\n <p\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n margin: '0 0 8px 0',\n fontWeight: 500,\n }}\n >\n {label}\n </p>\n\n {/* Value */}\n <p\n style={{\n fontSize: '36px',\n fontWeight: 700,\n color: THEME_COLORS.text,\n margin: 0,\n lineHeight: 1,\n }}\n >\n <AnimatedNumber value={value} />\n </p>\n\n {/* Trend */}\n {trend && trendValue && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n marginTop: '12px',\n }}\n >\n <TrendArrow direction={trend} />\n <span\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {trendValue}\n </span>\n </div>\n )}\n </div>\n\n {/* Icon */}\n {icon && (\n <div\n style={{\n width: '48px',\n height: '48px',\n borderRadius: '12px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: color,\n }}\n >\n {icon}\n </div>\n )}\n </div>\n </motion.div>\n );\n};\n\nexport default MetricCard;\n","import React from 'react';\n\n// Trend direction for metrics\nexport type TrendDirection = 'up' | 'down' | 'stable';\n\n// Status badge variants\nexport type StatusVariant = 'operational' | 'degraded' | 'outage' | 'maintenance';\n\n// Metric card props\nexport interface MetricCardProps {\n label: string;\n value: number;\n trend?: TrendDirection;\n trendValue?: string;\n color?: string;\n icon?: React.ReactNode;\n}\n\n// Status badge props\nexport interface StatusBadgeProps {\n status: StatusVariant;\n label: string;\n pulse?: boolean;\n}\n\n// Stat bar props\nexport interface StatBarProps {\n current: number;\n max: number;\n label?: string;\n color?: string;\n showPercentage?: boolean;\n}\n\n// Sparkline props\nexport interface SparklineProps {\n data: number[];\n width?: number;\n height?: number;\n color?: string;\n fill?: boolean;\n}\n\n// Activity feed item\nexport interface ActivityItem {\n id: string;\n type: 'success' | 'warning' | 'error' | 'info';\n title: string;\n description?: string;\n timestamp: Date | string;\n}\n\n// Activity feed props\nexport interface ActivityFeedProps {\n items: ActivityItem[];\n maxItems?: number;\n}\n\n// Dashboard grid props\nexport interface DashboardGridProps {\n columns?: 1 | 2 | 3 | 4;\n cards: React.ReactNode[];\n gap?: number;\n}\n\n// Column definition for data table\nexport interface ColumnDef<T> {\n field: keyof T;\n header: string;\n type?: 'text' | 'badge' | 'date' | 'number';\n sortable?: boolean;\n filterable?: boolean;\n}\n\n// Data table props\nexport interface DataTableProps<T> {\n data: T[];\n columns: ColumnDef<T>[];\n loading?: boolean;\n emptyMessage?: string;\n onRowClick?: (row: T) => void;\n}\n\n// JSON viewer props\nexport interface JsonViewerProps {\n data: unknown;\n collapsible?: boolean;\n maxHeight?: string;\n}\n\n// Theme colors for Stackwright Pro\nexport const THEME_COLORS = {\n primary: '#0066CC',\n success: '#10B981',\n warning: '#F59E0B',\n error: '#EF4444',\n info: '#3B82F6',\n background: '#FFFFFF',\n surface: '#F3F4F6',\n text: '#111827',\n textSecondary: '#6B7280',\n} as const;\n\n// Status colors\nexport const STATUS_COLORS: Record<StatusVariant, string> = {\n operational: '#10B981',\n degraded: '#F59E0B',\n outage: '#EF4444',\n maintenance: '#6B7280',\n};\n","import { motion } from 'motion/react';\nimport { STATUS_COLORS } from '../types';\nimport type { StatusBadgeProps } from '../types';\n\nexport const StatusBadge = ({ status, label, pulse = false }: StatusBadgeProps) => {\n const color = STATUS_COLORS[status];\n\n return (\n <div\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 12px',\n borderRadius: '9999px',\n backgroundColor: `${color}15`,\n border: `1px solid ${color}30`,\n }}\n >\n {/* Pulsing dot */}\n {pulse && (\n <motion.div\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.6, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: 'easeInOut',\n }}\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n boxShadow: `0 0 8px ${color}`,\n }}\n />\n )}\n\n {/* Static dot */}\n {!pulse && (\n <div\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n }}\n />\n )}\n\n {/* Label */}\n <span\n style={{\n fontSize: '13px',\n fontWeight: 600,\n color: color,\n textTransform: 'capitalize',\n }}\n >\n {label}\n </span>\n </div>\n );\n};\n\nexport default StatusBadge;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { StatBarProps } from '../types';\n\nexport const StatBar = ({\n current,\n max,\n label,\n color = THEME_COLORS.primary,\n showPercentage = true,\n}: StatBarProps) => {\n const percentage = Math.min(100, Math.round((current / max) * 100));\n\n return (\n <div style={{ width: '100%' }}>\n {/* Label and percentage */}\n {(label || showPercentage) && (\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '8px',\n }}\n >\n {label && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.text,\n fontWeight: 500,\n }}\n >\n {label}\n </span>\n )}\n {showPercentage && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n fontWeight: 600,\n }}\n >\n {percentage}%\n </span>\n )}\n </div>\n )}\n\n {/* Progress bar */}\n <div\n style={{\n width: '100%',\n height: '8px',\n backgroundColor: `${color}20`,\n borderRadius: '4px',\n overflow: 'hidden',\n }}\n >\n <motion.div\n initial={{ width: 0 }}\n animate={{ width: `${percentage}%` }}\n transition={{ duration: 0.8, ease: 'easeOut' }}\n style={{\n height: '100%',\n backgroundColor: color,\n borderRadius: '4px',\n }}\n />\n </div>\n\n {/* Current/Max values */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginTop: '4px',\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <span>{current.toLocaleString()}</span>\n <span>{max.toLocaleString()}</span>\n </div>\n </div>\n );\n};\n\nexport default StatBar;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { SparklineProps } from '../types';\n\nexport const Sparkline = ({\n data,\n width = 100,\n height = 30,\n color = THEME_COLORS.primary,\n fill = false,\n}: SparklineProps) => {\n if (!data || data.length < 2) {\n return null;\n }\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const range = max - min || 1;\n\n // Generate points\n const points = data.map((value, index) => {\n const x = (index / (data.length - 1)) * width;\n const y = height - ((value - min) / range) * height;\n return `${x},${y}`;\n });\n\n const pathD = `M ${points.join(' L ')}`;\n const fillPath = `${pathD} L ${width},${height} L 0,${height} Z`;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n style={{ overflow: 'visible' }}\n >\n <defs>\n <linearGradient id={`gradient-${color.replace('#', '')}`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.3} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n </defs>\n\n {/* Fill area */}\n {fill && (\n <motion.path\n d={fillPath}\n fill={`url(#gradient-${color.replace('#', '')})`}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.5 }}\n />\n )}\n\n {/* Line */}\n <motion.path\n d={pathD}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={{ duration: 1, ease: 'easeOut' }}\n />\n\n {/* End dot */}\n <motion.circle\n cx={width}\n cy={height - ((data[data.length - 1] - min) / range) * height}\n r=\"3\"\n fill={color}\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={{ delay: 0.9, duration: 0.2 }}\n />\n </svg>\n );\n};\n\nexport default Sparkline;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { ActivityFeedProps, ActivityItem } from '../types';\n\n// Icon components for each activity type\nconst ActivityIcon = ({ type }: { type: ActivityItem['type'] }) => {\n const color =\n type === 'success'\n ? THEME_COLORS.success\n : type === 'warning'\n ? THEME_COLORS.warning\n : type === 'error'\n ? THEME_COLORS.error\n : THEME_COLORS.info;\n\n const iconPaths: Record<ActivityItem['type'], string> = {\n success: 'M20 6L9 17l-5-5',\n warning: 'M12 9v4M12 17h.01',\n error: 'M18 6L6 18M6 6l12 12',\n info: 'M12 16v-4M12 8h.01',\n };\n\n return (\n <div\n style={{\n width: '32px',\n height: '32px',\n borderRadius: '8px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d={iconPaths[type]} />\n </svg>\n </div>\n );\n};\n\n// Format timestamp to relative time\nconst formatTimestamp = (timestamp: Date | string): string => {\n const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n};\n\n// Single activity item\nconst ActivityFeedItem = ({ item, index }: { item: ActivityItem; index: number }) => {\n return (\n <motion.div\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ delay: index * 0.1, duration: 0.3 }}\n style={{\n display: 'flex',\n gap: '12px',\n padding: '12px 0',\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n <ActivityIcon type={item.type} />\n <div style={{ flex: 1 }}>\n <p\n style={{\n fontSize: '14px',\n fontWeight: 500,\n color: THEME_COLORS.text,\n margin: 0,\n }}\n >\n {item.title}\n </p>\n {item.description && (\n <p\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n margin: '4px 0 0 0',\n }}\n >\n {item.description}\n </p>\n )}\n </div>\n <span\n style={{\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n whiteSpace: 'nowrap',\n }}\n >\n {formatTimestamp(item.timestamp)}\n </span>\n </motion.div>\n );\n};\n\nexport const ActivityFeed = ({ items, maxItems }: ActivityFeedProps) => {\n const displayItems = maxItems ? items.slice(0, maxItems) : items;\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '20px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <h3\n style={{\n fontSize: '16px',\n fontWeight: 600,\n color: THEME_COLORS.text,\n margin: '0 0 16px 0',\n }}\n >\n Recent Activity\n </h3>\n <div>\n {displayItems.map((item, index) => (\n <ActivityFeedItem key={item.id} item={item} index={index} />\n ))}\n </div>\n </div>\n );\n};\n\nexport default ActivityFeed;\n","import { motion } from 'motion/react';\nimport type { DashboardGridProps } from '../types';\n\nexport const DashboardGrid = ({ columns = 3, cards, gap = 24 }: DashboardGridProps) => {\n return (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${columns}, 1fr)`,\n gap: `${gap}px`,\n width: '100%',\n }}\n >\n {cards.map((card, index) => (\n <motion.div\n key={index}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: index * 0.1, duration: 0.4 }}\n >\n {card}\n </motion.div>\n ))}\n </div>\n );\n};\n\nexport default DashboardGrid;\n","import {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type ColumnDef as TanstackColumnDef,\n} from '@tanstack/react-table';\nimport { motion } from 'motion/react';\nimport { useState } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { DataTableProps, ColumnDef } from '../types';\n\nexport function DataTable<T extends object>({\n data,\n columns,\n loading = false,\n emptyMessage = 'No data available',\n onRowClick,\n}: DataTableProps<T>) {\n const [sorting, setSorting] = useState<SortingState>([]);\n\n // Convert ColumnDef to tanstack columns using accessors\n const tableColumns: TanstackColumnDef<T>[] = columns.map((col) => ({\n id: String(col.field),\n accessorKey: String(col.field) as keyof T,\n header: col.header,\n cell: (info) => {\n const value = info.getValue();\n\n // Format based on type\n if (col.type === 'date' && value) {\n return new Date(value as string | Date).toLocaleDateString();\n }\n if (col.type === 'number') {\n return (value as number).toLocaleString();\n }\n if (col.type === 'badge') {\n const badgeColor =\n value === 'available' || value === 'operational'\n ? THEME_COLORS.success\n : value === 'pending'\n ? THEME_COLORS.warning\n : THEME_COLORS.error;\n return (\n <span\n style={{\n padding: '4px 8px',\n borderRadius: '4px',\n backgroundColor: `${badgeColor}15`,\n color: badgeColor,\n fontSize: '12px',\n fontWeight: 500,\n }}\n >\n {String(value)}\n </span>\n );\n }\n return String(value ?? '');\n },\n sortingFn: col.sortable ? 'alphanumeric' : undefined,\n enableSorting: col.sortable ?? false,\n }));\n\n const table = useReactTable({\n data,\n columns: tableColumns,\n state: { sorting },\n onSortingChange: setSorting,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n });\n\n if (loading) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <motion.div\n animate={{ rotate: 360 }}\n transition={{ duration: 1, repeat: Infinity, ease: 'linear' }}\n style={{\n width: '24px',\n height: '24px',\n border: '3px solid #E5E7EB',\n borderTopColor: THEME_COLORS.primary,\n borderRadius: '50%',\n }}\n />\n </div>\n );\n }\n\n if (data.length === 0) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n overflow: 'hidden',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <div style={{ overflowX: 'auto' }}>\n <table style={{ width: '100%', borderCollapse: 'collapse' }}>\n <thead>\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n onClick={header.column.getToggleSortingHandler()}\n style={{\n padding: '12px 16px',\n textAlign: 'left',\n fontSize: '12px',\n fontWeight: 600,\n color: THEME_COLORS.textSecondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n backgroundColor: THEME_COLORS.surface,\n borderBottom: '1px solid #E5E7EB',\n cursor: columns.find((c) => c.field === header.column.id)?.sortable\n ? 'pointer'\n : 'default',\n userSelect: 'none',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n {flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getIsSorted() && (\n <span>{header.column.getIsSorted() === 'asc' ? '↑' : '↓'}</span>\n )}\n </div>\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.map((row) => (\n <motion.tr\n key={row.id}\n whileHover={{ backgroundColor: '#F9FAFB' }}\n onClick={() => onRowClick?.(row.original)}\n style={{\n cursor: onRowClick ? 'pointer' : 'default',\n transition: 'background-color 0.15s',\n }}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n style={{\n padding: '12px 16px',\n fontSize: '14px',\n color: THEME_COLORS.text,\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </motion.tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\nexport default DataTable;\n","import { motion, AnimatePresence } from 'motion/react';\nimport { useState } from 'react';\nimport type { JSX } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { JsonViewerProps } from '../types';\n\n// Syntax highlighting colors\nconst syntaxColors = {\n key: '#0066CC',\n string: '#10B981',\n number: '#F59E0B',\n boolean: '#8B5CF6',\n null: '#6B7280',\n bracket: '#111827',\n};\n\n// Recursive renderer for JSON\nconst JsonNode = ({\n data,\n depth = 0,\n collapsible,\n maxHeight,\n}: {\n data: unknown;\n depth?: number;\n collapsible?: boolean;\n maxHeight?: string;\n}) => {\n const [expanded, setExpanded] = useState(depth < 2);\n\n const indent = depth * 16;\n\n const renderValue = (value: unknown, _key?: string): JSX.Element => {\n if (value === null) {\n return <span style={{ color: syntaxColors.null }}>null</span>;\n }\n if (typeof value === 'boolean') {\n return <span style={{ color: syntaxColors.boolean }}>{String(value)}</span>;\n }\n if (typeof value === 'number') {\n return <span style={{ color: syntaxColors.number }}>{value}</span>;\n }\n if (typeof value === 'string') {\n return <span style={{ color: syntaxColors.string }}>&quot;{value}&quot;</span>;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return <span style={{ color: syntaxColors.bracket }}>[]</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n [{' '}\n {expanded ? (\n <>\n {value.map((item, i) => (\n <span key={i}>\n {renderValue(item)}\n {i < value.length - 1 && ', '}\n </span>\n ))}\n </>\n ) : (\n <span style={{ color: syntaxColors.null }}>...{value.length} items</span>\n )}{' '}\n ]\n </span>\n );\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return <span style={{ color: syntaxColors.bracket }}>{'{}'}</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n {expanded ? '{ ' : '{ ... '}\n {expanded && (\n <motion.div\n initial={false}\n animate={{ height: 'auto', opacity: 1 }}\n style={{ paddingLeft: 16 }}\n >\n {entries.map(([k, v], i) => (\n <div key={k}>\n <span style={{ color: syntaxColors.key }}>&quot;{k}&quot;</span>:{' '}\n {renderValue(v, k)}\n {i < entries.length - 1 && ','}\n </div>\n ))}\n </motion.div>\n )}\n {expanded ? '}' : '}'}\n </span>\n );\n }\n return <span>{String(value)}</span>;\n };\n\n if (collapsible && depth > 0 && typeof data === 'object' && data !== null) {\n return (\n <div style={{ marginLeft: indent }}>\n <motion.button\n onClick={() => setExpanded(!expanded)}\n whileHover={{ scale: 1.02 }}\n style={{\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '2px 4px',\n fontFamily: 'monospace',\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <span\n style={{\n transition: 'transform 0.2s',\n transform: expanded ? 'rotate(90deg)' : 'rotate(0deg)',\n }}\n >\n ▶\n </span>\n {expanded ? 'collapse' : 'expand'}\n </motion.button>\n <AnimatePresence>\n {expanded && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n style={{\n overflow: maxHeight ? (expanded ? 'auto' : 'hidden') : undefined,\n maxHeight,\n }}\n >\n {renderValue(data)}\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n\n return <div style={{ marginLeft: indent }}>{renderValue(data)}</div>;\n};\n\n// Copy to clipboard\nconst CopyButton = ({ data }: { data: unknown }) => {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(JSON.stringify(data, null, 2));\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <motion.button\n onClick={handleCopy}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n style={{\n position: 'absolute',\n top: '12px',\n right: '12px',\n padding: '6px 12px',\n backgroundColor: copied ? THEME_COLORS.success : THEME_COLORS.surface,\n color: copied ? 'white' : THEME_COLORS.text,\n border: 'none',\n borderRadius: '6px',\n fontSize: '12px',\n fontWeight: 500,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </motion.button>\n );\n};\n\nexport const JsonViewer = ({ data, collapsible = true, maxHeight }: JsonViewerProps) => {\n return (\n <div\n style={{\n position: 'relative',\n backgroundColor: '#F8FAFC',\n borderRadius: '8px',\n padding: '16px',\n fontFamily: 'monospace',\n fontSize: '13px',\n lineHeight: 1.6,\n overflow: maxHeight ? 'hidden' : undefined,\n maxHeight: maxHeight,\n }}\n >\n <CopyButton data={data} />\n <JsonNode data={data} collapsible={collapsible} maxHeight={maxHeight} />\n </div>\n );\n};\n\nexport default JsonViewer;\n","import React from 'react';\nimport { registerComponent } from '@stackwright/core';\n\nimport { MetricCard } from './components/MetricCard';\nimport { StatusBadge } from './components/StatusBadge';\nimport { StatBar } from './components/StatBar';\nimport { Sparkline } from './components/Sparkline';\nimport { ActivityFeed } from './components/ActivityFeed';\nimport { DashboardGrid } from './components/DashboardGrid';\nimport { DataTable } from './components/DataTable';\nimport { JsonViewer } from './components/JsonViewer';\n\n// Re-export the ComponentProps type for use in casting\nexport type { ComponentProps } from '@stackwright/core';\n\ntype AnyComponent = React.ComponentType<any>;\n\nexport function registerDisplayComponents() {\n // Register components with double-cast to bypass strict type checking\n // The registry accepts any component, but we want to keep specific prop types for internal use\n registerComponent('metric_card', MetricCard as AnyComponent);\n registerComponent('status_badge', StatusBadge as AnyComponent);\n registerComponent('stat_bar', StatBar as AnyComponent);\n registerComponent('sparkline', Sparkline as AnyComponent);\n registerComponent('activity_feed', ActivityFeed as AnyComponent);\n registerComponent('dashboard_grid', DashboardGrid as AnyComponent);\n registerComponent('data_table', DataTable as AnyComponent);\n registerComponent('json_viewer', JsonViewer as AnyComponent);\n}\n"]}
package/dist/index.mjs CHANGED
@@ -457,10 +457,7 @@ var formatTimestamp = (timestamp) => {
457
457
  if (diffDays < 7) return `${diffDays}d ago`;
458
458
  return date.toLocaleDateString();
459
459
  };
460
- var ActivityFeedItem = ({
461
- item,
462
- index
463
- }) => {
460
+ var ActivityFeedItem = ({ item, index }) => {
464
461
  return /* @__PURE__ */ jsxs5(
465
462
  motion5.div,
466
463
  {
@@ -549,11 +546,7 @@ var ActivityFeed = ({ items, maxItems }) => {
549
546
  // src/components/DashboardGrid.tsx
550
547
  import { motion as motion6 } from "motion/react";
551
548
  import { jsx as jsx6 } from "react/jsx-runtime";
552
- var DashboardGrid = ({
553
- columns = 3,
554
- cards,
555
- gap = 24
556
- }) => {
549
+ var DashboardGrid = ({ columns = 3, cards, gap = 24 }) => {
557
550
  return /* @__PURE__ */ jsx6(
558
551
  "div",
559
552
  {
@@ -653,7 +646,13 @@ function DataTable({
653
646
  {
654
647
  animate: { rotate: 360 },
655
648
  transition: { duration: 1, repeat: Infinity, ease: "linear" },
656
- style: { width: "24px", height: "24px", border: "3px solid #E5E7EB", borderTopColor: THEME_COLORS.primary, borderRadius: "50%" }
649
+ style: {
650
+ width: "24px",
651
+ height: "24px",
652
+ border: "3px solid #E5E7EB",
653
+ borderTopColor: THEME_COLORS.primary,
654
+ borderRadius: "50%"
655
+ }
657
656
  }
658
657
  )
659
658
  }
@@ -759,7 +758,7 @@ var JsonNode = ({
759
758
  }) => {
760
759
  const [expanded, setExpanded] = useState2(depth < 2);
761
760
  const indent = depth * 16;
762
- const renderValue = (value, key) => {
761
+ const renderValue = (value, _key) => {
763
762
  if (value === null) {
764
763
  return /* @__PURE__ */ jsx8("span", { style: { color: syntaxColors.null }, children: "null" });
765
764
  }
@@ -810,7 +809,8 @@ var JsonNode = ({
810
809
  k,
811
810
  '"'
812
811
  ] }),
813
- ": ",
812
+ ":",
813
+ " ",
814
814
  renderValue(v, k),
815
815
  i < entries.length - 1 && ","
816
816
  ] }, k))
@@ -822,8 +822,6 @@ var JsonNode = ({
822
822
  return /* @__PURE__ */ jsx8("span", { children: String(value) });
823
823
  };
824
824
  if (collapsible && depth > 0 && typeof data === "object" && data !== null) {
825
- const entries = Object.entries(data);
826
- const isExpandable = entries.length > 0 || Array.isArray(data);
827
825
  return /* @__PURE__ */ jsxs7("div", { style: { marginLeft: indent }, children: [
828
826
  /* @__PURE__ */ jsxs7(
829
827
  motion8.button,
@@ -843,7 +841,16 @@ var JsonNode = ({
843
841
  gap: "4px"
844
842
  },
845
843
  children: [
846
- /* @__PURE__ */ jsx8("span", { style: { transition: "transform 0.2s", transform: expanded ? "rotate(90deg)" : "rotate(0deg)" }, children: "\u25B6" }),
844
+ /* @__PURE__ */ jsx8(
845
+ "span",
846
+ {
847
+ style: {
848
+ transition: "transform 0.2s",
849
+ transform: expanded ? "rotate(90deg)" : "rotate(0deg)"
850
+ },
851
+ children: "\u25B6"
852
+ }
853
+ ),
847
854
  expanded ? "collapse" : "expand"
848
855
  ]
849
856
  }
@@ -854,7 +861,10 @@ var JsonNode = ({
854
861
  initial: { height: 0, opacity: 0 },
855
862
  animate: { height: "auto", opacity: 1 },
856
863
  exit: { height: 0, opacity: 0 },
857
- style: { overflow: maxHeight ? expanded ? "auto" : "hidden" : void 0, maxHeight },
864
+ style: {
865
+ overflow: maxHeight ? expanded ? "auto" : "hidden" : void 0,
866
+ maxHeight
867
+ },
858
868
  children: renderValue(data)
859
869
  }
860
870
  ) })
@@ -915,6 +925,19 @@ var JsonViewer = ({ data, collapsible = true, maxHeight }) => {
915
925
  }
916
926
  );
917
927
  };
928
+
929
+ // src/registration.ts
930
+ import { registerComponent } from "@stackwright/core";
931
+ function registerDisplayComponents() {
932
+ registerComponent("metric_card", MetricCard);
933
+ registerComponent("status_badge", StatusBadge);
934
+ registerComponent("stat_bar", StatBar);
935
+ registerComponent("sparkline", Sparkline);
936
+ registerComponent("activity_feed", ActivityFeed);
937
+ registerComponent("dashboard_grid", DashboardGrid);
938
+ registerComponent("data_table", DataTable);
939
+ registerComponent("json_viewer", JsonViewer);
940
+ }
918
941
  export {
919
942
  ActivityFeed,
920
943
  DashboardGrid,
@@ -925,6 +948,7 @@ export {
925
948
  Sparkline,
926
949
  StatBar,
927
950
  StatusBadge,
928
- THEME_COLORS
951
+ THEME_COLORS,
952
+ registerDisplayComponents
929
953
  };
930
954
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/MetricCard.tsx","../src/types/index.ts","../src/components/StatusBadge.tsx","../src/components/StatBar.tsx","../src/components/Sparkline.tsx","../src/components/ActivityFeed.tsx","../src/components/DashboardGrid.tsx","../src/components/DataTable.tsx","../src/components/JsonViewer.tsx"],"sourcesContent":["import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { MetricCardProps, TrendDirection } from '../types';\n\n// Trend arrow icons\nconst TrendArrow = ({ direction }: { direction: TrendDirection }) => {\n const color =\n direction === 'up'\n ? THEME_COLORS.success\n : direction === 'down'\n ? THEME_COLORS.error\n : THEME_COLORS.textSecondary;\n\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transform: direction === 'down' ? 'rotate(180deg)' : undefined,\n }}\n >\n <path d=\"M12 19V5M5 12l7-7 7 7\" />\n </svg>\n );\n};\n\n// Animated number counter\nconst AnimatedNumber = ({ value }: { value: number }) => {\n return (\n <motion.span\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, ease: 'easeOut' }}\n >\n {value.toLocaleString()}\n </motion.span>\n );\n};\n\nexport const MetricCard = ({\n label,\n value,\n trend,\n trendValue,\n color = THEME_COLORS.primary,\n icon,\n}: MetricCardProps) => {\n return (\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n whileHover={{ scale: 1.02, boxShadow: '0 4px 20px rgba(0,0,0,0.1)' }}\n transition={{ duration: 0.3 }}\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '24px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n position: 'relative',\n overflow: 'hidden',\n }}\n >\n {/* Accent bar */}\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '4px',\n backgroundColor: color,\n }}\n />\n\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>\n <div style={{ flex: 1 }}>\n {/* Label */}\n <p\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n margin: '0 0 8px 0',\n fontWeight: 500,\n }}\n >\n {label}\n </p>\n\n {/* Value */}\n <p\n style={{\n fontSize: '36px',\n fontWeight: 700,\n color: THEME_COLORS.text,\n margin: 0,\n lineHeight: 1,\n }}\n >\n <AnimatedNumber value={value} />\n </p>\n\n {/* Trend */}\n {trend && trendValue && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n marginTop: '12px',\n }}\n >\n <TrendArrow direction={trend} />\n <span\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {trendValue}\n </span>\n </div>\n )}\n </div>\n\n {/* Icon */}\n {icon && (\n <div\n style={{\n width: '48px',\n height: '48px',\n borderRadius: '12px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: color,\n }}\n >\n {icon}\n </div>\n )}\n </div>\n </motion.div>\n );\n};\n\nexport default MetricCard;\n","// Trend direction for metrics\nexport type TrendDirection = 'up' | 'down' | 'stable';\n\n// Status badge variants\nexport type StatusVariant = 'operational' | 'degraded' | 'outage' | 'maintenance';\n\n// Metric card props\nexport interface MetricCardProps {\n label: string;\n value: number;\n trend?: TrendDirection;\n trendValue?: string;\n color?: string;\n icon?: React.ReactNode;\n}\n\n// Status badge props\nexport interface StatusBadgeProps {\n status: StatusVariant;\n label: string;\n pulse?: boolean;\n}\n\n// Stat bar props\nexport interface StatBarProps {\n current: number;\n max: number;\n label?: string;\n color?: string;\n showPercentage?: boolean;\n}\n\n// Sparkline props\nexport interface SparklineProps {\n data: number[];\n width?: number;\n height?: number;\n color?: string;\n fill?: boolean;\n}\n\n// Activity feed item\nexport interface ActivityItem {\n id: string;\n type: 'success' | 'warning' | 'error' | 'info';\n title: string;\n description?: string;\n timestamp: Date | string;\n}\n\n// Activity feed props\nexport interface ActivityFeedProps {\n items: ActivityItem[];\n maxItems?: number;\n}\n\n// Dashboard grid props\nexport interface DashboardGridProps {\n columns?: 1 | 2 | 3 | 4;\n cards: React.ReactNode[];\n gap?: number;\n}\n\n// Column definition for data table\nexport interface ColumnDef<T> {\n field: keyof T;\n header: string;\n type?: 'text' | 'badge' | 'date' | 'number';\n sortable?: boolean;\n filterable?: boolean;\n}\n\n// Data table props\nexport interface DataTableProps<T> {\n data: T[];\n columns: ColumnDef<T>[];\n loading?: boolean;\n emptyMessage?: string;\n onRowClick?: (row: T) => void;\n}\n\n// JSON viewer props\nexport interface JsonViewerProps {\n data: unknown;\n collapsible?: boolean;\n maxHeight?: string;\n}\n\n// Theme colors for Stackwright Pro\nexport const THEME_COLORS = {\n primary: '#0066CC',\n success: '#10B981',\n warning: '#F59E0B',\n error: '#EF4444',\n info: '#3B82F6',\n background: '#FFFFFF',\n surface: '#F3F4F6',\n text: '#111827',\n textSecondary: '#6B7280',\n} as const;\n\n// Status colors\nexport const STATUS_COLORS: Record<StatusVariant, string> = {\n operational: '#10B981',\n degraded: '#F59E0B',\n outage: '#EF4444',\n maintenance: '#6B7280',\n};\n","import { motion } from 'motion/react';\nimport { STATUS_COLORS } from '../types';\nimport type { StatusBadgeProps } from '../types';\n\nexport const StatusBadge = ({ status, label, pulse = false }: StatusBadgeProps) => {\n const color = STATUS_COLORS[status];\n\n return (\n <div\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 12px',\n borderRadius: '9999px',\n backgroundColor: `${color}15`,\n border: `1px solid ${color}30`,\n }}\n >\n {/* Pulsing dot */}\n {pulse && (\n <motion.div\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.6, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: 'easeInOut',\n }}\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n boxShadow: `0 0 8px ${color}`,\n }}\n />\n )}\n\n {/* Static dot */}\n {!pulse && (\n <div\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n }}\n />\n )}\n\n {/* Label */}\n <span\n style={{\n fontSize: '13px',\n fontWeight: 600,\n color: color,\n textTransform: 'capitalize',\n }}\n >\n {label}\n </span>\n </div>\n );\n};\n\nexport default StatusBadge;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { StatBarProps } from '../types';\n\nexport const StatBar = ({\n current,\n max,\n label,\n color = THEME_COLORS.primary,\n showPercentage = true,\n}: StatBarProps) => {\n const percentage = Math.min(100, Math.round((current / max) * 100));\n\n return (\n <div style={{ width: '100%' }}>\n {/* Label and percentage */}\n {(label || showPercentage) && (\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '8px',\n }}\n >\n {label && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.text,\n fontWeight: 500,\n }}\n >\n {label}\n </span>\n )}\n {showPercentage && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n fontWeight: 600,\n }}\n >\n {percentage}%\n </span>\n )}\n </div>\n )}\n\n {/* Progress bar */}\n <div\n style={{\n width: '100%',\n height: '8px',\n backgroundColor: `${color}20`,\n borderRadius: '4px',\n overflow: 'hidden',\n }}\n >\n <motion.div\n initial={{ width: 0 }}\n animate={{ width: `${percentage}%` }}\n transition={{ duration: 0.8, ease: 'easeOut' }}\n style={{\n height: '100%',\n backgroundColor: color,\n borderRadius: '4px',\n }}\n />\n </div>\n\n {/* Current/Max values */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginTop: '4px',\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <span>{current.toLocaleString()}</span>\n <span>{max.toLocaleString()}</span>\n </div>\n </div>\n );\n};\n\nexport default StatBar;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { SparklineProps } from '../types';\n\nexport const Sparkline = ({\n data,\n width = 100,\n height = 30,\n color = THEME_COLORS.primary,\n fill = false,\n}: SparklineProps) => {\n if (!data || data.length < 2) {\n return null;\n }\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const range = max - min || 1;\n\n // Generate points\n const points = data.map((value, index) => {\n const x = (index / (data.length - 1)) * width;\n const y = height - ((value - min) / range) * height;\n return `${x},${y}`;\n });\n\n const pathD = `M ${points.join(' L ')}`;\n const fillPath = `${pathD} L ${width},${height} L 0,${height} Z`;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n style={{ overflow: 'visible' }}\n >\n <defs>\n <linearGradient id={`gradient-${color.replace('#', '')}`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.3} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n </defs>\n\n {/* Fill area */}\n {fill && (\n <motion.path\n d={fillPath}\n fill={`url(#gradient-${color.replace('#', '')})`}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.5 }}\n />\n )}\n\n {/* Line */}\n <motion.path\n d={pathD}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={{ duration: 1, ease: 'easeOut' }}\n />\n\n {/* End dot */}\n <motion.circle\n cx={width}\n cy={height - ((data[data.length - 1] - min) / range) * height}\n r=\"3\"\n fill={color}\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={{ delay: 0.9, duration: 0.2 }}\n />\n </svg>\n );\n};\n\nexport default Sparkline;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { ActivityFeedProps, ActivityItem } from '../types';\n\n// Icon components for each activity type\nconst ActivityIcon = ({ type }: { type: ActivityItem['type'] }) => {\n const color =\n type === 'success'\n ? THEME_COLORS.success\n : type === 'warning'\n ? THEME_COLORS.warning\n : type === 'error'\n ? THEME_COLORS.error\n : THEME_COLORS.info;\n\n const iconPaths: Record<ActivityItem['type'], string> = {\n success: 'M20 6L9 17l-5-5',\n warning: 'M12 9v4M12 17h.01',\n error: 'M18 6L6 18M6 6l12 12',\n info: 'M12 16v-4M12 8h.01',\n };\n\n return (\n <div\n style={{\n width: '32px',\n height: '32px',\n borderRadius: '8px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d={iconPaths[type]} />\n </svg>\n </div>\n );\n};\n\n// Format timestamp to relative time\nconst formatTimestamp = (timestamp: Date | string): string => {\n const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n};\n\n// Single activity item\nconst ActivityFeedItem = ({\n item,\n index,\n}: {\n item: ActivityItem;\n index: number;\n}) => {\n return (\n <motion.div\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ delay: index * 0.1, duration: 0.3 }}\n style={{\n display: 'flex',\n gap: '12px',\n padding: '12px 0',\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n <ActivityIcon type={item.type} />\n <div style={{ flex: 1 }}>\n <p\n style={{\n fontSize: '14px',\n fontWeight: 500,\n color: THEME_COLORS.text,\n margin: 0,\n }}\n >\n {item.title}\n </p>\n {item.description && (\n <p\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n margin: '4px 0 0 0',\n }}\n >\n {item.description}\n </p>\n )}\n </div>\n <span\n style={{\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n whiteSpace: 'nowrap',\n }}\n >\n {formatTimestamp(item.timestamp)}\n </span>\n </motion.div>\n );\n};\n\nexport const ActivityFeed = ({ items, maxItems }: ActivityFeedProps) => {\n const displayItems = maxItems ? items.slice(0, maxItems) : items;\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '20px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <h3\n style={{\n fontSize: '16px',\n fontWeight: 600,\n color: THEME_COLORS.text,\n margin: '0 0 16px 0',\n }}\n >\n Recent Activity\n </h3>\n <div>\n {displayItems.map((item, index) => (\n <ActivityFeedItem key={item.id} item={item} index={index} />\n ))}\n </div>\n </div>\n );\n};\n\nexport default ActivityFeed;\n","import { motion } from 'motion/react';\nimport type { DashboardGridProps } from '../types';\n\nexport const DashboardGrid = ({\n columns = 3,\n cards,\n gap = 24,\n}: DashboardGridProps) => {\n return (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${columns}, 1fr)`,\n gap: `${gap}px`,\n width: '100%',\n }}\n >\n {cards.map((card, index) => (\n <motion.div\n key={index}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: index * 0.1, duration: 0.4 }}\n >\n {card}\n </motion.div>\n ))}\n </div>\n );\n};\n\nexport default DashboardGrid;\n","import {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type ColumnDef as TanstackColumnDef,\n} from '@tanstack/react-table';\nimport { motion } from 'motion/react';\nimport { useState } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { DataTableProps, ColumnDef } from '../types';\n\nexport function DataTable<T extends object>({\n data,\n columns,\n loading = false,\n emptyMessage = 'No data available',\n onRowClick,\n}: DataTableProps<T>) {\n const [sorting, setSorting] = useState<SortingState>([]);\n\n // Convert ColumnDef to tanstack columns using accessors\n const tableColumns: TanstackColumnDef<T>[] = columns.map((col) => ({\n id: String(col.field),\n accessorKey: String(col.field) as keyof T,\n header: col.header,\n cell: (info) => {\n const value = info.getValue();\n \n // Format based on type\n if (col.type === 'date' && value) {\n return new Date(value as string | Date).toLocaleDateString();\n }\n if (col.type === 'number') {\n return (value as number).toLocaleString();\n }\n if (col.type === 'badge') {\n const badgeColor =\n value === 'available' || value === 'operational'\n ? THEME_COLORS.success\n : value === 'pending'\n ? THEME_COLORS.warning\n : THEME_COLORS.error;\n return (\n <span\n style={{\n padding: '4px 8px',\n borderRadius: '4px',\n backgroundColor: `${badgeColor}15`,\n color: badgeColor,\n fontSize: '12px',\n fontWeight: 500,\n }}\n >\n {String(value)}\n </span>\n );\n }\n return String(value ?? '');\n },\n sortingFn: col.sortable ? 'alphanumeric' : undefined,\n enableSorting: col.sortable ?? false,\n }));\n\n const table = useReactTable({\n data,\n columns: tableColumns,\n state: { sorting },\n onSortingChange: setSorting,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n });\n\n if (loading) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <motion.div\n animate={{ rotate: 360 }}\n transition={{ duration: 1, repeat: Infinity, ease: 'linear' }}\n style={{ width: '24px', height: '24px', border: '3px solid #E5E7EB', borderTopColor: THEME_COLORS.primary, borderRadius: '50%' }}\n />\n </div>\n );\n }\n\n if (data.length === 0) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n overflow: 'hidden',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <div style={{ overflowX: 'auto' }}>\n <table style={{ width: '100%', borderCollapse: 'collapse' }}>\n <thead>\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n onClick={header.column.getToggleSortingHandler()}\n style={{\n padding: '12px 16px',\n textAlign: 'left',\n fontSize: '12px',\n fontWeight: 600,\n color: THEME_COLORS.textSecondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n backgroundColor: THEME_COLORS.surface,\n borderBottom: '1px solid #E5E7EB',\n cursor: columns.find(c => c.field === header.column.id)?.sortable ? 'pointer' : 'default',\n userSelect: 'none',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n {flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getIsSorted() && (\n <span>{header.column.getIsSorted() === 'asc' ? '↑' : '↓'}</span>\n )}\n </div>\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.map((row) => (\n <motion.tr\n key={row.id}\n whileHover={{ backgroundColor: '#F9FAFB' }}\n onClick={() => onRowClick?.(row.original)}\n style={{\n cursor: onRowClick ? 'pointer' : 'default',\n transition: 'background-color 0.15s',\n }}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n style={{\n padding: '12px 16px',\n fontSize: '14px',\n color: THEME_COLORS.text,\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </motion.tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\nexport default DataTable;\n","import { motion, AnimatePresence } from 'motion/react';\nimport { useState } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { JsonViewerProps } from '../types';\n\n// Syntax highlighting colors\nconst syntaxColors = {\n key: '#0066CC',\n string: '#10B981',\n number: '#F59E0B',\n boolean: '#8B5CF6',\n null: '#6B7280',\n bracket: '#111827',\n};\n\n// Recursive renderer for JSON\nconst JsonNode = ({\n data,\n depth = 0,\n collapsible,\n maxHeight,\n}: {\n data: unknown;\n depth?: number;\n collapsible?: boolean;\n maxHeight?: string;\n}) => {\n const [expanded, setExpanded] = useState(depth < 2);\n\n const indent = depth * 16;\n\n const renderValue = (value: unknown, key?: string): JSX.Element => {\n if (value === null) {\n return <span style={{ color: syntaxColors.null }}>null</span>;\n }\n if (typeof value === 'boolean') {\n return <span style={{ color: syntaxColors.boolean }}>{String(value)}</span>;\n }\n if (typeof value === 'number') {\n return <span style={{ color: syntaxColors.number }}>{value}</span>;\n }\n if (typeof value === 'string') {\n return <span style={{ color: syntaxColors.string }}>\"{value}\"</span>;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return <span style={{ color: syntaxColors.bracket }}>[]</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n [{' '}\n {expanded ? (\n <>\n {value.map((item, i) => (\n <span key={i}>\n {renderValue(item)}\n {i < value.length - 1 && ', '}\n </span>\n ))}\n </>\n ) : (\n <span style={{ color: syntaxColors.null }}>...{value.length} items</span>\n )}{' '}\n ]\n </span>\n );\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return <span style={{ color: syntaxColors.bracket }}>{'{}'}</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n {expanded ? '{ ' : '{ ... '}\n {expanded && (\n <motion.div\n initial={false}\n animate={{ height: 'auto', opacity: 1 }}\n style={{ paddingLeft: 16 }}\n >\n {entries.map(([k, v], i) => (\n <div key={k}>\n <span style={{ color: syntaxColors.key }}>\"{k}\"</span>: {renderValue(v, k)}\n {i < entries.length - 1 && ','}\n </div>\n ))}\n </motion.div>\n )}\n {expanded ? '}' : '}'}\n </span>\n );\n }\n return <span>{String(value)}</span>;\n };\n\n if (collapsible && depth > 0 && typeof data === 'object' && data !== null) {\n const entries = Object.entries(data as Record<string, unknown>);\n const isExpandable = entries.length > 0 || Array.isArray(data);\n\n return (\n <div style={{ marginLeft: indent }}>\n <motion.button\n onClick={() => setExpanded(!expanded)}\n whileHover={{ scale: 1.02 }}\n style={{\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '2px 4px',\n fontFamily: 'monospace',\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <span style={{ transition: 'transform 0.2s', transform: expanded ? 'rotate(90deg)' : 'rotate(0deg)' }}>\n ▶\n </span>\n {expanded ? 'collapse' : 'expand'}\n </motion.button>\n <AnimatePresence>\n {expanded && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n style={{ overflow: maxHeight ? (expanded ? 'auto' : 'hidden') : undefined, maxHeight }}\n >\n {renderValue(data)}\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n\n return <div style={{ marginLeft: indent }}>{renderValue(data)}</div>;\n};\n\n// Copy to clipboard\nconst CopyButton = ({ data }: { data: unknown }) => {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(JSON.stringify(data, null, 2));\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <motion.button\n onClick={handleCopy}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n style={{\n position: 'absolute',\n top: '12px',\n right: '12px',\n padding: '6px 12px',\n backgroundColor: copied ? THEME_COLORS.success : THEME_COLORS.surface,\n color: copied ? 'white' : THEME_COLORS.text,\n border: 'none',\n borderRadius: '6px',\n fontSize: '12px',\n fontWeight: 500,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </motion.button>\n );\n};\n\nexport const JsonViewer = ({ data, collapsible = true, maxHeight }: JsonViewerProps) => {\n return (\n <div\n style={{\n position: 'relative',\n backgroundColor: '#F8FAFC',\n borderRadius: '8px',\n padding: '16px',\n fontFamily: 'monospace',\n fontSize: '13px',\n lineHeight: 1.6,\n overflow: maxHeight ? 'hidden' : undefined,\n maxHeight: maxHeight,\n }}\n >\n <CopyButton data={data} />\n <JsonNode data={data} collapsible={collapsible} maxHeight={maxHeight} />\n </div>\n );\n};\n\nexport default JsonViewer;\n"],"mappings":"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","names":["motion","jsx","jsxs","motion","motion","jsx","jsxs","motion","motion","jsx","jsxs","motion","motion","jsx","jsxs","motion","motion","jsx","motion","jsx","jsxs","motion","motion","useState","jsx","jsxs","useState","motion"]}
1
+ {"version":3,"sources":["../src/components/MetricCard.tsx","../src/types/index.ts","../src/components/StatusBadge.tsx","../src/components/StatBar.tsx","../src/components/Sparkline.tsx","../src/components/ActivityFeed.tsx","../src/components/DashboardGrid.tsx","../src/components/DataTable.tsx","../src/components/JsonViewer.tsx","../src/registration.ts"],"sourcesContent":["import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { MetricCardProps, TrendDirection } from '../types';\n\n// Trend arrow icons\nconst TrendArrow = ({ direction }: { direction: TrendDirection }) => {\n const color =\n direction === 'up'\n ? THEME_COLORS.success\n : direction === 'down'\n ? THEME_COLORS.error\n : THEME_COLORS.textSecondary;\n\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transform: direction === 'down' ? 'rotate(180deg)' : undefined,\n }}\n >\n <path d=\"M12 19V5M5 12l7-7 7 7\" />\n </svg>\n );\n};\n\n// Animated number counter\nconst AnimatedNumber = ({ value }: { value: number }) => {\n return (\n <motion.span\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, ease: 'easeOut' }}\n >\n {value.toLocaleString()}\n </motion.span>\n );\n};\n\nexport const MetricCard = ({\n label,\n value,\n trend,\n trendValue,\n color = THEME_COLORS.primary,\n icon,\n}: MetricCardProps) => {\n return (\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n whileHover={{ scale: 1.02, boxShadow: '0 4px 20px rgba(0,0,0,0.1)' }}\n transition={{ duration: 0.3 }}\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '24px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n position: 'relative',\n overflow: 'hidden',\n }}\n >\n {/* Accent bar */}\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: '4px',\n backgroundColor: color,\n }}\n />\n\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>\n <div style={{ flex: 1 }}>\n {/* Label */}\n <p\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n margin: '0 0 8px 0',\n fontWeight: 500,\n }}\n >\n {label}\n </p>\n\n {/* Value */}\n <p\n style={{\n fontSize: '36px',\n fontWeight: 700,\n color: THEME_COLORS.text,\n margin: 0,\n lineHeight: 1,\n }}\n >\n <AnimatedNumber value={value} />\n </p>\n\n {/* Trend */}\n {trend && trendValue && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n marginTop: '12px',\n }}\n >\n <TrendArrow direction={trend} />\n <span\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {trendValue}\n </span>\n </div>\n )}\n </div>\n\n {/* Icon */}\n {icon && (\n <div\n style={{\n width: '48px',\n height: '48px',\n borderRadius: '12px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: color,\n }}\n >\n {icon}\n </div>\n )}\n </div>\n </motion.div>\n );\n};\n\nexport default MetricCard;\n","import React from 'react';\n\n// Trend direction for metrics\nexport type TrendDirection = 'up' | 'down' | 'stable';\n\n// Status badge variants\nexport type StatusVariant = 'operational' | 'degraded' | 'outage' | 'maintenance';\n\n// Metric card props\nexport interface MetricCardProps {\n label: string;\n value: number;\n trend?: TrendDirection;\n trendValue?: string;\n color?: string;\n icon?: React.ReactNode;\n}\n\n// Status badge props\nexport interface StatusBadgeProps {\n status: StatusVariant;\n label: string;\n pulse?: boolean;\n}\n\n// Stat bar props\nexport interface StatBarProps {\n current: number;\n max: number;\n label?: string;\n color?: string;\n showPercentage?: boolean;\n}\n\n// Sparkline props\nexport interface SparklineProps {\n data: number[];\n width?: number;\n height?: number;\n color?: string;\n fill?: boolean;\n}\n\n// Activity feed item\nexport interface ActivityItem {\n id: string;\n type: 'success' | 'warning' | 'error' | 'info';\n title: string;\n description?: string;\n timestamp: Date | string;\n}\n\n// Activity feed props\nexport interface ActivityFeedProps {\n items: ActivityItem[];\n maxItems?: number;\n}\n\n// Dashboard grid props\nexport interface DashboardGridProps {\n columns?: 1 | 2 | 3 | 4;\n cards: React.ReactNode[];\n gap?: number;\n}\n\n// Column definition for data table\nexport interface ColumnDef<T> {\n field: keyof T;\n header: string;\n type?: 'text' | 'badge' | 'date' | 'number';\n sortable?: boolean;\n filterable?: boolean;\n}\n\n// Data table props\nexport interface DataTableProps<T> {\n data: T[];\n columns: ColumnDef<T>[];\n loading?: boolean;\n emptyMessage?: string;\n onRowClick?: (row: T) => void;\n}\n\n// JSON viewer props\nexport interface JsonViewerProps {\n data: unknown;\n collapsible?: boolean;\n maxHeight?: string;\n}\n\n// Theme colors for Stackwright Pro\nexport const THEME_COLORS = {\n primary: '#0066CC',\n success: '#10B981',\n warning: '#F59E0B',\n error: '#EF4444',\n info: '#3B82F6',\n background: '#FFFFFF',\n surface: '#F3F4F6',\n text: '#111827',\n textSecondary: '#6B7280',\n} as const;\n\n// Status colors\nexport const STATUS_COLORS: Record<StatusVariant, string> = {\n operational: '#10B981',\n degraded: '#F59E0B',\n outage: '#EF4444',\n maintenance: '#6B7280',\n};\n","import { motion } from 'motion/react';\nimport { STATUS_COLORS } from '../types';\nimport type { StatusBadgeProps } from '../types';\n\nexport const StatusBadge = ({ status, label, pulse = false }: StatusBadgeProps) => {\n const color = STATUS_COLORS[status];\n\n return (\n <div\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 12px',\n borderRadius: '9999px',\n backgroundColor: `${color}15`,\n border: `1px solid ${color}30`,\n }}\n >\n {/* Pulsing dot */}\n {pulse && (\n <motion.div\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.6, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: 'easeInOut',\n }}\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n boxShadow: `0 0 8px ${color}`,\n }}\n />\n )}\n\n {/* Static dot */}\n {!pulse && (\n <div\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n }}\n />\n )}\n\n {/* Label */}\n <span\n style={{\n fontSize: '13px',\n fontWeight: 600,\n color: color,\n textTransform: 'capitalize',\n }}\n >\n {label}\n </span>\n </div>\n );\n};\n\nexport default StatusBadge;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { StatBarProps } from '../types';\n\nexport const StatBar = ({\n current,\n max,\n label,\n color = THEME_COLORS.primary,\n showPercentage = true,\n}: StatBarProps) => {\n const percentage = Math.min(100, Math.round((current / max) * 100));\n\n return (\n <div style={{ width: '100%' }}>\n {/* Label and percentage */}\n {(label || showPercentage) && (\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '8px',\n }}\n >\n {label && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.text,\n fontWeight: 500,\n }}\n >\n {label}\n </span>\n )}\n {showPercentage && (\n <span\n style={{\n fontSize: '14px',\n color: THEME_COLORS.textSecondary,\n fontWeight: 600,\n }}\n >\n {percentage}%\n </span>\n )}\n </div>\n )}\n\n {/* Progress bar */}\n <div\n style={{\n width: '100%',\n height: '8px',\n backgroundColor: `${color}20`,\n borderRadius: '4px',\n overflow: 'hidden',\n }}\n >\n <motion.div\n initial={{ width: 0 }}\n animate={{ width: `${percentage}%` }}\n transition={{ duration: 0.8, ease: 'easeOut' }}\n style={{\n height: '100%',\n backgroundColor: color,\n borderRadius: '4px',\n }}\n />\n </div>\n\n {/* Current/Max values */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginTop: '4px',\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <span>{current.toLocaleString()}</span>\n <span>{max.toLocaleString()}</span>\n </div>\n </div>\n );\n};\n\nexport default StatBar;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { SparklineProps } from '../types';\n\nexport const Sparkline = ({\n data,\n width = 100,\n height = 30,\n color = THEME_COLORS.primary,\n fill = false,\n}: SparklineProps) => {\n if (!data || data.length < 2) {\n return null;\n }\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const range = max - min || 1;\n\n // Generate points\n const points = data.map((value, index) => {\n const x = (index / (data.length - 1)) * width;\n const y = height - ((value - min) / range) * height;\n return `${x},${y}`;\n });\n\n const pathD = `M ${points.join(' L ')}`;\n const fillPath = `${pathD} L ${width},${height} L 0,${height} Z`;\n\n return (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n style={{ overflow: 'visible' }}\n >\n <defs>\n <linearGradient id={`gradient-${color.replace('#', '')}`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.3} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n </defs>\n\n {/* Fill area */}\n {fill && (\n <motion.path\n d={fillPath}\n fill={`url(#gradient-${color.replace('#', '')})`}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.5 }}\n />\n )}\n\n {/* Line */}\n <motion.path\n d={pathD}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n transition={{ duration: 1, ease: 'easeOut' }}\n />\n\n {/* End dot */}\n <motion.circle\n cx={width}\n cy={height - ((data[data.length - 1] - min) / range) * height}\n r=\"3\"\n fill={color}\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={{ delay: 0.9, duration: 0.2 }}\n />\n </svg>\n );\n};\n\nexport default Sparkline;\n","import { motion } from 'motion/react';\nimport { THEME_COLORS } from '../types';\nimport type { ActivityFeedProps, ActivityItem } from '../types';\n\n// Icon components for each activity type\nconst ActivityIcon = ({ type }: { type: ActivityItem['type'] }) => {\n const color =\n type === 'success'\n ? THEME_COLORS.success\n : type === 'warning'\n ? THEME_COLORS.warning\n : type === 'error'\n ? THEME_COLORS.error\n : THEME_COLORS.info;\n\n const iconPaths: Record<ActivityItem['type'], string> = {\n success: 'M20 6L9 17l-5-5',\n warning: 'M12 9v4M12 17h.01',\n error: 'M18 6L6 18M6 6l12 12',\n info: 'M12 16v-4M12 8h.01',\n };\n\n return (\n <div\n style={{\n width: '32px',\n height: '32px',\n borderRadius: '8px',\n backgroundColor: `${color}15`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d={iconPaths[type]} />\n </svg>\n </div>\n );\n};\n\n// Format timestamp to relative time\nconst formatTimestamp = (timestamp: Date | string): string => {\n const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n};\n\n// Single activity item\nconst ActivityFeedItem = ({ item, index }: { item: ActivityItem; index: number }) => {\n return (\n <motion.div\n initial={{ opacity: 0, x: -20 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ delay: index * 0.1, duration: 0.3 }}\n style={{\n display: 'flex',\n gap: '12px',\n padding: '12px 0',\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n <ActivityIcon type={item.type} />\n <div style={{ flex: 1 }}>\n <p\n style={{\n fontSize: '14px',\n fontWeight: 500,\n color: THEME_COLORS.text,\n margin: 0,\n }}\n >\n {item.title}\n </p>\n {item.description && (\n <p\n style={{\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n margin: '4px 0 0 0',\n }}\n >\n {item.description}\n </p>\n )}\n </div>\n <span\n style={{\n fontSize: '12px',\n color: THEME_COLORS.textSecondary,\n whiteSpace: 'nowrap',\n }}\n >\n {formatTimestamp(item.timestamp)}\n </span>\n </motion.div>\n );\n};\n\nexport const ActivityFeed = ({ items, maxItems }: ActivityFeedProps) => {\n const displayItems = maxItems ? items.slice(0, maxItems) : items;\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n padding: '20px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <h3\n style={{\n fontSize: '16px',\n fontWeight: 600,\n color: THEME_COLORS.text,\n margin: '0 0 16px 0',\n }}\n >\n Recent Activity\n </h3>\n <div>\n {displayItems.map((item, index) => (\n <ActivityFeedItem key={item.id} item={item} index={index} />\n ))}\n </div>\n </div>\n );\n};\n\nexport default ActivityFeed;\n","import { motion } from 'motion/react';\nimport type { DashboardGridProps } from '../types';\n\nexport const DashboardGrid = ({ columns = 3, cards, gap = 24 }: DashboardGridProps) => {\n return (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${columns}, 1fr)`,\n gap: `${gap}px`,\n width: '100%',\n }}\n >\n {cards.map((card, index) => (\n <motion.div\n key={index}\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: index * 0.1, duration: 0.4 }}\n >\n {card}\n </motion.div>\n ))}\n </div>\n );\n};\n\nexport default DashboardGrid;\n","import {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type ColumnDef as TanstackColumnDef,\n} from '@tanstack/react-table';\nimport { motion } from 'motion/react';\nimport { useState } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { DataTableProps, ColumnDef } from '../types';\n\nexport function DataTable<T extends object>({\n data,\n columns,\n loading = false,\n emptyMessage = 'No data available',\n onRowClick,\n}: DataTableProps<T>) {\n const [sorting, setSorting] = useState<SortingState>([]);\n\n // Convert ColumnDef to tanstack columns using accessors\n const tableColumns: TanstackColumnDef<T>[] = columns.map((col) => ({\n id: String(col.field),\n accessorKey: String(col.field) as keyof T,\n header: col.header,\n cell: (info) => {\n const value = info.getValue();\n\n // Format based on type\n if (col.type === 'date' && value) {\n return new Date(value as string | Date).toLocaleDateString();\n }\n if (col.type === 'number') {\n return (value as number).toLocaleString();\n }\n if (col.type === 'badge') {\n const badgeColor =\n value === 'available' || value === 'operational'\n ? THEME_COLORS.success\n : value === 'pending'\n ? THEME_COLORS.warning\n : THEME_COLORS.error;\n return (\n <span\n style={{\n padding: '4px 8px',\n borderRadius: '4px',\n backgroundColor: `${badgeColor}15`,\n color: badgeColor,\n fontSize: '12px',\n fontWeight: 500,\n }}\n >\n {String(value)}\n </span>\n );\n }\n return String(value ?? '');\n },\n sortingFn: col.sortable ? 'alphanumeric' : undefined,\n enableSorting: col.sortable ?? false,\n }));\n\n const table = useReactTable({\n data,\n columns: tableColumns,\n state: { sorting },\n onSortingChange: setSorting,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n });\n\n if (loading) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n <motion.div\n animate={{ rotate: 360 }}\n transition={{ duration: 1, repeat: Infinity, ease: 'linear' }}\n style={{\n width: '24px',\n height: '24px',\n border: '3px solid #E5E7EB',\n borderTopColor: THEME_COLORS.primary,\n borderRadius: '50%',\n }}\n />\n </div>\n );\n }\n\n if (data.length === 0) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '48px',\n color: THEME_COLORS.textSecondary,\n }}\n >\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div\n style={{\n backgroundColor: 'white',\n borderRadius: '12px',\n overflow: 'hidden',\n boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n border: '1px solid #E5E7EB',\n }}\n >\n <div style={{ overflowX: 'auto' }}>\n <table style={{ width: '100%', borderCollapse: 'collapse' }}>\n <thead>\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n onClick={header.column.getToggleSortingHandler()}\n style={{\n padding: '12px 16px',\n textAlign: 'left',\n fontSize: '12px',\n fontWeight: 600,\n color: THEME_COLORS.textSecondary,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n backgroundColor: THEME_COLORS.surface,\n borderBottom: '1px solid #E5E7EB',\n cursor: columns.find((c) => c.field === header.column.id)?.sortable\n ? 'pointer'\n : 'default',\n userSelect: 'none',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n {flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getIsSorted() && (\n <span>{header.column.getIsSorted() === 'asc' ? '↑' : '↓'}</span>\n )}\n </div>\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.map((row) => (\n <motion.tr\n key={row.id}\n whileHover={{ backgroundColor: '#F9FAFB' }}\n onClick={() => onRowClick?.(row.original)}\n style={{\n cursor: onRowClick ? 'pointer' : 'default',\n transition: 'background-color 0.15s',\n }}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n style={{\n padding: '12px 16px',\n fontSize: '14px',\n color: THEME_COLORS.text,\n borderBottom: '1px solid #E5E7EB',\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </motion.tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\nexport default DataTable;\n","import { motion, AnimatePresence } from 'motion/react';\nimport { useState } from 'react';\nimport type { JSX } from 'react';\nimport { THEME_COLORS } from '../types';\nimport type { JsonViewerProps } from '../types';\n\n// Syntax highlighting colors\nconst syntaxColors = {\n key: '#0066CC',\n string: '#10B981',\n number: '#F59E0B',\n boolean: '#8B5CF6',\n null: '#6B7280',\n bracket: '#111827',\n};\n\n// Recursive renderer for JSON\nconst JsonNode = ({\n data,\n depth = 0,\n collapsible,\n maxHeight,\n}: {\n data: unknown;\n depth?: number;\n collapsible?: boolean;\n maxHeight?: string;\n}) => {\n const [expanded, setExpanded] = useState(depth < 2);\n\n const indent = depth * 16;\n\n const renderValue = (value: unknown, _key?: string): JSX.Element => {\n if (value === null) {\n return <span style={{ color: syntaxColors.null }}>null</span>;\n }\n if (typeof value === 'boolean') {\n return <span style={{ color: syntaxColors.boolean }}>{String(value)}</span>;\n }\n if (typeof value === 'number') {\n return <span style={{ color: syntaxColors.number }}>{value}</span>;\n }\n if (typeof value === 'string') {\n return <span style={{ color: syntaxColors.string }}>&quot;{value}&quot;</span>;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return <span style={{ color: syntaxColors.bracket }}>[]</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n [{' '}\n {expanded ? (\n <>\n {value.map((item, i) => (\n <span key={i}>\n {renderValue(item)}\n {i < value.length - 1 && ', '}\n </span>\n ))}\n </>\n ) : (\n <span style={{ color: syntaxColors.null }}>...{value.length} items</span>\n )}{' '}\n ]\n </span>\n );\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return <span style={{ color: syntaxColors.bracket }}>{'{}'}</span>;\n return (\n <span style={{ color: syntaxColors.bracket }}>\n {expanded ? '{ ' : '{ ... '}\n {expanded && (\n <motion.div\n initial={false}\n animate={{ height: 'auto', opacity: 1 }}\n style={{ paddingLeft: 16 }}\n >\n {entries.map(([k, v], i) => (\n <div key={k}>\n <span style={{ color: syntaxColors.key }}>&quot;{k}&quot;</span>:{' '}\n {renderValue(v, k)}\n {i < entries.length - 1 && ','}\n </div>\n ))}\n </motion.div>\n )}\n {expanded ? '}' : '}'}\n </span>\n );\n }\n return <span>{String(value)}</span>;\n };\n\n if (collapsible && depth > 0 && typeof data === 'object' && data !== null) {\n return (\n <div style={{ marginLeft: indent }}>\n <motion.button\n onClick={() => setExpanded(!expanded)}\n whileHover={{ scale: 1.02 }}\n style={{\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '2px 4px',\n fontFamily: 'monospace',\n fontSize: '13px',\n color: THEME_COLORS.textSecondary,\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <span\n style={{\n transition: 'transform 0.2s',\n transform: expanded ? 'rotate(90deg)' : 'rotate(0deg)',\n }}\n >\n ▶\n </span>\n {expanded ? 'collapse' : 'expand'}\n </motion.button>\n <AnimatePresence>\n {expanded && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n style={{\n overflow: maxHeight ? (expanded ? 'auto' : 'hidden') : undefined,\n maxHeight,\n }}\n >\n {renderValue(data)}\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n }\n\n return <div style={{ marginLeft: indent }}>{renderValue(data)}</div>;\n};\n\n// Copy to clipboard\nconst CopyButton = ({ data }: { data: unknown }) => {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(JSON.stringify(data, null, 2));\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <motion.button\n onClick={handleCopy}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n style={{\n position: 'absolute',\n top: '12px',\n right: '12px',\n padding: '6px 12px',\n backgroundColor: copied ? THEME_COLORS.success : THEME_COLORS.surface,\n color: copied ? 'white' : THEME_COLORS.text,\n border: 'none',\n borderRadius: '6px',\n fontSize: '12px',\n fontWeight: 500,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </motion.button>\n );\n};\n\nexport const JsonViewer = ({ data, collapsible = true, maxHeight }: JsonViewerProps) => {\n return (\n <div\n style={{\n position: 'relative',\n backgroundColor: '#F8FAFC',\n borderRadius: '8px',\n padding: '16px',\n fontFamily: 'monospace',\n fontSize: '13px',\n lineHeight: 1.6,\n overflow: maxHeight ? 'hidden' : undefined,\n maxHeight: maxHeight,\n }}\n >\n <CopyButton data={data} />\n <JsonNode data={data} collapsible={collapsible} maxHeight={maxHeight} />\n </div>\n );\n};\n\nexport default JsonViewer;\n","import React from 'react';\nimport { registerComponent } from '@stackwright/core';\n\nimport { MetricCard } from './components/MetricCard';\nimport { StatusBadge } from './components/StatusBadge';\nimport { StatBar } from './components/StatBar';\nimport { Sparkline } from './components/Sparkline';\nimport { ActivityFeed } from './components/ActivityFeed';\nimport { DashboardGrid } from './components/DashboardGrid';\nimport { DataTable } from './components/DataTable';\nimport { JsonViewer } from './components/JsonViewer';\n\n// Re-export the ComponentProps type for use in casting\nexport type { ComponentProps } from '@stackwright/core';\n\ntype AnyComponent = React.ComponentType<any>;\n\nexport function registerDisplayComponents() {\n // Register components with double-cast to bypass strict type checking\n // The registry accepts any component, but we want to keep specific prop types for internal use\n registerComponent('metric_card', MetricCard as AnyComponent);\n registerComponent('status_badge', StatusBadge as AnyComponent);\n registerComponent('stat_bar', StatBar as AnyComponent);\n registerComponent('sparkline', Sparkline as AnyComponent);\n registerComponent('activity_feed', ActivityFeed as AnyComponent);\n registerComponent('dashboard_grid', DashboardGrid as AnyComponent);\n registerComponent('data_table', DataTable as AnyComponent);\n registerComponent('json_viewer', JsonViewer as AnyComponent);\n}\n"],"mappings":"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","names":["motion","jsx","jsxs","motion","motion","jsx","jsxs","motion","motion","jsx","jsxs","motion","motion","jsx","jsxs","motion","motion","jsx","motion","jsx","jsxs","motion","motion","useState","jsx","jsxs","useState","motion"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackwright-pro/display-components",
3
- "version": "0.1.0",
3
+ "version": "0.1.2-alpha.0",
4
4
  "description": "Dashboard display components for Stackwright Pro",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -23,16 +23,20 @@
23
23
  "peerDependencies": {
24
24
  "@tanstack/react-table": "^8.x",
25
25
  "motion": "^11.x",
26
- "react": "^18.0.0"
26
+ "react": "^18.0.0 || ^19.0.0",
27
+ "react-dom": "^18.0.0 || ^19.0.0"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@tanstack/react-table": "^8.20.0",
31
+ "@testing-library/react": "^16.0.0",
30
32
  "@types/node": "^24.12.0",
31
33
  "@types/react": "^19.0.0",
32
34
  "@types/react-dom": "^19.0.0",
33
35
  "eslint": "^9.0.0",
36
+ "happy-dom": "^16.0.0",
34
37
  "motion": "^11.0.0",
35
38
  "react": "^19.0.0",
39
+ "react-dom": "^19.0.0",
36
40
  "tsup": "^8.0.0",
37
41
  "typescript": "^5.0.0",
38
42
  "vitest": "^2.0.0"
@@ -40,10 +44,15 @@
40
44
  "engines": {
41
45
  "node": ">=18.0.0"
42
46
  },
47
+ "license": "PROPRIETARY",
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
43
51
  "scripts": {
44
52
  "build": "tsup",
45
53
  "dev": "tsup --watch",
46
54
  "test": "vitest",
55
+ "test:coverage": "vitest run --coverage",
47
56
  "typecheck": "tsc --noEmit",
48
57
  "lint": "eslint src"
49
58
  }