pxengine 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pxengine",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "description": "Shadcn-based UI component library for agent-driven interfaces",
6
6
  "main": "./dist/index.cjs",
@@ -32,12 +32,12 @@
32
32
  "peerDependencies": {
33
33
  "react": "^18.0.0",
34
34
  "react-dom": "^18.0.0",
35
- "tailwindcss": "^3.4.0"
35
+ "tailwindcss": "^3.4.0",
36
+ "@types/react": "^19.0.2",
37
+ "@types/react-dom": "^19.0.2"
36
38
  },
37
39
  "devDependencies": {
38
40
  "@types/node": "^20.19.30",
39
- "@types/react": "^19.0.2",
40
- "@types/react-dom": "^19.0.2",
41
41
  "autoprefixer": "^10.4.23",
42
42
  "eslint": "^8.0.0",
43
43
  "postcss": "^8.5.6",
@@ -11,7 +11,7 @@ import { CardAtomType, UIComponent } from "../types/schema";
11
11
  import { cn } from "@/lib/utils";
12
12
 
13
13
  interface Props extends CardAtomType {
14
- renderComponent: (component: UIComponent) => React.ReactNode;
14
+ renderComponent: (component: UIComponent, index?: number) => React.ReactNode;
15
15
  }
16
16
 
17
17
  /**
@@ -36,7 +36,7 @@ export const CardAtom: React.FC<Props> = ({
36
36
  {(title || description) && (
37
37
  <CardHeader>
38
38
  {title && (
39
- <CardTitle className="text-xl font-bold text-gray-900">
39
+ <CardTitle className="text-xl font-bold text-gray900">
40
40
  {title}
41
41
  </CardTitle>
42
42
  )}
@@ -44,17 +44,17 @@ export const CardAtom: React.FC<Props> = ({
44
44
  </CardHeader>
45
45
  )}
46
46
  <CardContent className="space-y-4">
47
- {children.map((child) => (
48
- <React.Fragment key={child.id}>
49
- {renderComponent(child)}
47
+ {children.map((child, index) => (
48
+ <React.Fragment key={child.id || `card-content-${index}`}>
49
+ {renderComponent(child, index)}
50
50
  </React.Fragment>
51
51
  ))}
52
52
  </CardContent>
53
53
  {footer && footer.length > 0 && (
54
- <CardFooter className="bg-gray-50/50 border-t border-gray-100 flex flex-wrap gap-2 pt-6">
55
- {footer.map((footerChild) => (
56
- <React.Fragment key={footerChild.id}>
57
- {renderComponent(footerChild)}
54
+ <CardFooter className="bg-gray50/50 border-t border-gray200 flex flex-wrap gap-2 pt-6">
55
+ {footer.map((footerChild, index) => (
56
+ <React.Fragment key={footerChild.id || `card-footer-${index}`}>
57
+ {renderComponent(footerChild, index)}
58
58
  </React.Fragment>
59
59
  ))}
60
60
  </CardFooter>
@@ -0,0 +1,97 @@
1
+ import React from "react";
2
+ import {
3
+ Form,
4
+ FormField,
5
+ FormItem,
6
+ FormLabel,
7
+ FormControl,
8
+ FormDescription,
9
+ FormMessage,
10
+ } from "@/components/ui/form";
11
+ import { Input } from "@/components/ui/input";
12
+ import { useForm } from "react-hook-form";
13
+ import { cn } from "@/lib/utils";
14
+
15
+ export interface FormInputAtomType {
16
+ type: "FormInput";
17
+ name: string;
18
+ label?: string;
19
+ placeholder?: string;
20
+ description?: string;
21
+ defaultValue?: string;
22
+ required?: boolean;
23
+ inputType?:
24
+ | "text"
25
+ | "email"
26
+ | "password"
27
+ | "number"
28
+ | "tel"
29
+ | "url"
30
+ | "date"
31
+ | "time";
32
+ className?: string;
33
+ id?: string;
34
+ }
35
+
36
+ interface FormInputAtomProps extends Omit<FormInputAtomType, "type"> {
37
+ renderComponent?: any;
38
+ children?: any;
39
+ }
40
+
41
+ /**
42
+ * FormInputAtom
43
+ *
44
+ * Self-contained form input component that properly wraps FormField, FormItem, FormLabel, and FormControl.
45
+ * This component provides the necessary React Context for form components to work correctly.
46
+ *
47
+ * Features:
48
+ * - Handles all form context requirements internally
49
+ * - Supports various input types (text, email, password, etc.)
50
+ * - Includes validation support through react-hook-form
51
+ * - Schema-safe for dynamic rendering via PXEngineRenderer
52
+ */
53
+ export const FormInputAtom: React.FC<FormInputAtomProps> = ({
54
+ name,
55
+ label,
56
+ placeholder,
57
+ description,
58
+ defaultValue = "",
59
+ required = false,
60
+ inputType = "text",
61
+ className,
62
+ id,
63
+ }) => {
64
+ // Create a local form context for this field
65
+ const form = useForm({
66
+ defaultValues: {
67
+ [name]: defaultValue,
68
+ },
69
+ });
70
+
71
+ return (
72
+ <Form {...form}>
73
+ <FormField
74
+ control={form.control}
75
+ name={name}
76
+ rules={{
77
+ required: required ? `${label || name} is required` : undefined,
78
+ }}
79
+ render={({ field }) => (
80
+ <FormItem className={cn("w-full", className)}>
81
+ {label && <FormLabel>{label}</FormLabel>}
82
+ <FormControl>
83
+ <Input
84
+ type={inputType}
85
+ placeholder={placeholder}
86
+ id={id || `form-input-${name}`}
87
+ {...field}
88
+ />
89
+ </FormControl>
90
+ {description && <FormDescription>{description}</FormDescription>}
91
+ <FormMessage />
92
+ </FormItem>
93
+ )}
94
+ />
95
+ </Form>
96
+ );
97
+ };
@@ -0,0 +1,106 @@
1
+ import React from "react";
2
+ import {
3
+ Form,
4
+ FormField,
5
+ FormItem,
6
+ FormLabel,
7
+ FormControl,
8
+ FormDescription,
9
+ FormMessage,
10
+ } from "@/components/ui/form";
11
+ import {
12
+ Select,
13
+ SelectContent,
14
+ SelectItem,
15
+ SelectTrigger,
16
+ SelectValue,
17
+ } from "@/components/ui/select";
18
+ import { useForm } from "react-hook-form";
19
+ import { cn } from "@/lib/utils";
20
+
21
+ export interface SelectOption {
22
+ value: string;
23
+ label: string;
24
+ }
25
+
26
+ export interface FormSelectAtomType {
27
+ type: "FormSelect";
28
+ name: string;
29
+ label?: string;
30
+ placeholder?: string;
31
+ description?: string;
32
+ defaultValue?: string;
33
+ required?: boolean;
34
+ options: SelectOption[];
35
+ className?: string;
36
+ id?: string;
37
+ }
38
+
39
+ interface FormSelectAtomProps extends Omit<FormSelectAtomType, "type"> {
40
+ renderComponent?: any;
41
+ children?: any;
42
+ }
43
+
44
+ /**
45
+ * FormSelectAtom
46
+ *
47
+ * Self-contained form select component that properly wraps FormField, FormItem, FormLabel, FormControl, and Select.
48
+ * This component provides the necessary React Context for both form and select components to work correctly.
49
+ *
50
+ * Features:
51
+ * - Handles all form and select context requirements internally
52
+ * - Supports dynamic options list
53
+ * - Includes validation support through react-hook-form
54
+ * - Schema-safe for dynamic rendering via PXEngineRenderer
55
+ */
56
+ export const FormSelectAtom: React.FC<FormSelectAtomProps> = ({
57
+ name,
58
+ label,
59
+ placeholder = "Select an option",
60
+ description,
61
+ defaultValue = "",
62
+ required = false,
63
+ options = [],
64
+ className,
65
+ id,
66
+ }) => {
67
+ // Create a local form context for this field
68
+ const form = useForm({
69
+ defaultValues: {
70
+ [name]: defaultValue,
71
+ },
72
+ });
73
+
74
+ return (
75
+ <Form {...form}>
76
+ <FormField
77
+ control={form.control}
78
+ name={name}
79
+ rules={{
80
+ required: required ? `${label || name} is required` : undefined,
81
+ }}
82
+ render={({ field }) => (
83
+ <FormItem className={cn("w-full", className)}>
84
+ {label && <FormLabel>{label}</FormLabel>}
85
+ <Select onValueChange={field.onChange} defaultValue={field.value}>
86
+ <FormControl>
87
+ <SelectTrigger id={id || `form-select-${name}`}>
88
+ <SelectValue placeholder={placeholder} />
89
+ </SelectTrigger>
90
+ </FormControl>
91
+ <SelectContent>
92
+ {options.map((option) => (
93
+ <SelectItem key={option.value} value={option.value}>
94
+ {option.label}
95
+ </SelectItem>
96
+ ))}
97
+ </SelectContent>
98
+ </Select>
99
+ {description && <FormDescription>{description}</FormDescription>}
100
+ <FormMessage />
101
+ </FormItem>
102
+ )}
103
+ />
104
+ </Form>
105
+ );
106
+ };
@@ -0,0 +1,89 @@
1
+ import React from "react";
2
+ import {
3
+ Form,
4
+ FormField,
5
+ FormItem,
6
+ FormLabel,
7
+ FormControl,
8
+ FormDescription,
9
+ FormMessage,
10
+ } from "@/components/ui/form";
11
+ import { Textarea } from "@/components/ui/textarea";
12
+ import { useForm } from "react-hook-form";
13
+ import { cn } from "@/lib/utils";
14
+
15
+ export interface FormTextareaAtomType {
16
+ type: "FormTextarea";
17
+ name: string;
18
+ label?: string;
19
+ placeholder?: string;
20
+ description?: string;
21
+ defaultValue?: string;
22
+ required?: boolean;
23
+ rows?: number;
24
+ className?: string;
25
+ id?: string;
26
+ }
27
+
28
+ interface FormTextareaAtomProps extends Omit<FormTextareaAtomType, "type"> {
29
+ renderComponent?: any;
30
+ children?: any;
31
+ }
32
+
33
+ /**
34
+ * FormTextareaAtom
35
+ *
36
+ * Self-contained form textarea component that properly wraps FormField, FormItem, FormLabel, and FormControl.
37
+ * This component provides the necessary React Context for form components to work correctly.
38
+ *
39
+ * Features:
40
+ * - Handles all form context requirements internally
41
+ * - Supports configurable rows
42
+ * - Includes validation support through react-hook-form
43
+ * - Schema-safe for dynamic rendering via PXEngineRenderer
44
+ */
45
+ export const FormTextareaAtom: React.FC<FormTextareaAtomProps> = ({
46
+ name,
47
+ label,
48
+ placeholder,
49
+ description,
50
+ defaultValue = "",
51
+ required = false,
52
+ rows = 3,
53
+ className,
54
+ id,
55
+ }) => {
56
+ // Create a local form context for this field
57
+ const form = useForm({
58
+ defaultValues: {
59
+ [name]: defaultValue,
60
+ },
61
+ });
62
+
63
+ return (
64
+ <Form {...form}>
65
+ <FormField
66
+ control={form.control}
67
+ name={name}
68
+ rules={{
69
+ required: required ? `${label || name} is required` : undefined,
70
+ }}
71
+ render={({ field }) => (
72
+ <FormItem className={cn("w-full", className)}>
73
+ {label && <FormLabel>{label}</FormLabel>}
74
+ <FormControl>
75
+ <Textarea
76
+ placeholder={placeholder}
77
+ rows={rows}
78
+ id={id || `form-textarea-${name}`}
79
+ {...field}
80
+ />
81
+ </FormControl>
82
+ {description && <FormDescription>{description}</FormDescription>}
83
+ <FormMessage />
84
+ </FormItem>
85
+ )}
86
+ />
87
+ </Form>
88
+ );
89
+ };
@@ -3,7 +3,7 @@ import { LayoutAtomType, UIComponent } from "../types/schema";
3
3
  import { cn } from "@/lib/utils";
4
4
 
5
5
  interface Props extends LayoutAtomType {
6
- renderComponent: (component: UIComponent) => React.ReactNode;
6
+ renderComponent: (component: UIComponent, index?: number) => React.ReactNode;
7
7
  }
8
8
 
9
9
  /**
@@ -35,8 +35,10 @@ export const LayoutAtom: React.FC<Props> = ({
35
35
 
36
36
  return (
37
37
  <div className={classes}>
38
- {children.map((child) => (
39
- <React.Fragment key={child.id}>{renderComponent(child)}</React.Fragment>
38
+ {children.map((child, index) => (
39
+ <React.Fragment key={child.id || `layout-item-${index}`}>
40
+ {renderComponent(child, index)}
41
+ </React.Fragment>
40
42
  ))}
41
43
  </div>
42
44
  );
@@ -12,14 +12,14 @@ export const TextAtom: React.FC<TextAtomType> = ({
12
12
  className,
13
13
  }) => {
14
14
  const baseStyles: Record<string, string> = {
15
- h1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl text-gray-900",
16
- h2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0 text-gray-900",
17
- h3: "scroll-m-20 text-2xl font-semibold tracking-tight text-gray-900",
18
- h4: "scroll-m-20 text-xl font-semibold tracking-tight text-gray-900",
19
- p: "leading-7 [&:not(:first-child)]:mt-6 text-gray-700",
20
- small: "text-sm font-medium leading-none text-gray-600",
15
+ h1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl text-gray900",
16
+ h2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0 text-gray900",
17
+ h3: "scroll-m-20 text-2xl font-semibold tracking-tight text-gray900",
18
+ h4: "scroll-m-20 text-xl font-semibold tracking-tight text-gray900",
19
+ p: "leading-7 [&:not(:first-child)]:mt-6 text-gray700",
20
+ small: "text-sm font-medium leading-none text-gray600",
21
21
  muted: "text-sm text-muted-foreground",
22
- label: "text-[10px] font-bold text-gray-400 uppercase tracking-widest pl-1",
22
+ label: "text-[10px] font-bold text-gray400 uppercase tracking-widest pl-1",
23
23
  };
24
24
 
25
25
  const Component =
@@ -26,3 +26,7 @@ export * from "./SpinnerAtom";
26
26
  export * from "./CalendarAtom";
27
27
  export * from "./PaginationAtom";
28
28
  export * from "./CommandAtom";
29
+ // Form Atoms - self-contained with context wrappers
30
+ export * from "./FormInputAtom";
31
+ export * from "./FormSelectAtom";
32
+ export * from "./FormTextareaAtom";
@@ -0,0 +1,54 @@
1
+ // Auto-generated index file for UI components
2
+ export * from "./accordion";
3
+ export * from "./alert-dialog";
4
+ export * from "./alert";
5
+ export * from "./aspect-ratio";
6
+ export * from "./avatar";
7
+ export * from "./badge";
8
+ export * from "./breadcrumb";
9
+ export * from "./button-group";
10
+ export * from "./button";
11
+ export * from "./calendar";
12
+ export * from "./card";
13
+ export * from "./carousel";
14
+ export * from "./chart";
15
+ export * from "./checkbox";
16
+ export * from "./collapsible";
17
+ export * from "./command";
18
+ export * from "./context-menu";
19
+ export * from "./dialog";
20
+ export * from "./drawer";
21
+ export * from "./dropdown-menu";
22
+ export * from "./empty";
23
+ export * from "./field";
24
+ export * from "./form";
25
+ export * from "./hover-card";
26
+ export * from "./input-group";
27
+ export * from "./input-otp";
28
+ export * from "./input";
29
+ export * from "./item";
30
+ export * from "./kbd";
31
+ export * from "./label";
32
+ export * from "./menubar";
33
+ export * from "./navigation-menu";
34
+ export * from "./pagination";
35
+ export * from "./popover";
36
+ export * from "./progress";
37
+ export * from "./radio-group";
38
+ export * from "./resizable";
39
+ export * from "./scroll-area";
40
+ export * from "./select";
41
+ export * from "./separator";
42
+ export * from "./sheet";
43
+ export * from "./sidebar";
44
+ export * from "./skeleton";
45
+ export * from "./slider";
46
+ export * from "./sonner";
47
+ export * from "./spinner";
48
+ export * from "./switch";
49
+ export * from "./table";
50
+ export * from "./tabs";
51
+ export * from "./textarea";
52
+ export * from "./toggle-group";
53
+ export * from "./toggle";
54
+ export * from "./tooltip";
@@ -113,7 +113,7 @@ export const ActionButton = React.memo<ActionButtonProps>(
113
113
  variant="ghost"
114
114
  size="icon"
115
115
  onClick={onPause}
116
- className="h-10 w-10 rounded-full hover:bg-gray-100 text-gray-500"
116
+ className="h-10 w-10 rounded-full hover:bg-gray200 text-gray600"
117
117
  title={isPaused ? "Resume auto-proceed" : "Pause auto-proceed"}
118
118
  >
119
119
  {isPaused ? (