@schandlergarcia/sf-web-components 1.2.6 → 1.2.8
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 +2 -1
- package/scripts/postinstall.mjs +69 -93
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Account.cls +196 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/AccountHistory.cls +25 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Asset.cls +138 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Attachment.cls +35 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Case.cls +111 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Contact.cls +167 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Contract.cls +96 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Domain.cls +29 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Lead.cls +128 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Note.cls +32 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Opportunity.cls +113 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Order.cls +127 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Pricebook2.cls +47 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/PricebookEntry.cls +47 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Product2.cls +91 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/RecordType.cls +35 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Report.cls +47 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/Task.cls +79 -0
- package/src/components/library/.sfdx/tools/sobjects/standardObjects/User.cls +2318 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Account.json +2952 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/AccountHistory.json +875 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Asset.json +1699 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Attachment.json +362 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Case.json +1371 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Contact.json +2309 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Contract.json +1304 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Domain.json +293 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Lead.json +1977 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Note.json +303 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Opportunity.json +1470 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Order.json +1646 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Pricebook2.json +482 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/PricebookEntry.json +433 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Product2.json +1039 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/RecordType.json +2576 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Report.json +486 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/Task.json +4296 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/standardObjects/User.json +30415 -0
- package/src/components/library/.sfdx/tools/soqlMetadata/typeNames.json +78 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Account.d.ts +264 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/AccountHistory.d.ts +44 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Asset.d.ts +240 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Attachment.d.ts +76 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Case.d.ts +172 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Contact.d.ts +264 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Contract.d.ts +188 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Domain.d.ts +52 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Lead.d.ts +252 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Note.d.ts +64 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Opportunity.d.ts +200 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Order.d.ts +260 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Pricebook2.d.ts +64 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/PricebookEntry.d.ts +76 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Product2.d.ts +96 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/RecordType.d.ts +64 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Report.d.ts +80 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/Task.d.ts +184 -0
- package/src/components/library/.sfdx/typings/lwc/sobjects/User.d.ts +752 -0
- package/src/components/library/cards/ActionList.jsx +38 -0
- package/src/components/library/cards/ActivityCard.jsx +56 -0
- package/src/components/library/cards/BaseCard.jsx +109 -0
- package/src/components/library/cards/CalloutCard.jsx +37 -0
- package/src/components/library/cards/ChartCard.jsx +105 -0
- package/src/components/library/cards/FeedPanel.jsx +39 -0
- package/src/components/library/cards/ListCard.jsx +193 -0
- package/src/components/library/cards/MetricCard.jsx +109 -0
- package/src/components/library/cards/MetricsStrip.jsx +78 -0
- package/src/components/library/cards/SectionCard.jsx +83 -0
- package/src/components/library/cards/SemanticMetricCard.jsx +52 -0
- package/src/components/library/cards/SemanticMetricCardWithLoading.jsx +23 -0
- package/src/components/library/cards/SemanticTableCard.jsx +48 -0
- package/src/components/library/cards/SemanticTableCardWithLoading.jsx +22 -0
- package/src/components/library/cards/StatusCard.jsx +220 -0
- package/src/components/library/cards/TableCard.jsx +337 -0
- package/src/components/library/cards/WidgetCard.jsx +90 -0
- package/src/components/library/charts/D3Chart.jsx +109 -0
- package/src/components/library/charts/D3ChartTemplates.jsx +126 -0
- package/src/components/library/charts/GeoMap.jsx +293 -0
- package/src/components/library/chat/ChatBar.jsx +256 -0
- package/src/components/library/chat/ChatInput.jsx +89 -0
- package/src/components/library/chat/ChatMessage.jsx +178 -0
- package/src/components/library/chat/ChatMessageList.jsx +73 -0
- package/src/components/library/chat/ChatPanel.jsx +97 -0
- package/src/components/library/chat/ChatSuggestions.jsx +28 -0
- package/src/components/library/chat/ChatToolCall.jsx +100 -0
- package/src/components/library/chat/ChatTypingIndicator.jsx +23 -0
- package/src/components/library/chat/ChatWelcome.jsx +43 -0
- package/src/components/library/chat/index.jsx +10 -0
- package/src/components/library/chat/useChatState.jsx +130 -0
- package/src/components/library/data/DataModeProvider.jsx +67 -0
- package/src/components/library/data/DataModeToggle.jsx +36 -0
- package/src/components/library/data/chartDataProvider.jsx +61 -0
- package/src/components/library/data/filterUtils.jsx +141 -0
- package/src/components/library/data/useDataSource.jsx +33 -0
- package/src/components/library/data/usePageFilters.jsx +99 -0
- package/src/components/library/filters/FilterBar.jsx +95 -0
- package/src/components/library/filters/SearchFilter.jsx +36 -0
- package/src/components/library/filters/SelectFilter.jsx +55 -0
- package/src/components/library/filters/ToggleFilter.jsx +52 -0
- package/src/components/library/filters/index.jsx +4 -0
- package/src/components/library/forms/FormField.jsx +291 -0
- package/src/components/library/forms/FormModal.jsx +201 -0
- package/src/components/library/forms/FormRenderer.jsx +46 -0
- package/src/components/library/forms/FormSection.jsx +69 -0
- package/src/components/library/forms/index.jsx +5 -0
- package/src/components/library/forms/useFormState.jsx +165 -0
- package/src/components/library/heroui/Accordion.jsx +26 -0
- package/src/components/library/heroui/Alert.jsx +8 -0
- package/src/components/library/heroui/Badge.jsx +8 -0
- package/src/components/library/heroui/Breadcrumbs.jsx +22 -0
- package/src/components/library/heroui/Button.jsx +58 -0
- package/src/components/library/heroui/Card.jsx +8 -0
- package/src/components/library/heroui/Collapsible.jsx +42 -0
- package/src/components/library/heroui/DatePicker.jsx +34 -0
- package/src/components/library/heroui/Dialog.jsx +37 -0
- package/src/components/library/heroui/Drawer.jsx +32 -0
- package/src/components/library/heroui/Dropdown.jsx +28 -0
- package/src/components/library/heroui/Field.jsx +51 -0
- package/src/components/library/heroui/Input.jsx +6 -0
- package/src/components/library/heroui/Kbd.jsx +8 -0
- package/src/components/library/heroui/Meter.jsx +8 -0
- package/src/components/library/heroui/Modal.jsx +32 -0
- package/src/components/library/heroui/Pagination.jsx +8 -0
- package/src/components/library/heroui/Popover.jsx +64 -0
- package/src/components/library/heroui/ProgressBar.jsx +8 -0
- package/src/components/library/heroui/ProgressCircle.jsx +8 -0
- package/src/components/library/heroui/ScrollShadow.jsx +8 -0
- package/src/components/library/heroui/Select.jsx +37 -0
- package/src/components/library/heroui/Separator.jsx +8 -0
- package/src/components/library/heroui/Skeleton.jsx +8 -0
- package/src/components/library/heroui/Tabs.jsx +26 -0
- package/src/components/library/heroui/Toast.jsx +25 -0
- package/src/components/library/heroui/Toggle.jsx +14 -0
- package/src/components/library/heroui/Tooltip.jsx +21 -0
- package/src/components/library/index.jsx +149 -0
- package/src/components/library/layout/PageContainer.jsx +11 -0
- package/src/components/library/skeletons/CardSkeleton.jsx +30 -0
- package/src/components/library/theme/AppThemeProvider.jsx +67 -0
- package/src/components/library/theme/tokens.jsx +72 -0
- package/src/components/library/ui/Alert.jsx +80 -0
- package/src/components/library/ui/Avatar.jsx +44 -0
- package/src/components/library/ui/BreadcrumbExtras.tsx +119 -0
- package/src/components/library/ui/Card.jsx +117 -0
- package/src/components/library/ui/Checkbox.jsx +17 -0
- package/src/components/library/ui/Chip.jsx +38 -0
- package/src/components/library/ui/Collapsible.tsx +31 -0
- package/src/components/library/ui/Container.jsx +56 -0
- package/src/components/library/ui/DatePicker.tsx +34 -0
- package/src/components/library/ui/Dialog.tsx +141 -0
- package/src/components/library/ui/EmptyState.jsx +46 -0
- package/src/components/library/ui/Field.tsx +82 -0
- package/src/components/library/ui/FieldGroup.jsx +17 -0
- package/src/components/library/ui/Label.jsx +22 -0
- package/src/components/library/ui/PaginationExtras.tsx +143 -0
- package/src/components/library/ui/Popover.tsx +39 -0
- package/src/components/library/ui/Select.tsx +113 -0
- package/src/components/library/ui/Spinner.jsx +64 -0
- package/src/components/library/ui/Text.jsx +46 -0
- package/src/components/library/ui/UIButton.jsx +61 -0
- package/src/components/library/ui/UIInput.jsx +21 -0
- package/src/components/workspace/ComponentRegistry.jsx +297 -0
- package/src/templates/pages/Home.tsx.template +6 -5
- package/src/templates/pages/NotFound.tsx.template +2 -2
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
BaseCard,
|
|
4
|
+
MetricCard,
|
|
5
|
+
TableCard,
|
|
6
|
+
ChartCard,
|
|
7
|
+
D3Chart,
|
|
8
|
+
D3ChartTemplates,
|
|
9
|
+
StatusCard,
|
|
10
|
+
ListCard,
|
|
11
|
+
UIButton,
|
|
12
|
+
UIChip,
|
|
13
|
+
UIText
|
|
14
|
+
} from "@/components/library";
|
|
15
|
+
|
|
16
|
+
const BUILTIN_COMPONENTS = {
|
|
17
|
+
NarrativeSummary({ summary, title }) {
|
|
18
|
+
return (
|
|
19
|
+
<div className="text-sm text-slate-600 dark:text-slate-300">
|
|
20
|
+
{title && <div className="mb-1 font-medium text-slate-900 dark:text-slate-50">{title}</div>}
|
|
21
|
+
{summary}
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
MetricsStrip({ metrics = [], title, collapsible = false, collapsed: initialCollapsed = false }) {
|
|
27
|
+
const [collapsed, setCollapsed] = React.useState(initialCollapsed);
|
|
28
|
+
|
|
29
|
+
const items = metrics.length ? metrics : [
|
|
30
|
+
{ label: "Metric A", value: "—", trend: null },
|
|
31
|
+
{ label: "Metric B", value: "—", trend: null },
|
|
32
|
+
{ label: "Metric C", value: "—", trend: null }
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
if (collapsible && collapsed) {
|
|
36
|
+
return (
|
|
37
|
+
<button
|
|
38
|
+
type="button"
|
|
39
|
+
onClick={() => setCollapsed(false)}
|
|
40
|
+
className="flex w-full items-center justify-between rounded-lg border border-slate-200 bg-white px-3 py-2 text-left text-xs text-slate-500 hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400 dark:hover:bg-slate-800"
|
|
41
|
+
>
|
|
42
|
+
<span>{title ?? "Metrics"}: {items.map(m => `${m.label} ${m.value}`).join(" · ")}</span>
|
|
43
|
+
<span>▸</span>
|
|
44
|
+
</button>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div className="rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-800 dark:bg-slate-900">
|
|
50
|
+
{(title || collapsible) && (
|
|
51
|
+
<div className="mb-2 flex items-center justify-between">
|
|
52
|
+
<span className="text-xs font-medium text-slate-500 dark:text-slate-400">{title ?? "Metrics"}</span>
|
|
53
|
+
{collapsible && (
|
|
54
|
+
<button
|
|
55
|
+
type="button"
|
|
56
|
+
onClick={() => setCollapsed(true)}
|
|
57
|
+
className="text-xs text-slate-400 hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300"
|
|
58
|
+
>
|
|
59
|
+
Collapse
|
|
60
|
+
</button>
|
|
61
|
+
)}
|
|
62
|
+
</div>
|
|
63
|
+
)}
|
|
64
|
+
<div className="flex flex-wrap gap-4">
|
|
65
|
+
{items.map((m) => (
|
|
66
|
+
<div key={m.label} className="min-w-[80px]">
|
|
67
|
+
<div className="text-xs text-slate-400 dark:text-slate-500">{m.label}</div>
|
|
68
|
+
<div className="flex items-baseline gap-1.5">
|
|
69
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-200">{m.value}</span>
|
|
70
|
+
{m.trend && (
|
|
71
|
+
<span className={`text-xs ${String(m.trend).startsWith?.("+") || m.trend > 0 ? "text-red-500" : "text-emerald-500"}`}>
|
|
72
|
+
{typeof m.trend === "number" ? (m.trend > 0 ? `+${m.trend}` : m.trend) : m.trend}
|
|
73
|
+
</span>
|
|
74
|
+
)}
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
))}
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
ItemList({ items = [], title, onItemClick }) {
|
|
84
|
+
const [expanded, setExpanded] = React.useState(null);
|
|
85
|
+
if (!items.length) {
|
|
86
|
+
return <div className="text-sm text-slate-500 dark:text-slate-400">No items.</div>;
|
|
87
|
+
}
|
|
88
|
+
return (
|
|
89
|
+
<div className="space-y-2">
|
|
90
|
+
{title && (
|
|
91
|
+
<div className="flex items-center justify-between">
|
|
92
|
+
<span className="text-sm font-medium text-slate-900 dark:text-slate-50">{title}</span>
|
|
93
|
+
<span className="text-xs text-slate-400 dark:text-slate-500">{items.length} items</span>
|
|
94
|
+
</div>
|
|
95
|
+
)}
|
|
96
|
+
<div className="space-y-1.5">
|
|
97
|
+
{items.map((item, idx) => (
|
|
98
|
+
<div key={item.id ?? idx} className="rounded-xl border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-900">
|
|
99
|
+
<button
|
|
100
|
+
type="button"
|
|
101
|
+
onClick={() => {
|
|
102
|
+
setExpanded(expanded === (item.id ?? idx) ? null : (item.id ?? idx));
|
|
103
|
+
onItemClick?.(item);
|
|
104
|
+
}}
|
|
105
|
+
className="flex w-full items-start justify-between gap-3 p-3 text-left"
|
|
106
|
+
>
|
|
107
|
+
<div className="min-w-0 flex-1">
|
|
108
|
+
<div className="flex items-start justify-between gap-2">
|
|
109
|
+
<div className="text-sm font-medium text-slate-900 dark:text-slate-50">
|
|
110
|
+
{item.title ?? item.name ?? `Item ${idx + 1}`}
|
|
111
|
+
</div>
|
|
112
|
+
{item.status && (
|
|
113
|
+
<UIChip tone={item.status === "critical" ? "danger" : item.status === "warning" ? "warning" : "neutral"} className="shrink-0">
|
|
114
|
+
{item.status}
|
|
115
|
+
</UIChip>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
{item.description && (
|
|
119
|
+
<div className="mt-1 text-xs text-slate-500 dark:text-slate-400">{item.description}</div>
|
|
120
|
+
)}
|
|
121
|
+
</div>
|
|
122
|
+
</button>
|
|
123
|
+
{expanded === (item.id ?? idx) && item.actions && (
|
|
124
|
+
<div className="border-t border-slate-100 px-3 py-2 dark:border-slate-800">
|
|
125
|
+
<div className="flex flex-wrap gap-1.5">
|
|
126
|
+
{item.actions.map((action, i) => (
|
|
127
|
+
<button
|
|
128
|
+
key={typeof action === "string" ? action : action.label}
|
|
129
|
+
type="button"
|
|
130
|
+
className={`rounded-md px-2.5 py-1 text-xs font-medium transition-colors ${
|
|
131
|
+
i === 0
|
|
132
|
+
? "bg-slate-900 text-white hover:bg-slate-800 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-200"
|
|
133
|
+
: "bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"
|
|
134
|
+
}`}
|
|
135
|
+
>
|
|
136
|
+
{typeof action === "string" ? action : action.label}
|
|
137
|
+
</button>
|
|
138
|
+
))}
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
)}
|
|
142
|
+
</div>
|
|
143
|
+
))}
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
DataTable({ title, subtitle, columns = [], data = [], rows, searchable = true, sortable = true, paginated = true, pageSize = 5 }) {
|
|
150
|
+
const tableData = data.length ? data : (rows ?? []);
|
|
151
|
+
const cols = columns.length ? columns : [
|
|
152
|
+
{ key: "name", label: "Name" },
|
|
153
|
+
{ key: "status", label: "Status" },
|
|
154
|
+
{ key: "value", label: "Value" }
|
|
155
|
+
];
|
|
156
|
+
return (
|
|
157
|
+
<TableCard
|
|
158
|
+
title={title ?? "Data"}
|
|
159
|
+
subtitle={subtitle}
|
|
160
|
+
columns={cols}
|
|
161
|
+
data={tableData}
|
|
162
|
+
searchable={searchable}
|
|
163
|
+
sortable={sortable}
|
|
164
|
+
paginated={paginated}
|
|
165
|
+
pageSize={pageSize}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
DataChart({ title, subtitle, chartType = "line", data = [], height = 200 }) {
|
|
171
|
+
const series = data.length ? data : Array.from({ length: 12 }, (_, i) => ({ x: i, y: Math.random() * 100 }));
|
|
172
|
+
return (
|
|
173
|
+
<ChartCard
|
|
174
|
+
title={title ?? "Trend"}
|
|
175
|
+
subtitle={subtitle ?? "Data visualization"}
|
|
176
|
+
chartType={chartType}
|
|
177
|
+
height={height}
|
|
178
|
+
chart={
|
|
179
|
+
<D3Chart
|
|
180
|
+
data={series}
|
|
181
|
+
responsive
|
|
182
|
+
height={height}
|
|
183
|
+
ariaLabel={title}
|
|
184
|
+
renderChart={(svg, d, dims, opts) => D3ChartTemplates.lineChart(svg, d, dims, opts)}
|
|
185
|
+
options={{ xKey: "x", yKey: "y", showGrid: true, showAxes: true }}
|
|
186
|
+
/>
|
|
187
|
+
}
|
|
188
|
+
/>
|
|
189
|
+
);
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
MetricCard({ title, label, value, trend, change, changeType, color, icon, description }) {
|
|
193
|
+
return (
|
|
194
|
+
<MetricCard
|
|
195
|
+
title={title ?? label}
|
|
196
|
+
value={value ?? "—"}
|
|
197
|
+
trend={trend}
|
|
198
|
+
change={change}
|
|
199
|
+
changeType={changeType}
|
|
200
|
+
color={color}
|
|
201
|
+
icon={icon}
|
|
202
|
+
description={description}
|
|
203
|
+
/>
|
|
204
|
+
);
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
StatusCard({ title, subtitle, status, items, layout, showProgress, showTimestamp }) {
|
|
208
|
+
return (
|
|
209
|
+
<StatusCard
|
|
210
|
+
title={title}
|
|
211
|
+
subtitle={subtitle}
|
|
212
|
+
status={status}
|
|
213
|
+
items={items}
|
|
214
|
+
layout={layout}
|
|
215
|
+
showProgress={showProgress}
|
|
216
|
+
showTimestamp={showTimestamp}
|
|
217
|
+
/>
|
|
218
|
+
);
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
ActionList({ actions = [], title, onAction }) {
|
|
222
|
+
return (
|
|
223
|
+
<div className="rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-900">
|
|
224
|
+
{title && <div className="mb-3 text-sm font-medium text-slate-900 dark:text-slate-50">{title}</div>}
|
|
225
|
+
<div className="flex flex-wrap gap-2">
|
|
226
|
+
{actions.map((action, i) => (
|
|
227
|
+
<UIButton
|
|
228
|
+
key={i}
|
|
229
|
+
size="sm"
|
|
230
|
+
variant={i === 0 ? "primary" : "outline"}
|
|
231
|
+
onClick={() => onAction?.(action)}
|
|
232
|
+
>
|
|
233
|
+
{typeof action === "string" ? action : action.label}
|
|
234
|
+
</UIButton>
|
|
235
|
+
))}
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
);
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
CalloutCard({ title, message, tone = "neutral" }) {
|
|
242
|
+
const toneClasses = {
|
|
243
|
+
neutral: "border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-950/30 dark:text-slate-200",
|
|
244
|
+
success: "border-emerald-200 bg-emerald-50 text-emerald-800 dark:border-emerald-900/40 dark:bg-emerald-950/20 dark:text-emerald-200",
|
|
245
|
+
warning: "border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900/40 dark:bg-amber-950/20 dark:text-amber-200",
|
|
246
|
+
danger: "border-rose-200 bg-rose-50 text-rose-800 dark:border-rose-900/40 dark:bg-rose-950/20 dark:text-rose-200"
|
|
247
|
+
};
|
|
248
|
+
return (
|
|
249
|
+
<div className={`rounded-xl border p-4 ${toneClasses[tone] ?? toneClasses.neutral}`}>
|
|
250
|
+
{title && <div className="mb-1 text-sm font-semibold">{title}</div>}
|
|
251
|
+
<div className="text-sm">{message}</div>
|
|
252
|
+
</div>
|
|
253
|
+
);
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
Divider() {
|
|
257
|
+
return <div className="h-px bg-slate-200 dark:bg-slate-800" />;
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
Spacer({ size = "md" }) {
|
|
261
|
+
const heights = { sm: "h-2", md: "h-4", lg: "h-6" };
|
|
262
|
+
return <div className={heights[size] ?? heights.md} />;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
let _registry = { ...BUILTIN_COMPONENTS };
|
|
267
|
+
|
|
268
|
+
export function getComponentRegistry() {
|
|
269
|
+
return _registry;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export function registerComponent(type, Component) {
|
|
273
|
+
_registry = { ..._registry, [type]: Component };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export function registerComponents(map) {
|
|
277
|
+
_registry = { ..._registry, ...map };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function renderSchemaComponent(component, index) {
|
|
281
|
+
const registry = getComponentRegistry();
|
|
282
|
+
const Component = registry[component.type];
|
|
283
|
+
if (!Component) {
|
|
284
|
+
return (
|
|
285
|
+
<div key={index} className="rounded-lg border border-dashed border-slate-300 p-3 text-xs text-slate-500 dark:border-slate-700">
|
|
286
|
+
Unknown component: {component.type}
|
|
287
|
+
</div>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
return <Component key={component.id ?? index} {...(component.props ?? {})} />;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function renderSchema(components = []) {
|
|
294
|
+
return components.map((c, i) => renderSchemaComponent(c, i));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export default BUILTIN_COMPONENTS;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import
|
|
2
|
+
import UIInput from '@/components/ui/UIInput';
|
|
3
|
+
import UIButton from '@/components/ui/UIButton';
|
|
3
4
|
import { Search } from "lucide-react";
|
|
4
5
|
|
|
5
6
|
export default function HomePage() {
|
|
@@ -40,12 +41,12 @@ export default function HomePage() {
|
|
|
40
41
|
/>
|
|
41
42
|
</div>
|
|
42
43
|
<div className="flex gap-3 justify-center">
|
|
43
|
-
<
|
|
44
|
+
<UIButton onClick={handleSearch} variant="primary">
|
|
44
45
|
Search
|
|
45
|
-
</
|
|
46
|
-
<
|
|
46
|
+
</UIButton>
|
|
47
|
+
<UIButton onClick={() => console.log("Browse All")} variant="secondary">
|
|
47
48
|
Browse All
|
|
48
|
-
</
|
|
49
|
+
</UIButton>
|
|
49
50
|
</div>
|
|
50
51
|
</div>
|
|
51
52
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useNavigate } from "react-router";
|
|
2
|
-
import
|
|
2
|
+
import UIButton from '@/components/ui/UIButton';
|
|
3
3
|
|
|
4
4
|
export default function NotFound() {
|
|
5
5
|
const navigate = useNavigate();
|
|
@@ -12,7 +12,7 @@ export default function NotFound() {
|
|
|
12
12
|
<p className="text-lg text-slate-600 dark:text-slate-400 mb-8">
|
|
13
13
|
The page you're looking for doesn't exist.
|
|
14
14
|
</p>
|
|
15
|
-
<
|
|
15
|
+
<UIButton onClick={() => navigate("/")}>Go Home</UIButton>
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
18
|
);
|