@nocoo/basalt 2.0.3 → 2.1.2
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 +134 -15
- package/ai/COMPATIBILITY.md +180 -0
- package/ai/INTEGRATION.md +1760 -0
- package/ai/RECIPES.md +161 -0
- package/ai/USAGE.md +99 -0
- package/ai/registry.json +38099 -0
- package/ai/sources.json +10 -0
- package/dist/assets/brand-mark.d.ts +1 -0
- package/dist/assets/brand-mark.js +7 -0
- package/dist/assets/brand-mark.js.map +1 -0
- package/dist/charts/area.d.ts +58 -5
- package/dist/charts/area.js +20 -12
- package/dist/charts/area.js.map +1 -1
- package/dist/charts/bar.d.ts +54 -5
- package/dist/charts/bar.js +16 -10
- package/dist/charts/bar.js.map +1 -1
- package/dist/charts/bullet.d.ts +18 -1
- package/dist/charts/bullet.js +6 -3
- package/dist/charts/bullet.js.map +1 -1
- package/dist/charts/charts.d.ts +58 -5
- package/dist/charts/charts.js +13 -2
- package/dist/charts/charts.js.map +1 -1
- package/dist/charts/config.d.ts +7 -0
- package/dist/charts/config.js +5 -1
- package/dist/charts/config.js.map +1 -1
- package/dist/charts/custom-chart.d.ts +58 -5
- package/dist/charts/custom-chart.js +13 -2
- package/dist/charts/custom-chart.js.map +1 -1
- package/dist/charts/donut.d.ts +18 -1
- package/dist/charts/donut.js +6 -3
- package/dist/charts/donut.js.map +1 -1
- package/dist/charts/frame.d.ts +40 -3
- package/dist/charts/frame.js +55 -28
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/funnel.d.ts +18 -1
- package/dist/charts/funnel.js +5 -1
- package/dist/charts/funnel.js.map +1 -1
- package/dist/charts/gauge.d.ts +18 -1
- package/dist/charts/gauge.js +38 -20
- package/dist/charts/gauge.js.map +1 -1
- package/dist/charts/grouped-bar.d.ts +54 -5
- package/dist/charts/grouped-bar.js +16 -10
- package/dist/charts/grouped-bar.js.map +1 -1
- package/dist/charts/heatmap-calendar.d.ts +61 -0
- package/dist/charts/heatmap-calendar.js +287 -96
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.d.ts +99 -0
- package/dist/charts/heatmap-matrix.js +249 -0
- package/dist/charts/heatmap-matrix.js.map +1 -0
- package/dist/charts/line.d.ts +66 -5
- package/dist/charts/line.js +37 -30
- package/dist/charts/line.js.map +1 -1
- package/dist/charts/palette.d.ts +1 -0
- package/dist/charts/palette.js +7 -1
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts/radar.d.ts +18 -1
- package/dist/charts/radar.js +26 -19
- package/dist/charts/radar.js.map +1 -1
- package/dist/charts/sankey.d.ts +18 -1
- package/dist/charts/sankey.js +4 -1
- package/dist/charts/sankey.js.map +1 -1
- package/dist/charts/series.d.ts +5 -7
- package/dist/charts/series.js.map +1 -1
- package/dist/charts/slot-bar.d.ts +38 -6
- package/dist/charts/slot-bar.js +5 -2
- package/dist/charts/slot-bar.js.map +1 -1
- package/dist/charts/sparkline.d.ts +35 -5
- package/dist/charts/sparkline.js +22 -18
- package/dist/charts/sparkline.js.map +1 -1
- package/dist/charts/stacked-bar.d.ts +58 -5
- package/dist/charts/stacked-bar.js +19 -12
- package/dist/charts/stacked-bar.js.map +1 -1
- package/dist/charts/stat-card.d.ts +51 -1
- package/dist/charts/stat-card.js +66 -39
- package/dist/charts/stat-card.js.map +1 -1
- package/dist/charts/timeline.d.ts +3 -0
- package/dist/charts/timeline.js +4 -3
- package/dist/charts/timeline.js.map +1 -1
- package/dist/charts/timeseries.d.ts +58 -5
- package/dist/charts/timeseries.js +13 -2
- package/dist/charts/timeseries.js.map +1 -1
- package/dist/charts/tooltip.d.ts +57 -0
- package/dist/charts/tooltip.js +119 -2
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.d.ts +117 -2
- package/dist/components/accordion.js +20 -13
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.d.ts +131 -13
- package/dist/components/alert-dialog.js +12 -9
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/app-header.js +18 -17
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.js +15 -14
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/autocomplete.d.ts +4 -0
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/avatar.d.ts +76 -3
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/badge.d.ts +15 -1
- package/dist/components/badge.js +13 -12
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.d.ts +88 -2
- package/dist/components/banner.js +41 -40
- package/dist/components/banner.js.map +1 -1
- package/dist/components/basalt-mark.js +14 -8
- package/dist/components/basalt-mark.js.map +1 -1
- package/dist/components/battery-meter.d.ts +10 -0
- package/dist/components/battery-meter.js +56 -0
- package/dist/components/battery-meter.js.map +1 -0
- package/dist/components/breadcrumbs.d.ts +27 -7
- package/dist/components/breadcrumbs.js +21 -20
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/button.d.ts +48 -2
- package/dist/components/button.js +87 -36
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.d.ts +7 -0
- package/dist/components/chat-bubble.js +14 -13
- package/dist/components/chat-bubble.js.map +1 -1
- package/dist/components/chat-composer.d.ts +7 -3
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/chat-header.d.ts +6 -1
- package/dist/components/chat-header.js +17 -16
- package/dist/components/chat-header.js.map +1 -1
- package/dist/components/chat-inbox.d.ts +7 -2
- package/dist/components/chat-inbox.js.map +1 -1
- package/dist/components/checkbox.js +84 -53
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/clipboard-text.d.ts +13 -2
- package/dist/components/clipboard-text.js +4 -4
- package/dist/components/clipboard-text.js.map +1 -1
- package/dist/components/collapsible.d.ts +58 -15
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/command-palette.d.ts +151 -61
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +1 -1
- package/dist/components/confirm-dialog.js +6 -4
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/context-menu.d.ts +210 -2
- package/dist/components/context-menu.js +7 -4
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.d.ts +40 -2
- package/dist/components/data-table.js +168 -120
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.d.ts +53 -2
- package/dist/components/date-picker.js +387 -219
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.d.ts +7 -1
- package/dist/components/delete-resource.js +22 -18
- package/dist/components/delete-resource.js.map +1 -1
- package/dist/components/description-list.js +16 -15
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog.d.ts +141 -12
- package/dist/components/dialog.js +42 -38
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/dock.d.ts +1 -1
- package/dist/components/dock.js +39 -58
- package/dist/components/dock.js.map +1 -1
- package/dist/components/dropdown-menu.d.ts +229 -15
- package/dist/components/dropdown-menu.js +9 -6
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.d.ts +33 -0
- package/dist/components/editable-nav-item.js +90 -0
- package/dist/components/editable-nav-item.js.map +1 -0
- package/dist/components/empty.d.ts +22 -2
- package/dist/components/empty.js +22 -13
- package/dist/components/empty.js.map +1 -1
- package/dist/components/field.js +31 -30
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-dropzone.d.ts +37 -0
- package/dist/components/file-dropzone.js +103 -0
- package/dist/components/file-dropzone.js.map +1 -0
- package/dist/components/filter-bar.d.ts +34 -0
- package/dist/components/filter-bar.js +52 -0
- package/dist/components/filter-bar.js.map +1 -0
- package/dist/components/flow.js +19 -18
- package/dist/components/flow.js.map +1 -1
- package/dist/components/grid.d.ts +3 -1
- package/dist/components/grid.js.map +1 -1
- package/dist/components/hover-card.d.ts +111 -1
- package/dist/components/hover-card.js +9 -6
- package/dist/components/hover-card.js.map +1 -1
- package/dist/components/icon-picker.d.ts +34 -0
- package/dist/components/icon-picker.js +77 -0
- package/dist/components/icon-picker.js.map +1 -0
- package/dist/components/inline-editable.d.ts +46 -0
- package/dist/components/inline-editable.js +124 -0
- package/dist/components/inline-editable.js.map +1 -0
- package/dist/components/input-area.js +3 -3
- package/dist/components/input-group.js +7 -7
- package/dist/components/input.js +3 -3
- package/dist/components/label.js +18 -17
- package/dist/components/label.js.map +1 -1
- package/dist/components/layer-card.d.ts +10 -2
- package/dist/components/layer-card.js +71 -68
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/loader.d.ts +10 -2
- package/dist/components/loader.js.map +1 -1
- package/dist/components/menu-bar.d.ts +174 -6
- package/dist/components/menu-bar.js +33 -29
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.d.ts +27 -2
- package/dist/components/meter.js.map +1 -1
- package/dist/components/multi-select.d.ts +64 -0
- package/dist/components/multi-select.js +218 -0
- package/dist/components/multi-select.js.map +1 -0
- package/dist/components/navigation-menu.d.ts +88 -5
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/overlay.js +6 -5
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.js +23 -21
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/pagination.js +7 -7
- package/dist/components/popover.d.ts +136 -16
- package/dist/components/popover.js +32 -28
- package/dist/components/popover.js.map +1 -1
- package/dist/components/radio.js +38 -37
- package/dist/components/radio.js.map +1 -1
- package/dist/components/resource-list.d.ts +26 -1
- package/dist/components/resource-list.js +28 -15
- package/dist/components/resource-list.js.map +1 -1
- package/dist/components/responsive-master-detail.d.ts +27 -0
- package/dist/components/responsive-master-detail.js +85 -0
- package/dist/components/responsive-master-detail.js.map +1 -0
- package/dist/components/section-rule.js +23 -22
- package/dist/components/section-rule.js.map +1 -1
- package/dist/components/select.d.ts +27 -3
- package/dist/components/select.js +11 -11
- package/dist/components/select.js.map +1 -1
- package/dist/components/sheet.d.ts +115 -11
- package/dist/components/sheet.js +37 -30
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/sidebar.d.ts +109 -17
- package/dist/components/sidebar.js +112 -111
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.d.ts +22 -2
- package/dist/components/skeleton-line.js.map +1 -1
- package/dist/components/slider.d.ts +61 -1
- package/dist/components/slider.js +31 -15
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stat-strip.js +16 -15
- package/dist/components/stat-strip.js.map +1 -1
- package/dist/components/switch.js +78 -47
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table-of-contents.js +18 -17
- package/dist/components/table-of-contents.js.map +1 -1
- package/dist/components/table-pager.js +20 -19
- package/dist/components/table-pager.js.map +1 -1
- package/dist/components/table.d.ts +9 -3
- package/dist/components/table.js +19 -18
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js +29 -22
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.d.ts +58 -0
- package/dist/components/tag-badge.js +72 -0
- package/dist/components/tag-badge.js.map +1 -0
- package/dist/components/tag-color-picker.d.ts +20 -0
- package/dist/components/tag-color-picker.js +42 -0
- package/dist/components/tag-color-picker.js.map +1 -0
- package/dist/components/text.js +17 -16
- package/dist/components/text.js.map +1 -1
- package/dist/components/toast.d.ts +173 -3
- package/dist/components/toast.js +1 -1
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.d.ts +88 -2
- package/dist/components/toggle-group.js +32 -31
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.d.ts +35 -2
- package/dist/components/toggle.js +12 -11
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/tooltip.d.ts +144 -6
- package/dist/components/tooltip.js +9 -6
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typeahead-field.js +193 -132
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.d.ts +51 -0
- package/dist/components/upload-queue.js +116 -0
- package/dist/components/upload-queue.js.map +1 -0
- package/dist/providers/accent.d.ts +46 -2
- package/dist/providers/accent.js +358 -172
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/link.d.ts +14 -4
- package/dist/providers/link.js.map +1 -1
- package/dist/providers/theme.d.ts +38 -2
- package/dist/providers/theme.js +160 -27
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/base.css +83 -0
- package/dist/styles/standalone.css +699 -120
- package/dist/styles/tailwind.css +21 -7
- package/dist/styles/tokens.css +145 -91
- package/dist/utils/control-surface.d.ts +2 -1
- package/dist/utils/control-surface.js +4 -4
- package/dist/utils/control-surface.js.map +1 -1
- package/dist/utils/selection-indicator.js +2 -2
- package/dist/utils/selection-indicator.js.map +1 -1
- package/package.json +8 -4
package/ai/RECIPES.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Application recipes
|
|
2
|
+
|
|
3
|
+
These complete modules, included in v2.1.0, use only public Basalt imports and React.
|
|
4
|
+
|
|
5
|
+
Load exactly one CSS mode at the application entry: import `@nocoo/basalt/styles/standalone` for a build without Tailwind, or configure the Tailwind source scan and import `@nocoo/basalt/styles/tailwind` as described in INTEGRATION.md. In Next, import CSS in the root layout and import these modules through a `use client` boundary. Mount ThemeProvider once per application; the standalone recipes include their own root provider. Root pages should set body margin to zero.
|
|
6
|
+
|
|
7
|
+
Replace the local adapters with application routing, authentication and data services. Basalt does not own permissions, backend URLs, credentials, or persistence. The exact modules below are extracted from the installed tarball and exercised in A/B/Next consumers.
|
|
8
|
+
|
|
9
|
+
## AppFrame
|
|
10
|
+
|
|
11
|
+
Desktop navigation stays in flow; below 768 CSS pixels it becomes a named drawer. Closing or selecting a section restores the menu control. The media listener is removed on unmount.
|
|
12
|
+
|
|
13
|
+
```tsx compile:recipe-app-frame
|
|
14
|
+
import { AppHeader } from "@nocoo/basalt/components/app-header";
|
|
15
|
+
import { AppMain, AppShell, AppSkipLink } from "@nocoo/basalt/components/app-shell";
|
|
16
|
+
import { Button } from "@nocoo/basalt/components/button";
|
|
17
|
+
import { DialogDescription, DialogTitle } from "@nocoo/basalt/components/dialog";
|
|
18
|
+
import { PageHeader } from "@nocoo/basalt/components/page-header";
|
|
19
|
+
import { Sidebar, SidebarHeader, SidebarItem, SidebarNav, SidebarProvider } from "@nocoo/basalt/components/sidebar";
|
|
20
|
+
import { ThemeToggle } from "@nocoo/basalt/components/theme-toggle";
|
|
21
|
+
import { ThemeProvider } from "@nocoo/basalt/providers/theme";
|
|
22
|
+
import { useEffect, useState } from "react";
|
|
23
|
+
|
|
24
|
+
export default function AppFrameRecipe() {
|
|
25
|
+
const [page, setPage] = useState("Projects");
|
|
26
|
+
const [compact, setCompact] = useState(false);
|
|
27
|
+
const [collapsed, setCollapsed] = useState(true);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const media = matchMedia("(max-width: 767px)");
|
|
30
|
+
const update = () => { setCompact(media.matches); setCollapsed(media.matches); };
|
|
31
|
+
update();
|
|
32
|
+
media.addEventListener("change", update);
|
|
33
|
+
return () => media.removeEventListener("change", update);
|
|
34
|
+
}, []);
|
|
35
|
+
// Replace this local state change with your router's navigation adapter.
|
|
36
|
+
function navigate(next: string) { setPage(next); if (compact) setCollapsed(true); }
|
|
37
|
+
return <ThemeProvider><div style={{ position: "fixed", inset: 0 }}>
|
|
38
|
+
<SidebarProvider collapsed={collapsed} onCollapsedChange={setCollapsed} overlay={compact}>
|
|
39
|
+
<AppShell>
|
|
40
|
+
<AppSkipLink href="#recipe-main">Skip to content</AppSkipLink>
|
|
41
|
+
<Sidebar>
|
|
42
|
+
{compact && <><DialogTitle className="sr-only">Workspace navigation</DialogTitle><DialogDescription className="sr-only">Choose an application section.</DialogDescription></>}
|
|
43
|
+
<SidebarHeader><strong>Atlas workspace</strong></SidebarHeader>
|
|
44
|
+
<SidebarNav aria-label="Workspace navigation">
|
|
45
|
+
{["Projects", "Members", "Activity"].map((name) => <SidebarItem key={name} active={page === name} onClick={() => navigate(name)}>{name}</SidebarItem>)}
|
|
46
|
+
</SidebarNav>
|
|
47
|
+
</Sidebar>
|
|
48
|
+
<AppMain id="recipe-main" tabIndex={-1}>
|
|
49
|
+
<AppHeader leading={<Button size="sm" variant="ghost" aria-label="Toggle navigation" onClick={() => setCollapsed(!collapsed)}>Menu</Button>} actions={<ThemeToggle aria-label="Change theme" />} />
|
|
50
|
+
<div style={{ overflow: "auto", flex: 1, padding: 24 }}>
|
|
51
|
+
<PageHeader title={page} description="A reusable application frame with responsive navigation." />
|
|
52
|
+
<p role="status" className="mt-4 text-sm text-basalt-muted-foreground">Opened {page}. Your application supplies routes and page content.</p>
|
|
53
|
+
</div>
|
|
54
|
+
</AppMain>
|
|
55
|
+
</AppShell>
|
|
56
|
+
</SidebarProvider>
|
|
57
|
+
</div></ThemeProvider>;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Login
|
|
62
|
+
|
|
63
|
+
Native validation and FormData feed an application-supplied async authenticator. Failed authentication retains the form. Repeated submits are blocked and unmount aborts the request; the application owns the success transition and session.
|
|
64
|
+
|
|
65
|
+
```tsx compile:recipe-login
|
|
66
|
+
import { Button } from "@nocoo/basalt/components/button";
|
|
67
|
+
import { Field } from "@nocoo/basalt/components/field";
|
|
68
|
+
import { Input } from "@nocoo/basalt/components/input";
|
|
69
|
+
import { SensitiveInput } from "@nocoo/basalt/components/sensitive-input";
|
|
70
|
+
import { ThemeProvider } from "@nocoo/basalt/providers/theme";
|
|
71
|
+
import { useEffect, useRef, useState } from "react";
|
|
72
|
+
|
|
73
|
+
type Credentials = { email: string; password: string };
|
|
74
|
+
export function LoginForm({ authenticate, onSuccess }: {
|
|
75
|
+
authenticate: (credentials: Credentials, signal: AbortSignal) => Promise<void>;
|
|
76
|
+
onSuccess: (email: string) => void;
|
|
77
|
+
}) {
|
|
78
|
+
const [pending, setPending] = useState(false);
|
|
79
|
+
const [error, setError] = useState("");
|
|
80
|
+
const active = useRef<AbortController | null>(null);
|
|
81
|
+
useEffect(() => () => active.current?.abort(), []);
|
|
82
|
+
return <form aria-label="Sign in" className="space-y-4" onSubmit={async (event) => {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
if (active.current) return;
|
|
85
|
+
const form = new FormData(event.currentTarget);
|
|
86
|
+
const email = String(form.get("email") ?? "");
|
|
87
|
+
const password = String(form.get("password") ?? "");
|
|
88
|
+
const controller = new AbortController();
|
|
89
|
+
active.current = controller; setPending(true); setError("");
|
|
90
|
+
try {
|
|
91
|
+
await authenticate({ email, password }, controller.signal);
|
|
92
|
+
if (!controller.signal.aborted) onSuccess(email);
|
|
93
|
+
} catch (cause) {
|
|
94
|
+
if (!controller.signal.aborted) setError(cause instanceof Error ? cause.message : "Sign in failed. Try again.");
|
|
95
|
+
} finally {
|
|
96
|
+
if (!controller.signal.aborted) { active.current = null; setPending(false); }
|
|
97
|
+
}
|
|
98
|
+
}}>
|
|
99
|
+
<Field label="Email"><Input name="email" type="email" autoComplete="username" required /></Field>
|
|
100
|
+
<Field label="Password"><SensitiveInput name="password" autoComplete="current-password" revealLabel="Show password" hideLabel="Hide password" required /></Field>
|
|
101
|
+
{error && <p role="alert" className="text-sm text-basalt-destructive">{error}</p>}
|
|
102
|
+
<Button className="w-full" type="submit" loading={pending}>Sign in</Button>
|
|
103
|
+
</form>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export default function LoginRecipe() {
|
|
107
|
+
const [account, setAccount] = useState<string | null>(null);
|
|
108
|
+
return <ThemeProvider><main style={{ boxSizing: "border-box", minHeight: "100dvh", display: "grid", placeItems: "center", padding: 16 }}>
|
|
109
|
+
<div className="rounded-basalt-lg border border-basalt-border bg-basalt-card p-6 space-y-4" style={{ boxSizing: "border-box", width: "100%", maxWidth: 380 }}>
|
|
110
|
+
<h1 className="text-xl font-semibold">Welcome to Atlas</h1>
|
|
111
|
+
{account ? <><p role="status">Signed in as {account}</p><Button onClick={() => setAccount(null)}>Sign out</Button></> :
|
|
112
|
+
<><p className="text-sm text-basalt-muted-foreground">Local sign-in demo. Use password demo-pass.</p>
|
|
113
|
+
<LoginForm authenticate={async ({ password }) => { if (password !== "demo-pass") throw new Error("Incorrect demo password."); }} onSuccess={setAccount} /></>}
|
|
114
|
+
</div>
|
|
115
|
+
</main></ThemeProvider>;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## ResourceList
|
|
120
|
+
|
|
121
|
+
Search, an error with retry, formatted status cells, and a confirmation flow use page-owned state. The first local deletion fails so the retry path can be tested. For remote pagination use the existing DataTable manual-state adapter.
|
|
122
|
+
|
|
123
|
+
```tsx compile:recipe-resources
|
|
124
|
+
import { Button } from "@nocoo/basalt/components/button";
|
|
125
|
+
import { DataTable, type DataTableColumn } from "@nocoo/basalt/components/data-table";
|
|
126
|
+
import { DeleteResource } from "@nocoo/basalt/components/delete-resource";
|
|
127
|
+
import { Input } from "@nocoo/basalt/components/input";
|
|
128
|
+
import { ResourceList } from "@nocoo/basalt/components/resource-list";
|
|
129
|
+
import { TagBadge } from "@nocoo/basalt/components/tag-badge";
|
|
130
|
+
import { ThemeProvider } from "@nocoo/basalt/providers/theme";
|
|
131
|
+
import { useRef, useState } from "react";
|
|
132
|
+
|
|
133
|
+
type Project = { id: string; name: string; status: "Active" | "Paused" };
|
|
134
|
+
const initial: Project[] = [
|
|
135
|
+
{ id: "atlas", name: "Atlas", status: "Active" }, { id: "boreal", name: "Boreal", status: "Paused" },
|
|
136
|
+
{ id: "cedar", name: "Cedar", status: "Active" },
|
|
137
|
+
];
|
|
138
|
+
export default function ResourcesRecipe() {
|
|
139
|
+
const [rows, setRows] = useState(initial);
|
|
140
|
+
const [query, setQuery] = useState("");
|
|
141
|
+
const [error, setError] = useState(true);
|
|
142
|
+
const [message, setMessage] = useState("");
|
|
143
|
+
const failDeletion = useRef(true);
|
|
144
|
+
const filtered = rows.filter((row) => row.name.toLowerCase().includes(query.toLowerCase()));
|
|
145
|
+
const columns: DataTableColumn<Project>[] = [
|
|
146
|
+
{ id: "name", header: "Project", accessor: (row) => row.name },
|
|
147
|
+
{ id: "status", header: "Status", accessor: (row) => <TagBadge name={row.status} color={row.status === "Active" ? "success" : "warning"} /> },
|
|
148
|
+
{ id: "actions", header: "Actions", sortable: false, accessor: (row) => <DeleteResource name={row.name} onDelete={async () => {
|
|
149
|
+
if (failDeletion.current) { failDeletion.current = false; throw new Error("Temporary conflict. Retry this deletion."); }
|
|
150
|
+
setRows((current) => current.filter((item) => item.id !== row.id)); setMessage("Deleted " + row.name);
|
|
151
|
+
}} /> },
|
|
152
|
+
];
|
|
153
|
+
return <ThemeProvider><main style={{ padding: 24, maxWidth: 960, margin: "auto" }}>
|
|
154
|
+
<ResourceList title="Projects" description="A complete resource-page composition with local service adapters." data={[]}
|
|
155
|
+
toolbar={<div className="flex flex-wrap gap-3"><Input aria-label="Search projects" placeholder="Search projects…" value={query} onChange={(event) => setQuery(event.target.value)} /><Button variant="outline" onClick={() => { setRows(initial); setQuery(""); setMessage(""); }}>Reset projects</Button></div>}
|
|
156
|
+
footer={<p role="status" className="text-sm text-basalt-muted-foreground">{message || (filtered.length + " projects")}</p>}>
|
|
157
|
+
<DataTable aria-label="Projects" data={filtered} columns={columns} error={error ? "The project service is unavailable." : undefined} onRetry={() => setError(false)} />
|
|
158
|
+
</ResourceList>
|
|
159
|
+
</main></ThemeProvider>;
|
|
160
|
+
}
|
|
161
|
+
```
|
package/ai/USAGE.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Basalt AI & Machine Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how AI code assistants, automated agents, and developers can consume `@nocoo/basalt` (v2.1.2).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Machine Registry Entrypoint
|
|
8
|
+
|
|
9
|
+
The complete, machine-readable component registry and API surface is published within the installed npm package at file:
|
|
10
|
+
`node_modules/@nocoo/basalt/ai/registry.json` (relative package path: `ai/registry.json`).
|
|
11
|
+
*(Note: `ai/registry.json` is a published file within the npm package directory, not an imported JavaScript/ESM export subpath.)*
|
|
12
|
+
Document anchors formatted as `ai/registry.json#<slug>` reference specific catalog entries within the `catalogEntries` array by matching the `slug` property (e.g. `ai/registry.json#button` matches the entry where `slug === "button"`).
|
|
13
|
+
|
|
14
|
+
It contains:
|
|
15
|
+
- **122 Exported Modules** (1 root barrel, components, charts, providers)
|
|
16
|
+
- **111 Ready Catalog Entries** with full API definitions
|
|
17
|
+
- **741 Public Symbols** (395 runtime values, 346 TypeScript types)
|
|
18
|
+
- **Detailed Component API**: Props, types, defaults, descriptions, and function callable signatures (including all `toast()` variants)
|
|
19
|
+
- **Exact Peer Dependency Closures**: Identifies optional peers required per subpath (e.g., Recharts)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Reading Original Component Sources From Installed Package
|
|
24
|
+
|
|
25
|
+
Basalt distributes complete TypeScript source code embedded directly inside the published package artifacts:
|
|
26
|
+
- **Compiled Modules**: Full TypeScript source code is embedded in the `sourcesContent` field of individual sourcemaps under `node_modules/@nocoo/basalt/dist/<subpath>.js.map`.
|
|
27
|
+
- **Pure Re-Export Modules**: Modules without an independent sourcemap (such as pure re-export modules) are preserved verbatim with integrity hashes in `node_modules/@nocoo/basalt/ai/sources.json`. The root entrypoint `@nocoo/basalt` still emits full JavaScript exports in `dist/index.js`.
|
|
28
|
+
|
|
29
|
+
Inspect `ai/registry.json` or the component's catalog metadata to identify the exact package read location and expected SHA-256 integrity hash for each module. Do not attempt to read from unbundled repository source paths or unreleased remote git tags.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. Component Import Conventions
|
|
34
|
+
|
|
35
|
+
### Root Import vs. Granular Subpaths
|
|
36
|
+
Basalt supports both lightweight root imports and tree-shakeable granular subpaths:
|
|
37
|
+
|
|
38
|
+
```tsx compile:usage-import-conventions
|
|
39
|
+
// Root import for standard components
|
|
40
|
+
import { Button, Input, LayerCard, Dialog, Toaster, toast } from "@nocoo/basalt";
|
|
41
|
+
|
|
42
|
+
// Granular subpaths for visualization, calendar pickers, and tables
|
|
43
|
+
import { DatePicker } from "@nocoo/basalt/components/date-picker";
|
|
44
|
+
import { DataTable } from "@nocoo/basalt/components/data-table";
|
|
45
|
+
import { Sparkline } from "@nocoo/basalt/charts/sparkline";
|
|
46
|
+
|
|
47
|
+
export function ImportConventionsDemo() {
|
|
48
|
+
return (
|
|
49
|
+
<div>
|
|
50
|
+
<Button variant="default">Root Button</Button>
|
|
51
|
+
<DatePicker aria-label="Target Date" />
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Optional Peer Dependency Rules
|
|
58
|
+
- **Recharts**: Required ONLY when using chart subpaths (`@nocoo/basalt/charts/*`). Root imports and basic UI do not import Recharts.
|
|
59
|
+
- **DatePicker & DataTable**: Built-in implementations operate standalone without requiring `react-day-picker` or `@tanstack/react-table`.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 4. Styling Setup
|
|
64
|
+
|
|
65
|
+
### Tailwind CSS v4 Contract
|
|
66
|
+
```css
|
|
67
|
+
@import "@nocoo/basalt/styles/tailwind";
|
|
68
|
+
@import "tailwindcss";
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Standalone CSS Contract (No Tailwind)
|
|
72
|
+
```ts
|
|
73
|
+
import "@nocoo/basalt/styles/standalone";
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 5. Toast Notification Architecture
|
|
79
|
+
|
|
80
|
+
Mount a single `<Toaster />` globally at the root of your application (without an id):
|
|
81
|
+
```tsx compile:usage-toast-architecture
|
|
82
|
+
import type React from "react";
|
|
83
|
+
import { Toaster, toast, Button } from "@nocoo/basalt";
|
|
84
|
+
|
|
85
|
+
export function App() {
|
|
86
|
+
return (
|
|
87
|
+
<>
|
|
88
|
+
<Toaster />
|
|
89
|
+
<Button onClick={() => toast.success("Project saved")}>Save</Button>
|
|
90
|
+
</>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 6. Application recipes and palette preferences
|
|
96
|
+
|
|
97
|
+
Read [RECIPES.md](RECIPES.md) for complete AppFrame, Login, and Resources modules. Each module is compiled and exercised from the installed tarball in standalone, Tailwind, and Next.js consumers. These recipes keep authentication, routing, data and network requests in the application.
|
|
98
|
+
|
|
99
|
+
Read [INTEGRATION.md#accent-provider](INTEGRATION.md#accent-provider) for the twelve control accents, optional `paletteOverrides`, and the fixed five-color chart cycle matching the classic candy swatches with its existing gray retained. Check [COMPATIBILITY.md](COMPATIBILITY.md) before migrating old color indices or stored IDs. The catalog at https://basaltui.com/palette provides an application-owned editor with localStorage persistence.
|