@aiready/components 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +240 -0
- package/dist/charts/ForceDirectedGraph.d.ts +40 -0
- package/dist/charts/ForceDirectedGraph.js +294 -0
- package/dist/charts/ForceDirectedGraph.js.map +1 -0
- package/dist/components/badge.d.ts +13 -0
- package/dist/components/badge.js +32 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/button.d.ts +14 -0
- package/dist/components/button.js +52 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/card.d.ts +10 -0
- package/dist/components/card.js +66 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/checkbox.d.ts +8 -0
- package/dist/components/checkbox.js +42 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/container.d.ts +8 -0
- package/dist/components/container.js +36 -0
- package/dist/components/container.js.map +1 -0
- package/dist/components/grid.d.ts +9 -0
- package/dist/components/grid.js +44 -0
- package/dist/components/grid.js.map +1 -0
- package/dist/components/input.d.ts +7 -0
- package/dist/components/input.js +30 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/label.d.ts +10 -0
- package/dist/components/label.js +28 -0
- package/dist/components/label.js.map +1 -0
- package/dist/components/radio-group.d.ts +17 -0
- package/dist/components/radio-group.js +64 -0
- package/dist/components/radio-group.js.map +1 -0
- package/dist/components/select.d.ts +15 -0
- package/dist/components/select.js +45 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/separator.d.ts +9 -0
- package/dist/components/separator.js +30 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/stack.d.ts +11 -0
- package/dist/components/stack.js +60 -0
- package/dist/components/stack.js.map +1 -0
- package/dist/components/switch.d.ts +9 -0
- package/dist/components/switch.js +49 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/textarea.d.ts +7 -0
- package/dist/components/textarea.js +29 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/hooks/useD3.d.ts +6 -0
- package/dist/hooks/useD3.js +35 -0
- package/dist/hooks/useD3.js.map +1 -0
- package/dist/hooks/useDebounce.d.ts +3 -0
- package/dist/hooks/useDebounce.js +19 -0
- package/dist/hooks/useDebounce.js.map +1 -0
- package/dist/hooks/useForceSimulation.d.ts +39 -0
- package/dist/hooks/useForceSimulation.js +107 -0
- package/dist/hooks/useForceSimulation.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +927 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/cn.d.ts +5 -0
- package/dist/utils/cn.js +11 -0
- package/dist/utils/cn.js.map +1 -0
- package/dist/utils/colors.d.ts +19 -0
- package/dist/utils/colors.js +52 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/formatters.d.ts +13 -0
- package/dist/utils/formatters.js +100 -0
- package/dist/utils/formatters.js.map +1 -0
- package/package.json +83 -0
- package/src/charts/ForceDirectedGraph.tsx +356 -0
- package/src/components/badge.tsx +35 -0
- package/src/components/button.tsx +53 -0
- package/src/components/card.tsx +78 -0
- package/src/components/checkbox.tsx +39 -0
- package/src/components/container.tsx +31 -0
- package/src/components/grid.tsx +40 -0
- package/src/components/input.tsx +24 -0
- package/src/components/label.tsx +24 -0
- package/src/components/radio-group.tsx +71 -0
- package/src/components/select.tsx +53 -0
- package/src/components/separator.tsx +29 -0
- package/src/components/stack.tsx +61 -0
- package/src/components/switch.tsx +49 -0
- package/src/components/textarea.tsx +23 -0
- package/src/hooks/useD3.ts +125 -0
- package/src/hooks/useDebounce.ts +44 -0
- package/src/hooks/useForceSimulation.ts +328 -0
- package/src/index.ts +51 -0
- package/src/utils/cn.ts +11 -0
- package/src/utils/colors.ts +58 -0
- package/src/utils/formatters.ts +161 -0
- package/tailwind.config.js +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/components/separator.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACFA,IAAM,SAAA,GAAkB,KAAA,CAAA,UAAA;AAAA,EACtB,CACE,EAAE,SAAA,EAAW,WAAA,GAAc,YAAA,EAAc,aAAa,IAAA,EAAM,GAAG,KAAA,EAAM,EACrE,GAAA,qBAEA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,IAAA,EAAM,aAAa,MAAA,GAAS,WAAA;AAAA,MAC5B,kBAAA,EAAkB,WAAA;AAAA,MAClB,SAAA,EAAW,EAAA;AAAA,QACT,oBAAA;AAAA,QACA,WAAA,KAAgB,eAAe,gBAAA,GAAmB,gBAAA;AAAA,QAClD;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA;AAGV;AACA,SAAA,CAAU,WAAA,GAAc,WAAA","file":"separator.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merges class names using clsx and tailwind-merge\n * @param inputs - Class values to merge\n * @returns Merged class names\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import * as React from 'react';\nimport { cn } from '../utils/cn';\n\nexport interface SeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: 'horizontal' | 'vertical';\n decorative?: boolean;\n}\n\nconst Separator = React.forwardRef<HTMLDivElement, SeparatorProps>(\n (\n { className, orientation = 'horizontal', decorative = true, ...props },\n ref\n ) => (\n <div\n ref={ref}\n role={decorative ? 'none' : 'separator'}\n aria-orientation={orientation}\n className={cn(\n 'shrink-0 bg-border',\n orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',\n className\n )}\n {...props}\n />\n )\n);\nSeparator.displayName = 'Separator';\n\nexport { Separator };"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface StackProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
direction?: 'horizontal' | 'vertical';
|
|
5
|
+
spacing?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
6
|
+
align?: 'start' | 'center' | 'end' | 'stretch';
|
|
7
|
+
justify?: 'start' | 'center' | 'end' | 'between' | 'around';
|
|
8
|
+
}
|
|
9
|
+
declare const Stack: React.ForwardRefExoticComponent<StackProps & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
|
|
11
|
+
export { Stack, type StackProps };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/stack.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var Stack = React.forwardRef(
|
|
11
|
+
({
|
|
12
|
+
className,
|
|
13
|
+
direction = "vertical",
|
|
14
|
+
spacing = "md",
|
|
15
|
+
align = "stretch",
|
|
16
|
+
justify = "start",
|
|
17
|
+
...props
|
|
18
|
+
}, ref) => {
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
ref,
|
|
23
|
+
className: cn(
|
|
24
|
+
"flex",
|
|
25
|
+
{
|
|
26
|
+
"flex-col": direction === "vertical",
|
|
27
|
+
"flex-row": direction === "horizontal"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"gap-1": spacing === "xs",
|
|
31
|
+
"gap-2": spacing === "sm",
|
|
32
|
+
"gap-4": spacing === "md",
|
|
33
|
+
"gap-6": spacing === "lg",
|
|
34
|
+
"gap-8": spacing === "xl"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"items-start": align === "start",
|
|
38
|
+
"items-center": align === "center",
|
|
39
|
+
"items-end": align === "end",
|
|
40
|
+
"items-stretch": align === "stretch"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"justify-start": justify === "start",
|
|
44
|
+
"justify-center": justify === "center",
|
|
45
|
+
"justify-end": justify === "end",
|
|
46
|
+
"justify-between": justify === "between",
|
|
47
|
+
"justify-around": justify === "around"
|
|
48
|
+
},
|
|
49
|
+
className
|
|
50
|
+
),
|
|
51
|
+
...props
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
Stack.displayName = "Stack";
|
|
57
|
+
|
|
58
|
+
export { Stack };
|
|
59
|
+
//# sourceMappingURL=stack.js.map
|
|
60
|
+
//# sourceMappingURL=stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/components/stack.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACAA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EAClB,CACE;AAAA,IACE,SAAA;AAAA,IACA,SAAA,GAAY,UAAA;AAAA,IACZ,OAAA,GAAU,IAAA;AAAA,IACV,KAAA,GAAQ,SAAA;AAAA,IACR,OAAA,GAAU,OAAA;AAAA,IACV,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,MAAA;AAAA,UACA;AAAA,YACE,YAAY,SAAA,KAAc,UAAA;AAAA,YAC1B,YAAY,SAAA,KAAc;AAAA,WAC5B;AAAA,UACA;AAAA,YACE,SAAS,OAAA,KAAY,IAAA;AAAA,YACrB,SAAS,OAAA,KAAY,IAAA;AAAA,YACrB,SAAS,OAAA,KAAY,IAAA;AAAA,YACrB,SAAS,OAAA,KAAY,IAAA;AAAA,YACrB,SAAS,OAAA,KAAY;AAAA,WACvB;AAAA,UACA;AAAA,YACE,eAAe,KAAA,KAAU,OAAA;AAAA,YACzB,gBAAgB,KAAA,KAAU,QAAA;AAAA,YAC1B,aAAa,KAAA,KAAU,KAAA;AAAA,YACvB,iBAAiB,KAAA,KAAU;AAAA,WAC7B;AAAA,UACA;AAAA,YACE,iBAAiB,OAAA,KAAY,OAAA;AAAA,YAC7B,kBAAkB,OAAA,KAAY,QAAA;AAAA,YAC9B,eAAe,OAAA,KAAY,KAAA;AAAA,YAC3B,mBAAmB,OAAA,KAAY,SAAA;AAAA,YAC/B,kBAAkB,OAAA,KAAY;AAAA,WAChC;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"stack.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merges class names using clsx and tailwind-merge\n * @param inputs - Class values to merge\n * @returns Merged class names\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import * as React from 'react';\nimport { cn } from '../utils/cn';\n\nexport interface StackProps extends React.HTMLAttributes<HTMLDivElement> {\n direction?: 'horizontal' | 'vertical';\n spacing?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n align?: 'start' | 'center' | 'end' | 'stretch';\n justify?: 'start' | 'center' | 'end' | 'between' | 'around';\n}\n\nconst Stack = React.forwardRef<HTMLDivElement, StackProps>(\n (\n {\n className,\n direction = 'vertical',\n spacing = 'md',\n align = 'stretch',\n justify = 'start',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'flex',\n {\n 'flex-col': direction === 'vertical',\n 'flex-row': direction === 'horizontal',\n },\n {\n 'gap-1': spacing === 'xs',\n 'gap-2': spacing === 'sm',\n 'gap-4': spacing === 'md',\n 'gap-6': spacing === 'lg',\n 'gap-8': spacing === 'xl',\n },\n {\n 'items-start': align === 'start',\n 'items-center': align === 'center',\n 'items-end': align === 'end',\n 'items-stretch': align === 'stretch',\n },\n {\n 'justify-start': justify === 'start',\n 'justify-center': justify === 'center',\n 'justify-end': justify === 'end',\n 'justify-between': justify === 'between',\n 'justify-around': justify === 'around',\n },\n className\n )}\n {...props}\n />\n );\n }\n);\nStack.displayName = 'Stack';\n\nexport { Stack };"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface SwitchProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
4
|
+
label?: string;
|
|
5
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
6
|
+
}
|
|
7
|
+
declare const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLInputElement>>;
|
|
8
|
+
|
|
9
|
+
export { Switch, type SwitchProps };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/switch.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var Switch = React.forwardRef(
|
|
11
|
+
({ className, label, id, checked, onCheckedChange, onChange, ...props }, ref) => {
|
|
12
|
+
const switchId = id || React.useId();
|
|
13
|
+
const handleChange = (e) => {
|
|
14
|
+
onChange?.(e);
|
|
15
|
+
onCheckedChange?.(e.target.checked);
|
|
16
|
+
};
|
|
17
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
18
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: switchId, className: "relative inline-flex cursor-pointer items-center", children: [
|
|
19
|
+
/* @__PURE__ */ jsx(
|
|
20
|
+
"input",
|
|
21
|
+
{
|
|
22
|
+
type: "checkbox",
|
|
23
|
+
id: switchId,
|
|
24
|
+
ref,
|
|
25
|
+
checked,
|
|
26
|
+
onChange: handleChange,
|
|
27
|
+
className: "peer sr-only",
|
|
28
|
+
...props
|
|
29
|
+
}
|
|
30
|
+
),
|
|
31
|
+
/* @__PURE__ */ jsx(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
className: cn(
|
|
35
|
+
'peer h-6 w-11 rounded-full bg-gray-200 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[""] peer-checked:bg-primary peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-ring peer-focus:ring-offset-2 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
|
|
36
|
+
className
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
] }),
|
|
41
|
+
label && /* @__PURE__ */ jsx("span", { className: "ml-3 text-sm font-medium text-foreground", children: label })
|
|
42
|
+
] });
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
Switch.displayName = "Switch";
|
|
46
|
+
|
|
47
|
+
export { Switch };
|
|
48
|
+
//# sourceMappingURL=switch.js.map
|
|
49
|
+
//# sourceMappingURL=switch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/components/switch.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACDA,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,EAAA,EAAI,OAAA,EAAS,eAAA,EAAiB,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC/E,IAAA,MAAM,QAAA,GAAW,MAAY,KAAA,CAAA,KAAA,EAAM;AAEnC,IAAA,MAAM,YAAA,GAAe,CAAC,CAAA,KAA2C;AAC/D,MAAA,QAAA,GAAW,CAAC,CAAA;AACZ,MAAA,eAAA,GAAkB,CAAA,CAAE,OAAO,OAAO,CAAA;AAAA,IACpC,CAAA;AAEA,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,OAAA,EAAS,QAAA,EAAU,SAAA,EAAU,kDAAA,EAClC,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,UAAA;AAAA,YACL,EAAA,EAAI,QAAA;AAAA,YACJ,GAAA;AAAA,YACA,OAAA;AAAA,YACA,QAAA,EAAU,YAAA;AAAA,YACV,SAAA,EAAU,cAAA;AAAA,YACT,GAAG;AAAA;AAAA,SACN;AAAA,wBACA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,ucAAA;AAAA,cACA;AAAA;AACF;AAAA;AACF,OAAA,EACF,CAAA;AAAA,MACC,KAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4CACb,QAAA,EAAA,KAAA,EACH;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"switch.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merges class names using clsx and tailwind-merge\n * @param inputs - Class values to merge\n * @returns Merged class names\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import * as React from 'react';\nimport { cn } from '../utils/cn';\n\nexport interface SwitchProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label?: string;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nconst Switch = React.forwardRef<HTMLInputElement, SwitchProps>(\n ({ className, label, id, checked, onCheckedChange, onChange, ...props }, ref) => {\n const switchId = id || React.useId();\n \n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.(e);\n onCheckedChange?.(e.target.checked);\n };\n \n return (\n <div className=\"flex items-center\">\n <label htmlFor={switchId} className=\"relative inline-flex cursor-pointer items-center\">\n <input\n type=\"checkbox\"\n id={switchId}\n ref={ref}\n checked={checked}\n onChange={handleChange}\n className=\"peer sr-only\"\n {...props}\n />\n <div\n className={cn(\n 'peer h-6 w-11 rounded-full bg-gray-200 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[\"\"] peer-checked:bg-primary peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-ring peer-focus:ring-offset-2 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',\n className\n )}\n />\n </label>\n {label && (\n <span className=\"ml-3 text-sm font-medium text-foreground\">\n {label}\n </span>\n )}\n </div>\n );\n }\n);\nSwitch.displayName = 'Switch';\n\nexport { Switch };"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
4
|
+
}
|
|
5
|
+
declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
6
|
+
|
|
7
|
+
export { Textarea, type TextareaProps };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/textarea.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var Textarea = React.forwardRef(
|
|
11
|
+
({ className, ...props }, ref) => {
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
"textarea",
|
|
14
|
+
{
|
|
15
|
+
className: cn(
|
|
16
|
+
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
17
|
+
className
|
|
18
|
+
),
|
|
19
|
+
ref,
|
|
20
|
+
...props
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
Textarea.displayName = "Textarea";
|
|
26
|
+
|
|
27
|
+
export { Textarea };
|
|
28
|
+
//# sourceMappingURL=textarea.js.map
|
|
29
|
+
//# sourceMappingURL=textarea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/components/textarea.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACJA,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACrB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAChC,IAAA,uBACE,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,sSAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"textarea.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merges class names using clsx and tailwind-merge\n * @param inputs - Class values to merge\n * @returns Merged class names\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import * as React from 'react';\nimport { cn } from '../utils/cn';\n\nexport interface TextareaProps\n extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n 'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\nTextarea.displayName = 'Textarea';\n\nexport { Textarea };"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as d3 from 'd3';
|
|
2
|
+
|
|
3
|
+
declare function useD3<T extends SVGSVGElement | HTMLDivElement>(renderFn: (selection: d3.Selection<T, unknown, null, undefined>) => void, dependencies?: React.DependencyList): React.RefObject<T | null>;
|
|
4
|
+
declare function useD3WithResize<T extends SVGSVGElement | HTMLDivElement>(renderFn: (selection: d3.Selection<T, unknown, null, undefined>) => void, dependencies?: React.DependencyList): React.RefObject<T | null>;
|
|
5
|
+
|
|
6
|
+
export { useD3, useD3WithResize };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
import * as d3 from 'd3';
|
|
3
|
+
|
|
4
|
+
// src/hooks/useD3.ts
|
|
5
|
+
function useD3(renderFn, dependencies = []) {
|
|
6
|
+
const ref = useRef(null);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (ref.current) {
|
|
9
|
+
const selection = d3.select(ref.current);
|
|
10
|
+
renderFn(selection);
|
|
11
|
+
}
|
|
12
|
+
}, dependencies);
|
|
13
|
+
return ref;
|
|
14
|
+
}
|
|
15
|
+
function useD3WithResize(renderFn, dependencies = []) {
|
|
16
|
+
const ref = useRef(null);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!ref.current) return;
|
|
19
|
+
const selection = d3.select(ref.current);
|
|
20
|
+
const render = () => renderFn(selection);
|
|
21
|
+
render();
|
|
22
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
23
|
+
render();
|
|
24
|
+
});
|
|
25
|
+
resizeObserver.observe(ref.current);
|
|
26
|
+
return () => {
|
|
27
|
+
resizeObserver.disconnect();
|
|
28
|
+
};
|
|
29
|
+
}, dependencies);
|
|
30
|
+
return ref;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { useD3, useD3WithResize };
|
|
34
|
+
//# sourceMappingURL=useD3.js.map
|
|
35
|
+
//# sourceMappingURL=useD3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useD3.ts"],"names":[],"mappings":";;;;AAkDO,SAAS,KAAA,CACd,QAAA,EACA,YAAA,GAAqC,EAAC,EACX;AAC3B,EAAA,MAAM,GAAA,GAAM,OAAiB,IAAI,CAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAI,OAAA,EAAS;AACf,MAAA,MAAM,SAAA,GAAe,EAAA,CAAA,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AACvC,MAAA,QAAA,CAAS,SAAS,CAAA;AAAA,IACpB;AAAA,EAEF,GAAG,YAAY,CAAA;AAEf,EAAA,OAAO,GAAA;AACT;AA6BO,SAAS,eAAA,CACd,QAAA,EACA,YAAA,GAAqC,EAAC,EACX;AAC3B,EAAA,MAAM,GAAA,GAAM,OAAiB,IAAI,CAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAI,OAAA,EAAS;AAElB,IAAA,MAAM,SAAA,GAAe,EAAA,CAAA,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AACvC,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,SAAS,CAAA;AAGvC,IAAA,MAAA,EAAO;AAGP,IAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,MAAM;AAC9C,MAAA,MAAA,EAAO;AAAA,IACT,CAAC,CAAA;AAED,IAAA,cAAA,CAAe,OAAA,CAAQ,IAAI,OAAO,CAAA;AAGlC,IAAA,OAAO,MAAM;AACX,MAAA,cAAA,CAAe,UAAA,EAAW;AAAA,IAC5B,CAAA;AAAA,EAEF,GAAG,YAAY,CAAA;AAEf,EAAA,OAAO,GAAA;AACT","file":"useD3.js","sourcesContent":["import { useEffect, useRef } from 'react';\nimport * as d3 from 'd3';\n\n/**\n * Hook for managing D3 selections with React lifecycle\n * Provides a ref to the SVG/container element and runs a render function when dependencies change\n *\n * @param renderFn - Function that receives the D3 selection and performs rendering\n * @param dependencies - Array of dependencies that trigger re-render\n * @returns Ref to attach to the SVG/container element\n *\n * @example\n * ```tsx\n * function BarChart({ data }: { data: number[] }) {\n * const ref = useD3(\n * (svg) => {\n * const width = 600;\n * const height = 400;\n * const margin = { top: 20, right: 20, bottom: 30, left: 40 };\n *\n * // Clear previous content\n * svg.selectAll('*').remove();\n *\n * // Set up scales\n * const x = d3.scaleBand()\n * .domain(data.map((_, i) => i.toString()))\n * .range([margin.left, width - margin.right])\n * .padding(0.1);\n *\n * const y = d3.scaleLinear()\n * .domain([0, d3.max(data) || 0])\n * .range([height - margin.bottom, margin.top]);\n *\n * // Draw bars\n * svg.selectAll('rect')\n * .data(data)\n * .join('rect')\n * .attr('x', (_, i) => x(i.toString())!)\n * .attr('y', d => y(d))\n * .attr('width', x.bandwidth())\n * .attr('height', d => y(0) - y(d))\n * .attr('fill', 'steelblue');\n * },\n * [data]\n * );\n *\n * return <svg ref={ref} width={600} height={400} />;\n * }\n * ```\n */\nexport function useD3<T extends SVGSVGElement | HTMLDivElement>(\n renderFn: (selection: d3.Selection<T, unknown, null, undefined>) => void,\n dependencies: React.DependencyList = []\n): React.RefObject<T | null> {\n const ref = useRef<T | null>(null);\n\n useEffect(() => {\n if (ref.current) {\n const selection = d3.select(ref.current);\n renderFn(selection);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies);\n\n return ref;\n}\n\n/**\n * Hook for managing D3 selections with automatic resize handling\n * Similar to useD3 but also triggers re-render on window resize\n *\n * @param renderFn - Function that receives the D3 selection and performs rendering\n * @param dependencies - Array of dependencies that trigger re-render\n * @returns Ref to attach to the SVG/container element\n *\n * @example\n * ```tsx\n * function ResponsiveChart({ data }: { data: number[] }) {\n * const ref = useD3WithResize(\n * (svg) => {\n * const container = svg.node();\n * const width = container?.clientWidth || 600;\n * const height = container?.clientHeight || 400;\n *\n * // Render with responsive dimensions\n * // ...\n * },\n * [data]\n * );\n *\n * return <svg ref={ref} style={{ width: '100%', height: '400px' }} />;\n * }\n * ```\n */\nexport function useD3WithResize<T extends SVGSVGElement | HTMLDivElement>(\n renderFn: (selection: d3.Selection<T, unknown, null, undefined>) => void,\n dependencies: React.DependencyList = []\n): React.RefObject<T | null> {\n const ref = useRef<T | null>(null);\n\n useEffect(() => {\n if (!ref.current) return;\n\n const selection = d3.select(ref.current);\n const render = () => renderFn(selection);\n\n // Initial render\n render();\n\n // Set up resize observer\n const resizeObserver = new ResizeObserver(() => {\n render();\n });\n\n resizeObserver.observe(ref.current);\n\n // Cleanup\n return () => {\n resizeObserver.disconnect();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies);\n\n return ref;\n}"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/hooks/useDebounce.ts
|
|
4
|
+
function useDebounce(value, delay = 300) {
|
|
5
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const timer = setTimeout(() => {
|
|
8
|
+
setDebouncedValue(value);
|
|
9
|
+
}, delay);
|
|
10
|
+
return () => {
|
|
11
|
+
clearTimeout(timer);
|
|
12
|
+
};
|
|
13
|
+
}, [value, delay]);
|
|
14
|
+
return debouncedValue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { useDebounce };
|
|
18
|
+
//# sourceMappingURL=useDebounce.js.map
|
|
19
|
+
//# sourceMappingURL=useDebounce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useDebounce.ts"],"names":[],"mappings":";;;AA2BO,SAAS,WAAA,CAAe,KAAA,EAAU,KAAA,GAAgB,GAAA,EAAQ;AAC/D,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAY,KAAK,CAAA;AAE7D,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,MAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,IACzB,GAAG,KAAK,CAAA;AAGR,IAAA,OAAO,MAAM;AACX,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,KAAK,CAAC,CAAA;AAEjB,EAAA,OAAO,cAAA;AACT","file":"useDebounce.js","sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Debounce a value with a specified delay\n * Useful for search inputs, filters, and other frequently changing values\n *\n * @param value - The value to debounce\n * @param delay - Delay in milliseconds (default: 300ms)\n * @returns The debounced value\n *\n * @example\n * ```tsx\n * function SearchInput() {\n * const [searchTerm, setSearchTerm] = useState('');\n * const debouncedSearchTerm = useDebounce(searchTerm, 500);\n *\n * useEffect(() => {\n * // This will only run when user stops typing for 500ms\n * if (debouncedSearchTerm) {\n * performSearch(debouncedSearchTerm);\n * }\n * }, [debouncedSearchTerm]);\n *\n * return <input value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} />;\n * }\n * ```\n */\nexport function useDebounce<T>(value: T, delay: number = 300): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n // Set up the timeout to update debounced value after delay\n const timer = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n // Clean up the timeout if value changes or component unmounts\n return () => {\n clearTimeout(timer);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as d3 from 'd3';
|
|
2
|
+
|
|
3
|
+
interface SimulationNode extends d3.SimulationNodeDatum {
|
|
4
|
+
id: string;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}
|
|
7
|
+
interface SimulationLink extends d3.SimulationLinkDatum<SimulationNode> {
|
|
8
|
+
source: string | SimulationNode;
|
|
9
|
+
target: string | SimulationNode;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
interface ForceSimulationOptions {
|
|
13
|
+
chargeStrength?: number;
|
|
14
|
+
linkDistance?: number;
|
|
15
|
+
linkStrength?: number;
|
|
16
|
+
collisionStrength?: number;
|
|
17
|
+
collisionRadius?: number;
|
|
18
|
+
centerStrength?: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
alphaDecay?: number;
|
|
22
|
+
velocityDecay?: number;
|
|
23
|
+
}
|
|
24
|
+
interface UseForceSimulationReturn {
|
|
25
|
+
nodes: SimulationNode[];
|
|
26
|
+
links: SimulationLink[];
|
|
27
|
+
restart: () => void;
|
|
28
|
+
stop: () => void;
|
|
29
|
+
isRunning: boolean;
|
|
30
|
+
alpha: number;
|
|
31
|
+
}
|
|
32
|
+
declare function useForceSimulation(initialNodes: SimulationNode[], initialLinks: SimulationLink[], options: ForceSimulationOptions): UseForceSimulationReturn;
|
|
33
|
+
declare function useDrag(simulation: d3.Simulation<SimulationNode, any> | null | undefined): {
|
|
34
|
+
onDragStart: (event: any, node: SimulationNode) => void;
|
|
35
|
+
onDrag: (event: any, node: SimulationNode) => void;
|
|
36
|
+
onDragEnd: (event: any, node: SimulationNode) => void;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { type ForceSimulationOptions, type SimulationLink, type SimulationNode, type UseForceSimulationReturn, useDrag, useForceSimulation };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import * as d3 from 'd3';
|
|
3
|
+
|
|
4
|
+
// src/hooks/useForceSimulation.ts
|
|
5
|
+
function useForceSimulation(initialNodes, initialLinks, options) {
|
|
6
|
+
const {
|
|
7
|
+
chargeStrength = -300,
|
|
8
|
+
linkDistance = 100,
|
|
9
|
+
linkStrength = 1,
|
|
10
|
+
collisionStrength = 1,
|
|
11
|
+
collisionRadius = 10,
|
|
12
|
+
centerStrength = 0.1,
|
|
13
|
+
width,
|
|
14
|
+
height,
|
|
15
|
+
alphaDecay = 0.0228,
|
|
16
|
+
velocityDecay = 0.4
|
|
17
|
+
} = options;
|
|
18
|
+
const [nodes, setNodes] = useState(initialNodes);
|
|
19
|
+
const [links, setLinks] = useState(initialLinks);
|
|
20
|
+
const [isRunning, setIsRunning] = useState(false);
|
|
21
|
+
const [alpha, setAlpha] = useState(1);
|
|
22
|
+
const simulationRef = useRef(null);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const nodesCopy = initialNodes.map((node) => ({ ...node }));
|
|
25
|
+
const linksCopy = initialLinks.map((link) => ({ ...link }));
|
|
26
|
+
const simulation = d3.forceSimulation(nodesCopy).force(
|
|
27
|
+
"link",
|
|
28
|
+
d3.forceLink(linksCopy).id((d) => d.id).distance(linkDistance).strength(linkStrength)
|
|
29
|
+
).force("charge", d3.forceManyBody().strength(chargeStrength)).force("center", d3.forceCenter(width / 2, height / 2).strength(centerStrength)).force(
|
|
30
|
+
"collision",
|
|
31
|
+
d3.forceCollide().radius(collisionRadius).strength(collisionStrength)
|
|
32
|
+
).alphaDecay(alphaDecay).velocityDecay(velocityDecay);
|
|
33
|
+
simulationRef.current = simulation;
|
|
34
|
+
simulation.on("tick", () => {
|
|
35
|
+
setNodes([...nodesCopy]);
|
|
36
|
+
setLinks([...linksCopy]);
|
|
37
|
+
setAlpha(simulation.alpha());
|
|
38
|
+
setIsRunning(simulation.alpha() > simulation.alphaMin());
|
|
39
|
+
});
|
|
40
|
+
simulation.on("end", () => {
|
|
41
|
+
setIsRunning(false);
|
|
42
|
+
});
|
|
43
|
+
return () => {
|
|
44
|
+
simulation.stop();
|
|
45
|
+
};
|
|
46
|
+
}, [
|
|
47
|
+
initialNodes,
|
|
48
|
+
initialLinks,
|
|
49
|
+
chargeStrength,
|
|
50
|
+
linkDistance,
|
|
51
|
+
linkStrength,
|
|
52
|
+
collisionStrength,
|
|
53
|
+
collisionRadius,
|
|
54
|
+
centerStrength,
|
|
55
|
+
width,
|
|
56
|
+
height,
|
|
57
|
+
alphaDecay,
|
|
58
|
+
velocityDecay
|
|
59
|
+
]);
|
|
60
|
+
const restart = () => {
|
|
61
|
+
if (simulationRef.current) {
|
|
62
|
+
simulationRef.current.alpha(1).restart();
|
|
63
|
+
setIsRunning(true);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const stop = () => {
|
|
67
|
+
if (simulationRef.current) {
|
|
68
|
+
simulationRef.current.stop();
|
|
69
|
+
setIsRunning(false);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
nodes,
|
|
74
|
+
links,
|
|
75
|
+
restart,
|
|
76
|
+
stop,
|
|
77
|
+
isRunning,
|
|
78
|
+
alpha
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function useDrag(simulation) {
|
|
82
|
+
const dragStarted = (event, node) => {
|
|
83
|
+
if (!simulation) return;
|
|
84
|
+
if (!event.active) simulation.alphaTarget(0.3).restart();
|
|
85
|
+
node.fx = node.x;
|
|
86
|
+
node.fy = node.y;
|
|
87
|
+
};
|
|
88
|
+
const dragged = (event, node) => {
|
|
89
|
+
node.fx = event.x;
|
|
90
|
+
node.fy = event.y;
|
|
91
|
+
};
|
|
92
|
+
const dragEnded = (event, node) => {
|
|
93
|
+
if (!simulation) return;
|
|
94
|
+
if (!event.active) simulation.alphaTarget(0);
|
|
95
|
+
node.fx = null;
|
|
96
|
+
node.fy = null;
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
onDragStart: dragStarted,
|
|
100
|
+
onDrag: dragged,
|
|
101
|
+
onDragEnd: dragEnded
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { useDrag, useForceSimulation };
|
|
106
|
+
//# sourceMappingURL=useForceSimulation.js.map
|
|
107
|
+
//# sourceMappingURL=useForceSimulation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useForceSimulation.ts"],"names":[],"mappings":"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","file":"useForceSimulation.js","sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport * as d3 from 'd3';\n\nexport interface SimulationNode extends d3.SimulationNodeDatum {\n id: string;\n [key: string]: any;\n}\n\nexport interface SimulationLink extends d3.SimulationLinkDatum<SimulationNode> {\n source: string | SimulationNode;\n target: string | SimulationNode;\n [key: string]: any;\n}\n\nexport interface ForceSimulationOptions {\n /**\n * Strength of the charge force (repulsion between nodes)\n * @default -300\n */\n chargeStrength?: number;\n\n /**\n * Distance for links between nodes\n * @default 100\n */\n linkDistance?: number;\n\n /**\n * Strength of the link force\n * @default 1\n */\n linkStrength?: number;\n\n /**\n * Strength of collision detection\n * @default 1\n */\n collisionStrength?: number;\n\n /**\n * Radius for collision detection (node size)\n * @default 10\n */\n collisionRadius?: number;\n\n /**\n * Strength of centering force\n * @default 0.1\n */\n centerStrength?: number;\n\n /**\n * Width of the simulation space\n */\n width: number;\n\n /**\n * Height of the simulation space\n */\n height: number;\n\n /**\n * Alpha decay rate (how quickly the simulation cools down)\n * @default 0.0228\n */\n alphaDecay?: number;\n\n /**\n * Velocity decay (friction)\n * @default 0.4\n */\n velocityDecay?: number;\n}\n\nexport interface UseForceSimulationReturn {\n /**\n * Current nodes with positions\n */\n nodes: SimulationNode[];\n\n /**\n * Current links\n */\n links: SimulationLink[];\n\n /**\n * Restart the simulation\n */\n restart: () => void;\n\n /**\n * Stop the simulation\n */\n stop: () => void;\n\n /**\n * Whether the simulation is currently running\n */\n isRunning: boolean;\n\n /**\n * Current alpha value (simulation heat)\n */\n alpha: number;\n}\n\n/**\n * Hook for managing d3-force simulations\n * Automatically handles simulation lifecycle, tick updates, and cleanup\n *\n * @param initialNodes - Initial nodes for the simulation\n * @param initialLinks - Initial links for the simulation\n * @param options - Configuration options for the force simulation\n * @returns Simulation state and control functions\n *\n * @example\n * ```tsx\n * function NetworkGraph() {\n * const nodes = [\n * { id: 'node1', name: 'Node 1' },\n * { id: 'node2', name: 'Node 2' },\n * { id: 'node3', name: 'Node 3' },\n * ];\n *\n * const links = [\n * { source: 'node1', target: 'node2' },\n * { source: 'node2', target: 'node3' },\n * ];\n *\n * const { nodes: simulatedNodes, links: simulatedLinks, restart } = useForceSimulation(\n * nodes,\n * links,\n * {\n * width: 800,\n * height: 600,\n * chargeStrength: -500,\n * linkDistance: 150,\n * }\n * );\n *\n * return (\n * <svg width={800} height={600}>\n * {simulatedLinks.map((link, i) => (\n * <line\n * key={i}\n * x1={(link.source as SimulationNode).x}\n * y1={(link.source as SimulationNode).y}\n * x2={(link.target as SimulationNode).x}\n * y2={(link.target as SimulationNode).y}\n * stroke=\"#999\"\n * />\n * ))}\n * {simulatedNodes.map((node) => (\n * <circle\n * key={node.id}\n * cx={node.x}\n * cy={node.y}\n * r={10}\n * fill=\"#69b3a2\"\n * />\n * ))}\n * </svg>\n * );\n * }\n * ```\n */\nexport function useForceSimulation(\n initialNodes: SimulationNode[],\n initialLinks: SimulationLink[],\n options: ForceSimulationOptions\n): UseForceSimulationReturn {\n const {\n chargeStrength = -300,\n linkDistance = 100,\n linkStrength = 1,\n collisionStrength = 1,\n collisionRadius = 10,\n centerStrength = 0.1,\n width,\n height,\n alphaDecay = 0.0228,\n velocityDecay = 0.4,\n } = options;\n\n const [nodes, setNodes] = useState<SimulationNode[]>(initialNodes);\n const [links, setLinks] = useState<SimulationLink[]>(initialLinks);\n const [isRunning, setIsRunning] = useState(false);\n const [alpha, setAlpha] = useState(1);\n\n const simulationRef = useRef<d3.Simulation<SimulationNode, SimulationLink> | null>(null);\n\n useEffect(() => {\n // Create a copy of nodes and links to avoid mutating the original data\n const nodesCopy = initialNodes.map((node) => ({ ...node }));\n const linksCopy = initialLinks.map((link) => ({ ...link }));\n\n // Create the simulation\n const simulation = d3\n .forceSimulation<SimulationNode>(nodesCopy)\n .force(\n 'link',\n d3\n .forceLink<SimulationNode, SimulationLink>(linksCopy)\n .id((d) => d.id)\n .distance(linkDistance)\n .strength(linkStrength)\n )\n .force('charge', d3.forceManyBody().strength(chargeStrength))\n .force('center', d3.forceCenter(width / 2, height / 2).strength(centerStrength))\n .force(\n 'collision',\n d3.forceCollide<SimulationNode>().radius(collisionRadius).strength(collisionStrength)\n )\n .alphaDecay(alphaDecay)\n .velocityDecay(velocityDecay);\n\n simulationRef.current = simulation;\n\n // Update state on each tick\n simulation.on('tick', () => {\n setNodes([...nodesCopy]);\n setLinks([...linksCopy]);\n setAlpha(simulation.alpha());\n setIsRunning(simulation.alpha() > simulation.alphaMin());\n });\n\n simulation.on('end', () => {\n setIsRunning(false);\n });\n\n // Cleanup on unmount\n return () => {\n simulation.stop();\n };\n }, [\n initialNodes,\n initialLinks,\n chargeStrength,\n linkDistance,\n linkStrength,\n collisionStrength,\n collisionRadius,\n centerStrength,\n width,\n height,\n alphaDecay,\n velocityDecay,\n ]);\n\n const restart = () => {\n if (simulationRef.current) {\n simulationRef.current.alpha(1).restart();\n setIsRunning(true);\n }\n };\n\n const stop = () => {\n if (simulationRef.current) {\n simulationRef.current.stop();\n setIsRunning(false);\n }\n };\n\n return {\n nodes,\n links,\n restart,\n stop,\n isRunning,\n alpha,\n };\n}\n\n/**\n * Hook for creating a draggable force simulation\n * Provides drag handlers that can be attached to node elements\n *\n * @param simulation - The d3 force simulation instance\n * @returns Drag behavior that can be applied to nodes\n *\n * @example\n * ```tsx\n * function DraggableNetworkGraph() {\n * const simulation = useRef<d3.Simulation<SimulationNode, SimulationLink>>();\n * const drag = useDrag(simulation.current);\n *\n * return (\n * <svg>\n * {nodes.map((node) => (\n * <circle\n * key={node.id}\n * {...drag}\n * cx={node.x}\n * cy={node.y}\n * r={10}\n * />\n * ))}\n * </svg>\n * );\n * }\n * ```\n */\nexport function useDrag(simulation: d3.Simulation<SimulationNode, any> | null | undefined) {\n const dragStarted = (event: any, node: SimulationNode) => {\n if (!simulation) return;\n if (!event.active) simulation.alphaTarget(0.3).restart();\n node.fx = node.x;\n node.fy = node.y;\n };\n\n const dragged = (event: any, node: SimulationNode) => {\n node.fx = event.x;\n node.fy = event.y;\n };\n\n const dragEnded = (event: any, node: SimulationNode) => {\n if (!simulation) return;\n if (!event.active) simulation.alphaTarget(0);\n node.fx = null;\n node.fy = null;\n };\n\n return {\n onDragStart: dragStarted,\n onDrag: dragged,\n onDragEnd: dragEnded,\n };\n}"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { Button, ButtonProps, buttonVariants } from './components/button.js';
|
|
2
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './components/card.js';
|
|
3
|
+
export { Input, InputProps } from './components/input.js';
|
|
4
|
+
export { Label, LabelProps } from './components/label.js';
|
|
5
|
+
export { Badge, BadgeProps, badgeVariants } from './components/badge.js';
|
|
6
|
+
export { Container, ContainerProps } from './components/container.js';
|
|
7
|
+
export { Grid, GridProps } from './components/grid.js';
|
|
8
|
+
export { Stack, StackProps } from './components/stack.js';
|
|
9
|
+
export { Separator, SeparatorProps } from './components/separator.js';
|
|
10
|
+
export { Checkbox, CheckboxProps } from './components/checkbox.js';
|
|
11
|
+
export { RadioGroup, RadioGroupProps, RadioOption } from './components/radio-group.js';
|
|
12
|
+
export { Switch, SwitchProps } from './components/switch.js';
|
|
13
|
+
export { Textarea, TextareaProps } from './components/textarea.js';
|
|
14
|
+
export { Select, SelectOption, SelectProps } from './components/select.js';
|
|
15
|
+
export { cn } from './utils/cn.js';
|
|
16
|
+
export { chartColors, domainColors, getDomainColor, getSeverityColor, hexToRgba, severityColors } from './utils/colors.js';
|
|
17
|
+
export { formatCompactNumber, formatDate, formatDateTime, formatDecimal, formatDuration, formatFileSize, formatMetric, formatNumber, formatPercentage, formatRange, formatRelativeTime } from './utils/formatters.js';
|
|
18
|
+
export { useDebounce } from './hooks/useDebounce.js';
|
|
19
|
+
export { useD3, useD3WithResize } from './hooks/useD3.js';
|
|
20
|
+
export { ForceSimulationOptions, SimulationLink, SimulationNode, UseForceSimulationReturn, useDrag, useForceSimulation } from './hooks/useForceSimulation.js';
|
|
21
|
+
export { ForceDirectedGraph, ForceDirectedGraphProps, GraphLink, GraphNode } from './charts/ForceDirectedGraph.js';
|
|
22
|
+
import 'class-variance-authority/types';
|
|
23
|
+
import 'react';
|
|
24
|
+
import 'class-variance-authority';
|
|
25
|
+
import 'react/jsx-runtime';
|
|
26
|
+
import 'clsx';
|
|
27
|
+
import 'd3';
|