pxengine 0.1.12 → 0.1.14

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.
Files changed (186) hide show
  1. package/dist/index.cjs +227 -291
  2. package/dist/index.d.cts +15 -11
  3. package/dist/index.d.ts +15 -11
  4. package/dist/index.js +225 -287
  5. package/dist/registry.json +20 -22
  6. package/package.json +2 -4
  7. package/config/tailwind-preset.js +0 -106
  8. package/src/atoms/AccordionAtom.tsx +0 -44
  9. package/src/atoms/AlertAtom.tsx +0 -48
  10. package/src/atoms/AlertDialogAtom.tsx +0 -66
  11. package/src/atoms/AspectRatioAtom.tsx +0 -27
  12. package/src/atoms/AvatarAtom.tsx +0 -21
  13. package/src/atoms/BadgeAtom.tsx +0 -35
  14. package/src/atoms/BreadcrumbAtom.tsx +0 -36
  15. package/src/atoms/ButtonAtom.tsx +0 -65
  16. package/src/atoms/CalendarAtom.tsx +0 -24
  17. package/src/atoms/CardAtom.tsx +0 -66
  18. package/src/atoms/CarouselAtom.tsx +0 -40
  19. package/src/atoms/ChartAtom.tsx +0 -192
  20. package/src/atoms/CheckboxAtom.tsx +0 -33
  21. package/src/atoms/CollapsibleAtom.tsx +0 -44
  22. package/src/atoms/CommandAtom.tsx +0 -46
  23. package/src/atoms/ContextMenuAtom.tsx +0 -49
  24. package/src/atoms/DialogAtom.tsx +0 -68
  25. package/src/atoms/DrawerAtom.tsx +0 -49
  26. package/src/atoms/DropdownMenuAtom.tsx +0 -49
  27. package/src/atoms/FormInputAtom.tsx +0 -101
  28. package/src/atoms/FormSelectAtom.tsx +0 -110
  29. package/src/atoms/FormTextareaAtom.tsx +0 -93
  30. package/src/atoms/InputAtom.tsx +0 -216
  31. package/src/atoms/InputOTPAtom.tsx +0 -49
  32. package/src/atoms/KbdAtom.tsx +0 -25
  33. package/src/atoms/LabelAtom.tsx +0 -23
  34. package/src/atoms/LayoutAtom.tsx +0 -45
  35. package/src/atoms/PaginationAtom.tsx +0 -49
  36. package/src/atoms/PopoverAtom.tsx +0 -40
  37. package/src/atoms/ProgressAtom.tsx +0 -15
  38. package/src/atoms/RadioGroupAtom.tsx +0 -31
  39. package/src/atoms/RatingAtom.tsx +0 -37
  40. package/src/atoms/ResizableAtom.tsx +0 -51
  41. package/src/atoms/ScrollAreaAtom.tsx +0 -31
  42. package/src/atoms/SeparatorAtom.tsx +0 -16
  43. package/src/atoms/SheetAtom.tsx +0 -72
  44. package/src/atoms/SkeletonAtom.tsx +0 -22
  45. package/src/atoms/SliderAtom.tsx +0 -32
  46. package/src/atoms/SpinnerAtom.tsx +0 -26
  47. package/src/atoms/SwitchAtom.tsx +0 -32
  48. package/src/atoms/TableAtom.tsx +0 -60
  49. package/src/atoms/TabsAtom.tsx +0 -40
  50. package/src/atoms/TextAtom.tsx +0 -36
  51. package/src/atoms/TextareaAtom.tsx +0 -42
  52. package/src/atoms/TimelineAtom.tsx +0 -77
  53. package/src/atoms/ToggleAtom.tsx +0 -36
  54. package/src/atoms/TooltipAtom.tsx +0 -39
  55. package/src/atoms/VideoAtom.tsx +0 -34
  56. package/src/atoms/index.ts +0 -49
  57. package/src/components/index.ts +0 -178
  58. package/src/components/ui/accordion.tsx +0 -56
  59. package/src/components/ui/alert-dialog.tsx +0 -139
  60. package/src/components/ui/alert.tsx +0 -59
  61. package/src/components/ui/aspect-ratio.tsx +0 -5
  62. package/src/components/ui/avatar.tsx +0 -50
  63. package/src/components/ui/badge.tsx +0 -36
  64. package/src/components/ui/breadcrumb.tsx +0 -115
  65. package/src/components/ui/button-group.tsx +0 -83
  66. package/src/components/ui/button.tsx +0 -56
  67. package/src/components/ui/calendar.tsx +0 -213
  68. package/src/components/ui/card.tsx +0 -79
  69. package/src/components/ui/carousel.tsx +0 -260
  70. package/src/components/ui/chart.tsx +0 -367
  71. package/src/components/ui/checkbox.tsx +0 -28
  72. package/src/components/ui/collapsible.tsx +0 -11
  73. package/src/components/ui/command.tsx +0 -153
  74. package/src/components/ui/context-menu.tsx +0 -198
  75. package/src/components/ui/dialog.tsx +0 -122
  76. package/src/components/ui/drawer.tsx +0 -116
  77. package/src/components/ui/dropdown-menu.tsx +0 -200
  78. package/src/components/ui/empty.tsx +0 -104
  79. package/src/components/ui/field.tsx +0 -244
  80. package/src/components/ui/form.tsx +0 -176
  81. package/src/components/ui/hover-card.tsx +0 -27
  82. package/src/components/ui/index.ts +0 -54
  83. package/src/components/ui/input-group.tsx +0 -168
  84. package/src/components/ui/input-otp.tsx +0 -69
  85. package/src/components/ui/input.tsx +0 -22
  86. package/src/components/ui/item.tsx +0 -193
  87. package/src/components/ui/kbd.tsx +0 -28
  88. package/src/components/ui/label.tsx +0 -26
  89. package/src/components/ui/menubar.tsx +0 -254
  90. package/src/components/ui/navigation-menu.tsx +0 -128
  91. package/src/components/ui/pagination.tsx +0 -117
  92. package/src/components/ui/popover.tsx +0 -29
  93. package/src/components/ui/progress.tsx +0 -28
  94. package/src/components/ui/radio-group.tsx +0 -42
  95. package/src/components/ui/resizable.tsx +0 -44
  96. package/src/components/ui/scroll-area.tsx +0 -46
  97. package/src/components/ui/select.tsx +0 -160
  98. package/src/components/ui/separator.tsx +0 -29
  99. package/src/components/ui/sheet.tsx +0 -140
  100. package/src/components/ui/sidebar.tsx +0 -771
  101. package/src/components/ui/skeleton.tsx +0 -15
  102. package/src/components/ui/slider.tsx +0 -26
  103. package/src/components/ui/sonner.tsx +0 -45
  104. package/src/components/ui/spinner.tsx +0 -16
  105. package/src/components/ui/switch.tsx +0 -27
  106. package/src/components/ui/table.tsx +0 -117
  107. package/src/components/ui/tabs.tsx +0 -53
  108. package/src/components/ui/textarea.tsx +0 -22
  109. package/src/components/ui/toggle-group.tsx +0 -61
  110. package/src/components/ui/toggle.tsx +0 -43
  111. package/src/components/ui/tooltip.tsx +0 -30
  112. package/src/hooks/use-mobile.tsx +0 -19
  113. package/src/index.ts +0 -24
  114. package/src/lib/countries.ts +0 -203
  115. package/src/lib/index.ts +0 -2
  116. package/src/lib/utils.ts +0 -15
  117. package/src/lib/validators/index.ts +0 -1
  118. package/src/lib/validators/theme.ts +0 -148
  119. package/src/molecules/creator-discovery/AudienceDemographicsCard/AudienceDemographicsCard.tsx +0 -44
  120. package/src/molecules/creator-discovery/AudienceDemographicsCard/index.ts +0 -1
  121. package/src/molecules/creator-discovery/AudienceMetricCard/AudienceMetricCard.tsx +0 -50
  122. package/src/molecules/creator-discovery/AudienceMetricCard/index.ts +0 -1
  123. package/src/molecules/creator-discovery/BrandAffinityGroup/BrandAffinityGroup.tsx +0 -36
  124. package/src/molecules/creator-discovery/BrandAffinityGroup/index.ts +0 -1
  125. package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.tsx +0 -123
  126. package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.types.ts +0 -13
  127. package/src/molecules/creator-discovery/CampaignSeedCard/index.ts +0 -2
  128. package/src/molecules/creator-discovery/ContentPreviewGallery/ContentPreviewGallery.tsx +0 -41
  129. package/src/molecules/creator-discovery/ContentPreviewGallery/index.ts +0 -1
  130. package/src/molecules/creator-discovery/CreatorActionHeader/CreatorActionHeader.tsx +0 -77
  131. package/src/molecules/creator-discovery/CreatorActionHeader/index.ts +0 -1
  132. package/src/molecules/creator-discovery/CreatorGridCard/CreatorGridCard.tsx +0 -104
  133. package/src/molecules/creator-discovery/CreatorGridCard/index.ts +0 -1
  134. package/src/molecules/creator-discovery/CreatorProfileSummary/CreatorProfileSummary.tsx +0 -65
  135. package/src/molecules/creator-discovery/CreatorProfileSummary/index.ts +0 -1
  136. package/src/molecules/creator-discovery/GrowthChartCard/GrowthChartCard.tsx +0 -58
  137. package/src/molecules/creator-discovery/GrowthChartCard/index.ts +0 -1
  138. package/src/molecules/creator-discovery/MCQCard/MCQCard.tsx +0 -165
  139. package/src/molecules/creator-discovery/MCQCard/MCQCard.types.ts +0 -71
  140. package/src/molecules/creator-discovery/MCQCard/index.ts +0 -2
  141. package/src/molecules/creator-discovery/PlatformIconGroup/PlatformIconGroup.tsx +0 -72
  142. package/src/molecules/creator-discovery/PlatformIconGroup/index.ts +0 -1
  143. package/src/molecules/creator-discovery/SearchSpecCard/CustomFieldRenderers.tsx +0 -334
  144. package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.tsx +0 -111
  145. package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.types.ts +0 -18
  146. package/src/molecules/creator-discovery/SearchSpecCard/index.ts +0 -3
  147. package/src/molecules/creator-discovery/TopPostsGrid/TopPostsGrid.tsx +0 -49
  148. package/src/molecules/creator-discovery/TopPostsGrid/index.ts +0 -1
  149. package/src/molecules/creator-discovery/index.ts +0 -13
  150. package/src/molecules/generic/ActionButton/ActionButton.tsx +0 -137
  151. package/src/molecules/generic/ActionButton/ActionButton.types.ts +0 -68
  152. package/src/molecules/generic/ActionButton/index.ts +0 -2
  153. package/src/molecules/generic/DataGrid/DataGrid.tsx +0 -102
  154. package/src/molecules/generic/DataGrid/index.ts +0 -1
  155. package/src/molecules/generic/EditableField/EditableField.tsx +0 -229
  156. package/src/molecules/generic/EditableField/EditableField.types.ts +0 -73
  157. package/src/molecules/generic/EditableField/index.ts +0 -2
  158. package/src/molecules/generic/EmptyState/EmptyState.tsx +0 -61
  159. package/src/molecules/generic/EmptyState/index.ts +0 -1
  160. package/src/molecules/generic/FileUpload/FileUpload.tsx +0 -62
  161. package/src/molecules/generic/FileUpload/index.ts +0 -1
  162. package/src/molecules/generic/FilterBar/FilterBar.tsx +0 -54
  163. package/src/molecules/generic/FilterBar/index.ts +0 -1
  164. package/src/molecules/generic/FormCard/FormCard.tsx +0 -136
  165. package/src/molecules/generic/FormCard/FormCard.types.ts +0 -93
  166. package/src/molecules/generic/FormCard/index.ts +0 -2
  167. package/src/molecules/generic/LoadingOverlay/LoadingOverlay.tsx +0 -39
  168. package/src/molecules/generic/LoadingOverlay/index.ts +0 -1
  169. package/src/molecules/generic/NotificationList/NotificationList.tsx +0 -80
  170. package/src/molecules/generic/NotificationList/index.ts +0 -1
  171. package/src/molecules/generic/StatsGrid/StatsGrid.tsx +0 -80
  172. package/src/molecules/generic/StatsGrid/index.ts +0 -1
  173. package/src/molecules/generic/StepWizard/StepWizard.tsx +0 -67
  174. package/src/molecules/generic/StepWizard/index.ts +0 -1
  175. package/src/molecules/generic/TagCloud/TagCloud.tsx +0 -32
  176. package/src/molecules/generic/TagCloud/index.ts +0 -1
  177. package/src/molecules/generic/index.ts +0 -12
  178. package/src/molecules/index.ts +0 -2
  179. package/src/render/PXEngineRenderer.tsx +0 -458
  180. package/src/render/index.ts +0 -1
  181. package/src/styles/globals.css +0 -146
  182. package/src/types/atoms.ts +0 -450
  183. package/src/types/common.ts +0 -116
  184. package/src/types/index.ts +0 -3
  185. package/src/types/molecules.ts +0 -279
  186. package/src/types/schema.ts +0 -12
@@ -1,68 +0,0 @@
1
- import { ButtonVariant, ButtonSize } from "@/types/common";
2
-
3
- export interface ActionButtonProps {
4
- /**
5
- * Unique identifier
6
- */
7
- id?: string;
8
-
9
- /**
10
- * Main button label
11
- */
12
- label: string;
13
-
14
- /**
15
- * Secondary label (e.g. for sub-actions or state changes)
16
- */
17
- secondaryLabel?: string;
18
-
19
- /**
20
- * Countdown in seconds. If provided, the button will show a timer.
21
- */
22
- countdown?: number;
23
-
24
- /**
25
- * Whether the auto-proceed is paused
26
- */
27
- isPaused?: boolean;
28
-
29
- /**
30
- * Triggered when the user pauses/resumes the timer
31
- */
32
- onPause?: () => void;
33
-
34
- /**
35
- * Triggered when the user clicks the button or timer expires
36
- */
37
- onProceed: () => void;
38
-
39
- /**
40
- * Button variant (from shadcn)
41
- */
42
- variant?: ButtonVariant;
43
-
44
- /**
45
- * Button size (from shadcn)
46
- */
47
- size?: ButtonSize;
48
-
49
- /**
50
- * Whether the button is disabled
51
- */
52
- disabled?: boolean;
53
-
54
- /**
55
- * Loading state
56
- */
57
- isLoading?: boolean;
58
-
59
- /**
60
- * Custom className
61
- */
62
- className?: string;
63
-
64
- /**
65
- * Whether to show the countdown visually
66
- */
67
- showCountdown?: boolean;
68
- }
@@ -1,2 +0,0 @@
1
- export * from "./ActionButton";
2
- export * from "./ActionButton.types";
@@ -1,102 +0,0 @@
1
- import React from "react";
2
- import {
3
- Table,
4
- TableBody,
5
- TableCell,
6
- TableHead,
7
- TableHeader,
8
- TableRow,
9
- } from "@/components/ui/table";
10
- import { Badge } from "@/components/ui/badge";
11
- import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
12
- import { DataGridMolecule } from "../../../types/molecules";
13
- import { cn } from "@/lib/utils";
14
-
15
- /**
16
- * DataGrid
17
- * A premium table component with typed cells and responsive design.
18
- */
19
- export const DataGrid: React.FC<DataGridMolecule> = ({
20
- columns,
21
- data,
22
- pageSize = 10,
23
- className,
24
- }) => {
25
- const renderCell = (item: any, column: any) => {
26
- const value = item[column.accessorKey];
27
-
28
- switch (column.type) {
29
- case "badge":
30
- return (
31
- <Badge
32
- variant="secondary"
33
- className="bg-purple-50 text-purple-700 border-purple-100"
34
- >
35
- {value}
36
- </Badge>
37
- );
38
- case "avatar":
39
- return (
40
- <div className="flex items-center gap-2">
41
- <Avatar className="h-8 w-8">
42
- <AvatarImage src={value} />
43
- <AvatarFallback>{item.name?.charAt(0) || "U"}</AvatarFallback>
44
- </Avatar>
45
- {item.name && <span className="font-medium">{item.name}</span>}
46
- </div>
47
- );
48
- case "date":
49
- return (
50
- <span className="text-muted-foreground">
51
- {new Date(value).toLocaleDateString()}
52
- </span>
53
- );
54
- case "number":
55
- return (
56
- <span className="font-mono font-medium">
57
- {value.toLocaleString()}
58
- </span>
59
- );
60
- default:
61
- return <span>{value}</span>;
62
- }
63
- };
64
-
65
- return (
66
- <div
67
- className={cn(
68
- "rounded-3xl border border-purple-50 bg-white overflow-hidden shadow-sm",
69
- className,
70
- )}
71
- >
72
- <Table>
73
- <TableHeader className="bg-gray-50/50">
74
- <TableRow>
75
- {columns.map((col) => (
76
- <TableHead
77
- key={col.accessorKey}
78
- className="font-bold text-gray-900 h-12"
79
- >
80
- {col.header}
81
- </TableHead>
82
- ))}
83
- </TableRow>
84
- </TableHeader>
85
- <TableBody>
86
- {data.slice(0, pageSize).map((item, idx) => (
87
- <TableRow
88
- key={idx}
89
- className="hover:bg-purple-50/30 transition-colors border-gray-50"
90
- >
91
- {columns.map((col) => (
92
- <TableCell key={col.accessorKey} className="py-4">
93
- {renderCell(item, col)}
94
- </TableCell>
95
- ))}
96
- </TableRow>
97
- ))}
98
- </TableBody>
99
- </Table>
100
- </div>
101
- );
102
- };
@@ -1 +0,0 @@
1
- export * from "./DataGrid";
@@ -1,229 +0,0 @@
1
- import React, { useState, useEffect, useRef } from "react";
2
- import { EditableFieldProps } from "./EditableField.types";
3
- import { cn } from "@/lib/utils";
4
- import {
5
- Button,
6
- Input,
7
- Label,
8
- Textarea,
9
- Select,
10
- SelectContent,
11
- SelectItem,
12
- SelectTrigger,
13
- SelectValue,
14
- Slider,
15
- } from "@/components";
16
- import { Check, X, Pencil, Loader2 } from "lucide-react";
17
-
18
- /**
19
- * EditableField
20
- *
21
- * A generic field that toggles between display and edit modes.
22
- * Supports various input types and custom rendering.
23
- */
24
- export const EditableField = React.memo<EditableFieldProps>(
25
- ({
26
- label,
27
- value,
28
- type,
29
- isEditing: isEditingProp,
30
- onEdit,
31
- onSave,
32
- onCancel,
33
- isSaving = false,
34
- isChanged = false,
35
- config = {},
36
- className,
37
- renderDisplay,
38
- renderEdit,
39
- }) => {
40
- const [localValue, setLocalValue] = useState(value);
41
- const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);
42
-
43
- // Sync local value when external value changes or editing starts
44
- useEffect(() => {
45
- setLocalValue(value);
46
- }, [value, isEditingProp]);
47
-
48
- // Focus input when editing starts
49
- useEffect(() => {
50
- if (isEditingProp) {
51
- setTimeout(() => inputRef.current?.focus(), 0);
52
- }
53
- }, [isEditingProp]);
54
-
55
- const handleSave = () => {
56
- onSave?.(localValue);
57
- };
58
-
59
- const handleKeyDown = (e: React.KeyboardEvent) => {
60
- if (e.key === "Enter" && !e.shiftKey && type !== "textarea") {
61
- e.preventDefault();
62
- handleSave();
63
- } else if (e.key === "Escape") {
64
- onCancel?.();
65
- }
66
- };
67
-
68
- const renderInput = () => {
69
- if (renderEdit) {
70
- return renderEdit(localValue, setLocalValue);
71
- }
72
-
73
- switch (type) {
74
- case "textarea":
75
- return (
76
- <Textarea
77
- ref={inputRef as React.RefObject<HTMLTextAreaElement>}
78
- value={localValue || ""}
79
- onChange={(e) => setLocalValue(e.target.value)}
80
- onKeyDown={handleKeyDown}
81
- placeholder={config.placeholder}
82
- rows={config.rows || 3}
83
- className="min-h-[80px] resize-none"
84
- />
85
- );
86
- case "select":
87
- return (
88
- <Select
89
- value={localValue?.toString()}
90
- onValueChange={(val) => setLocalValue(val)}
91
- >
92
- <SelectTrigger className="w-full">
93
- <SelectValue
94
- placeholder={config.placeholder || "Select an option"}
95
- />
96
- </SelectTrigger>
97
- <SelectContent>
98
- {config.options?.map((opt: any) => {
99
- const label = typeof opt === "string" ? opt : opt.label;
100
- const val = typeof opt === "string" ? opt : opt.value;
101
- return (
102
- <SelectItem key={val} value={val}>
103
- {label}
104
- </SelectItem>
105
- );
106
- })}
107
- </SelectContent>
108
- </Select>
109
- );
110
- case "slider":
111
- return (
112
- <div className="pt-6 pb-2 px-2">
113
- <Slider
114
- defaultValue={[localValue?.min || 0, localValue?.max || 100]}
115
- max={config.sliderConfig?.max || 100}
116
- min={config.sliderConfig?.min || 0}
117
- step={config.sliderConfig?.step || 1}
118
- onValueChange={([min, max]) => setLocalValue({ min, max })}
119
- />
120
- {config.sliderConfig?.formatValue && (
121
- <div className="mt-2 text-xs text-muted-foreground text-center">
122
- {config.sliderConfig.formatValue(localValue)}
123
- </div>
124
- )}
125
- </div>
126
- );
127
- case "number":
128
- return (
129
- <Input
130
- ref={inputRef as React.RefObject<HTMLInputElement>}
131
- type="number"
132
- value={localValue || ""}
133
- onChange={(e) => setLocalValue(e.target.value)}
134
- onKeyDown={handleKeyDown}
135
- min={config.numberConfig?.min}
136
- max={config.numberConfig?.max}
137
- step={config.numberConfig?.step}
138
- />
139
- );
140
- default:
141
- return (
142
- <Input
143
- ref={inputRef as React.RefObject<HTMLInputElement>}
144
- type="text"
145
- value={localValue || ""}
146
- onChange={(e) => setLocalValue(e.target.value)}
147
- onKeyDown={handleKeyDown}
148
- placeholder={config.placeholder}
149
- />
150
- );
151
- }
152
- };
153
-
154
- const formattedValue = () => {
155
- if (renderDisplay) return renderDisplay(value);
156
-
157
- if (type === "slider") {
158
- return config.sliderConfig?.formatValue
159
- ? config.sliderConfig.formatValue(value)
160
- : `${value?.min} - ${value?.max}`;
161
- }
162
-
163
- if (!value)
164
- return <span className="text-muted-foreground italic">Not set</span>;
165
-
166
- return value.toString();
167
- };
168
-
169
- return (
170
- <div className={cn("group flex flex-col gap-1.5 py-2", className)}>
171
- <div className="flex items-center justify-between">
172
- <Label className="text-xs font-medium text-gray500 uppercase tracking-tight">
173
- {label}
174
- </Label>
175
- {isChanged && !isEditingProp && (
176
- <div
177
- className="w-1.5 h-1.5 rounded-full bg-amber-500"
178
- title="Unsaved changes"
179
- />
180
- )}
181
- </div>
182
-
183
- {isEditingProp ? (
184
- <div className="flex flex-col gap-2">
185
- {renderInput()}
186
- <div className="flex items-center justify-end gap-2">
187
- <Button
188
- size="icon"
189
- variant="outline"
190
- className="h-8 w-8 text-destructive border-destructive/20 hover:bg-destructive/10"
191
- onClick={onCancel}
192
- disabled={isSaving}
193
- >
194
- <X className="h-4 w-4" />
195
- </Button>
196
- <Button
197
- size="icon"
198
- className="h-8 w-8 bg-purple500 hover:bg-purple600 text-white"
199
- onClick={handleSave}
200
- disabled={isSaving}
201
- >
202
- {isSaving ? (
203
- <Loader2 className="h-4 w-4 animate-spin" />
204
- ) : (
205
- <Check className="h-4 w-4" />
206
- )}
207
- </Button>
208
- </div>
209
- </div>
210
- ) : (
211
- <div
212
- className={cn(
213
- "relative flex items-center justify-between rounded-md px-2 py-1.5 transition-all",
214
- "hover:bg-gray-100/50 cursor-pointer border border-transparent hover:border-gray-200",
215
- )}
216
- onClick={onEdit}
217
- >
218
- <div className="text-sm text-gray-900 font-medium truncate flex-1 leading-relaxed">
219
- {formattedValue()}
220
- </div>
221
- <Pencil className="h-3.5 w-3.5 text-gray-400 opacity-0 group-hover:opacity-100 transition-opacity" />
222
- </div>
223
- )}
224
- </div>
225
- );
226
- },
227
- );
228
-
229
- EditableField.displayName = "EditableField";
@@ -1,73 +0,0 @@
1
- import { FieldType, FieldConfig } from "@/types/common";
2
-
3
- export interface EditableFieldProps {
4
- /**
5
- * Unique identifier
6
- */
7
- id?: string;
8
-
9
- /**
10
- * Field label
11
- */
12
- label: string;
13
-
14
- /**
15
- * Field value
16
- */
17
- value: any;
18
-
19
- /**
20
- * Input type (text, textarea, number, slider, etc.)
21
- */
22
- type: FieldType;
23
-
24
- /**
25
- * Current editing state
26
- */
27
- isEditing?: boolean;
28
-
29
- /**
30
- * Triggered when the user wants to start editing
31
- */
32
- onEdit?: () => void;
33
-
34
- /**
35
- * Triggered when the user saves the new value
36
- */
37
- onSave?: (newValue: any) => void;
38
-
39
- /**
40
- * Triggered when the user cancels editing
41
- */
42
- onCancel?: () => void;
43
-
44
- /**
45
- * Loading state during save
46
- */
47
- isSaving?: boolean;
48
-
49
- /**
50
- * Indicates if the value has been changed but not saved
51
- */
52
- isChanged?: boolean;
53
-
54
- /**
55
- * Configuration for the specific field type
56
- */
57
- config?: Partial<FieldConfig>;
58
-
59
- /**
60
- * Custom className for the container
61
- */
62
- className?: string;
63
-
64
- /**
65
- * Custom renderer for the display state
66
- */
67
- renderDisplay?: (value: any) => React.ReactNode;
68
-
69
- /**
70
- * Custom renderer for the edit state
71
- */
72
- renderEdit?: (value: any, onChange: (v: any) => void) => React.ReactNode;
73
- }
@@ -1,2 +0,0 @@
1
- export * from "./EditableField";
2
- export * from "./EditableField.types";
@@ -1,61 +0,0 @@
1
- import React from "react";
2
- import { ButtonAtom } from "../../../atoms/ButtonAtom";
3
- import { TextAtom } from "../../../atoms/TextAtom";
4
- import { EmptyStateMolecule } from "../../../types/molecules";
5
- import { cn } from "@/lib/utils";
6
- import * as Icons from "lucide-react";
7
-
8
- /**
9
- * EmptyState
10
- * A placeholder for empty lists or results.
11
- */
12
- export const EmptyState: React.FC<
13
- EmptyStateMolecule & { onAction?: (action: string) => void }
14
- > = ({
15
- title,
16
- description,
17
- icon,
18
- actionLabel,
19
- action,
20
- className,
21
- onAction,
22
- }) => {
23
- const Icon = icon ? (Icons as any)[icon] : Icons.Search;
24
-
25
- return (
26
- <div
27
- className={cn(
28
- "flex flex-col items-center justify-center p-12 text-center rounded-3xl bg-purple-50/30 border-2 border-dashed border-purple-100",
29
- className,
30
- )}
31
- >
32
- <div className="w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mb-4">
33
- <Icon className="w-8 h-8 text-purple-600" />
34
- </div>
35
- <TextAtom
36
- id="empty-title"
37
- type="text"
38
- content={title}
39
- variant="h3"
40
- className="text-gray-900 mb-2"
41
- />
42
- <TextAtom
43
- id="empty-desc"
44
- type="text"
45
- content={description}
46
- variant="p"
47
- className="text-muted-foreground mb-6 max-w-sm"
48
- />
49
- {actionLabel && action && (
50
- <ButtonAtom
51
- id="empty-action"
52
- type="button"
53
- label={actionLabel}
54
- action={action}
55
- variant="purple"
56
- onAction={onAction}
57
- />
58
- )}
59
- </div>
60
- );
61
- };
@@ -1 +0,0 @@
1
- export * from "./EmptyState";
@@ -1,62 +0,0 @@
1
- import React from "react";
2
- import { Upload } from "lucide-react";
3
- import { FileUploadMolecule } from "../../../types/molecules";
4
- import { cn } from "@/lib/utils";
5
- import { Button } from "@/components/ui/button";
6
-
7
- /**
8
- * FileUpload
9
- * Drag-and-drop file upload zone.
10
- */
11
- export const FileUpload: React.FC<
12
- FileUploadMolecule & { onFilesSelected?: (files: File[]) => void }
13
- > = ({ title, accept, multiple, className, onFilesSelected }) => {
14
- const [isDragging, setIsDragging] = React.useState(false);
15
-
16
- return (
17
- <div
18
- className={cn(
19
- "relative flex flex-col items-center justify-center p-8 border-2 border-dashed rounded-3xl transition-all",
20
- isDragging
21
- ? "border-purple-500 bg-purple-50"
22
- : "border-purple-100 bg-white",
23
- className,
24
- )}
25
- onDragOver={(e) => {
26
- e.preventDefault();
27
- setIsDragging(true);
28
- }}
29
- onDragLeave={() => setIsDragging(false)}
30
- onDrop={(e) => {
31
- e.preventDefault();
32
- setIsDragging(false);
33
- if (e.dataTransfer.files) {
34
- onFilesSelected?.(Array.from(e.dataTransfer.files));
35
- }
36
- }}
37
- >
38
- <div className="w-12 h-12 bg-purple-100 rounded-2xl flex items-center justify-center mb-4 text-purple-600">
39
- <Upload className="w-6 h-6" />
40
- </div>
41
- <h4 className="font-bold text-gray-900 mb-1">{title}</h4>
42
- <p className="text-sm text-muted-foreground mb-6">
43
- Drag and drop or click to browse
44
- </p>
45
- <input
46
- type="file"
47
- multiple={multiple}
48
- accept={accept}
49
- className="absolute inset-0 opacity-0 cursor-pointer"
50
- onChange={(e) =>
51
- e.target.files && onFilesSelected?.(Array.from(e.target.files))
52
- }
53
- />
54
- <Button
55
- variant="outline"
56
- className="rounded-full border-purple-200 text-purple-700 hover:bg-purple-50"
57
- >
58
- Select Files
59
- </Button>
60
- </div>
61
- );
62
- };
@@ -1 +0,0 @@
1
- export * from "./FileUpload";
@@ -1,54 +0,0 @@
1
- import React from "react";
2
- import { Badge } from "@/components/ui/badge";
3
- import { Input } from "@/components/ui/input";
4
- import { Search } from "lucide-react";
5
- import { FilterBarMolecule } from "../../../types/molecules";
6
- import { cn } from "@/lib/utils";
7
-
8
- /**
9
- * FilterBar
10
- * A horizontal bar with active filter chips and search.
11
- */
12
- export const FilterBar: React.FC<
13
- FilterBarMolecule & {
14
- onFilterToggle?: (val: string) => void;
15
- onSearch?: (val: string) => void;
16
- }
17
- > = ({ filters, showSearch = true, className, onFilterToggle, onSearch }) => {
18
- return (
19
- <div
20
- className={cn(
21
- "flex flex-wrap items-center gap-3 p-2 bg-white/50 backdrop-blur-md border border-purple-50 rounded-2xl shadow-sm",
22
- className,
23
- )}
24
- >
25
- {showSearch && (
26
- <div className="relative flex-1 min-w-[200px]">
27
- <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
28
- <Input
29
- placeholder="Search creators..."
30
- className="pl-9 bg-transparent border-none focus-visible:ring-0 placeholder:text-muted-foreground/50"
31
- onChange={(e) => onSearch?.(e.target.value)}
32
- />
33
- </div>
34
- )}
35
- <div className="flex flex-wrap gap-2">
36
- {filters.map((filter) => (
37
- <Badge
38
- key={filter.value}
39
- variant={filter.active ? "default" : "outline"}
40
- className={cn(
41
- "cursor-pointer px-3 py-1 rounded-full transition-all",
42
- filter.active
43
- ? "bg-purple-600 hover:bg-purple-700 border-none"
44
- : "hover:bg-purple-50 hover:border-purple-200",
45
- )}
46
- onClick={() => onFilterToggle?.(filter.value)}
47
- >
48
- {filter.label}
49
- </Badge>
50
- ))}
51
- </div>
52
- </div>
53
- );
54
- };
@@ -1 +0,0 @@
1
- export * from "./FilterBar";