@cfast/ui 0.0.1

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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +727 -0
  3. package/dist/chunk-755IRYDN.js +941 -0
  4. package/dist/chunk-7SNK37GF.js +418 -0
  5. package/dist/chunk-ASMYTWTR.js +356 -0
  6. package/dist/chunk-B2XXH5V4.js +66 -0
  7. package/dist/chunk-BQMXYYEV.js +348 -0
  8. package/dist/chunk-DTKBXCTU.js +211 -0
  9. package/dist/chunk-EYIBATYR.js +33 -0
  10. package/dist/chunk-FPZAQ2YQ.js +474 -0
  11. package/dist/chunk-G2OU4BYC.js +205 -0
  12. package/dist/chunk-JEGEIQ3R.js +925 -0
  13. package/dist/chunk-JUNLQJ6H.js +1013 -0
  14. package/dist/chunk-NRGMW3JA.js +906 -0
  15. package/dist/chunk-Q6FPL2OJ.js +1086 -0
  16. package/dist/chunk-QHWAGKNW.js +456 -0
  17. package/dist/chunk-QZT62CGJ.js +924 -0
  18. package/dist/chunk-RDTUEOLK.js +486 -0
  19. package/dist/chunk-RESL4IJJ.js +112 -0
  20. package/dist/chunk-UDCWQUTR.js +221 -0
  21. package/dist/chunk-UE7PZOIJ.js +11 -0
  22. package/dist/chunk-UTZTHGNE.js +84 -0
  23. package/dist/chunk-UVRXMOX5.js +439 -0
  24. package/dist/chunk-XFD3N2D4.js +161 -0
  25. package/dist/client-CXIHCQtA.d.ts +274 -0
  26. package/dist/client.d.ts +617 -0
  27. package/dist/client.js +54 -0
  28. package/dist/index.d.ts +415 -0
  29. package/dist/index.js +296 -0
  30. package/dist/joy.d.ts +199 -0
  31. package/dist/joy.js +1150 -0
  32. package/dist/permission-gate-DVmY42oz.d.ts +1269 -0
  33. package/dist/permission-gate-apt9T9Mu.d.ts +1256 -0
  34. package/dist/types-1bAiH2uK.d.ts +392 -0
  35. package/dist/types-BX6u5sAd.d.ts +403 -0
  36. package/dist/types-BpdY7w5l.d.ts +403 -0
  37. package/dist/types-BrepeVp8.d.ts +403 -0
  38. package/dist/types-BvAqMZhn.d.ts +403 -0
  39. package/dist/types-C74nSscq.d.ts +403 -0
  40. package/dist/types-DD1Cpx8F.d.ts +403 -0
  41. package/dist/types-DHUhQwJn.d.ts +403 -0
  42. package/dist/types-DZSJNt_M.d.ts +392 -0
  43. package/dist/types-DaaJiIjW.d.ts +391 -0
  44. package/dist/types-LUpWJwps.d.ts +403 -0
  45. package/dist/types-a7zVU6WE.d.ts +394 -0
  46. package/dist/types-biJTHMcH.d.ts +403 -0
  47. package/dist/types-ow_qSEYJ.d.ts +392 -0
  48. package/dist/types-wnLasZaB.d.ts +1234 -0
  49. package/package.json +88 -0
@@ -0,0 +1,415 @@
1
+ export { ActionButton, AvatarWithInitials, BulkActionBar, ConfirmProvider, DataTable, DetailView, DropZone, FileList, FilterBar, FormStatus, ImagePreview, ImpersonationBanner, ListView, RoleBadge, UIPluginProvider, createUIPlugin, getInitials, useActionToast, useColumnInference, useComponent, useConfirm, useToast, useUIPlugin } from './client.js';
2
+ import { D as DateFieldProps, B as BooleanFieldProps, N as NumberFieldProps, T as TextFieldProps, E as EmailFieldProps, U as UrlFieldProps, I as ImageFieldProps, F as FileFieldProps, R as RelationFieldProps, J as JsonFieldProps, a as FieldComponent, b as EmptyStateProps, c as NavigationProgressProps, d as BreadcrumbItem, e as TabItem, A as AppShellProps, f as NavigationItem, g as UserMenuProps } from './permission-gate-DVmY42oz.js';
3
+ export { h as ActionButtonProps, i as AlertSlotProps, j as AppShellSlotProps, k as AvatarWithInitialsProps, l as BaseFieldProps, m as BreadcrumbSlotProps, n as BulkAction, o as ButtonSlotProps, C as ChipSlotProps, p as ColumnDef, q as ColumnShorthand, r as ConfirmDialogSlotProps, s as ConfirmOptions, t as DataTableProps, u as DetailViewProps, v as DropZoneProps, w as DropZoneSlotProps, x as FileListFile, y as FileListProps, z as FilterBarProps, G as FilterDef, H as FilterOption, K as FilterType, L as FormStatusData, M as FormStatusProps, O as ImagePreviewProps, P as ImpersonationBannerProps, Q as ListViewProps, S as PageContainerSlotProps, V as PermissionGate, W as PermissionGateProps, X as RoleBadgeProps, Y as SidebarSlotProps, Z as TableCellSlotProps, _ as TableRowSlotProps, $ as TableSectionSlotProps, a0 as TableSlotProps, a1 as ToastApi, a2 as ToastOptions, a3 as ToastSlotProps, a4 as ToastType, a5 as TooltipSlotProps, a6 as UIPlugin, a7 as UIPluginComponents, a8 as UserMenuLink, a9 as WhenForbidden } from './permission-gate-DVmY42oz.js';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import { ReactNode } from 'react';
6
+ import '@cfast/actions/client';
7
+
8
+ /**
9
+ * Read-only display component that formats date values.
10
+ *
11
+ * Accepts `Date` objects, ISO strings, or Unix timestamps. Renders a `<time>`
12
+ * element with the formatted date and a machine-readable `datetime` attribute.
13
+ * Returns an em-dash for null/undefined values and "Invalid date" for unparseable input.
14
+ *
15
+ * @param props - See {@link DateFieldProps}.
16
+ * @returns A `<time>` element with the formatted date, or a placeholder `<span>`.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * <DateField value={post.createdAt} format="relative" />
21
+ * // -> "3 days ago"
22
+ *
23
+ * <DateField value="2026-03-11" format="short" locale="en" />
24
+ * // -> "Mar 11, 2026"
25
+ * ```
26
+ */
27
+ declare function DateField({ value, format, locale, }: DateFieldProps): react_jsx_runtime.JSX.Element;
28
+
29
+ /**
30
+ * Read-only display component that renders a boolean value as a colored chip.
31
+ *
32
+ * Uses the plugin's `chip` slot (via {@link useComponent}) for styling.
33
+ * Displays customizable labels and colors for `true` and `false` states.
34
+ * Returns an em-dash for null/undefined values.
35
+ *
36
+ * @param props - See {@link BooleanFieldProps}.
37
+ * @returns A styled chip element, or a placeholder `<span>` for null values.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * <BooleanField value={post.published} trueLabel="Published" falseLabel="Draft" />
42
+ * // -> Green chip: "Published" or neutral chip: "Draft"
43
+ * ```
44
+ */
45
+ declare function BooleanField({ value, trueLabel, falseLabel, trueColor, falseColor, }: BooleanFieldProps): react_jsx_runtime.JSX.Element;
46
+
47
+ /**
48
+ * Read-only display component that formats numeric values.
49
+ *
50
+ * Uses `Intl.NumberFormat` for locale-aware formatting. Supports currency
51
+ * display and decimal precision control. Returns an em-dash for null/undefined values.
52
+ *
53
+ * @param props - See {@link NumberFieldProps}.
54
+ * @returns A `<span>` with the formatted number, or a placeholder for null values.
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * <NumberField value={1234.5} locale="en" />
59
+ * // -> "1,234.5"
60
+ *
61
+ * <NumberField value={29.99} currency="USD" />
62
+ * // -> "$29.99"
63
+ * ```
64
+ */
65
+ declare function NumberField({ value, locale, currency, decimals, }: NumberFieldProps): react_jsx_runtime.JSX.Element;
66
+
67
+ /**
68
+ * Read-only display component for plain text values.
69
+ *
70
+ * Optionally truncates long strings at `maxLength` characters with an ellipsis
71
+ * and shows the full text in a `title` tooltip on hover. Returns an em-dash
72
+ * for null/undefined values.
73
+ *
74
+ * @param props - See {@link TextFieldProps}.
75
+ * @returns A `<span>` with the text content, or a placeholder for null values.
76
+ *
77
+ * @example
78
+ * ```tsx
79
+ * <TextField value={post.title} maxLength={50} />
80
+ * // -> Truncated with tooltip if longer than 50 characters
81
+ * ```
82
+ */
83
+ declare function TextField({ value, maxLength, }: TextFieldProps): react_jsx_runtime.JSX.Element;
84
+
85
+ /**
86
+ * Read-only display component that renders an email address as a clickable `mailto:` link.
87
+ *
88
+ * Returns an em-dash for null/undefined values.
89
+ *
90
+ * @param props - See {@link EmailFieldProps}.
91
+ * @returns An `<a>` element with a `mailto:` href, or a placeholder `<span>` for null values.
92
+ *
93
+ * @example
94
+ * ```tsx
95
+ * <EmailField value={user.email} />
96
+ * // -> <a href="mailto:user@example.com">user@example.com</a>
97
+ * ```
98
+ */
99
+ declare function EmailField({ value }: EmailFieldProps): react_jsx_runtime.JSX.Element;
100
+
101
+ /**
102
+ * Read-only display component that renders a URL as an external link.
103
+ *
104
+ * Opens in a new tab with `rel="noopener noreferrer"` and appends an arrow
105
+ * indicator. When `truncate` is enabled, displays only the hostname and path
106
+ * instead of the full URL. Returns an em-dash for null/undefined values.
107
+ *
108
+ * @param props - See {@link UrlFieldProps}.
109
+ * @returns An `<a>` element with `target="_blank"`, or a placeholder `<span>` for null values.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * <UrlField value="https://example.com/blog/post-1" truncate />
114
+ * // -> "example.com/blog/post-1 (arrow icon)"
115
+ * ```
116
+ */
117
+ declare function UrlField({ value, truncate }: UrlFieldProps): react_jsx_runtime.JSX.Element;
118
+
119
+ /**
120
+ * Read-only display component that renders an image thumbnail.
121
+ *
122
+ * Displays the image at the specified dimensions with `object-fit: cover` and
123
+ * rounded corners. Returns an em-dash for null/undefined values.
124
+ *
125
+ * @param props - See {@link ImageFieldProps}.
126
+ * @returns An `<img>` element, or a placeholder `<span>` for null values.
127
+ *
128
+ * @example
129
+ * ```tsx
130
+ * <ImageField value={post.coverImageUrl} width={120} height={80} alt="Cover" />
131
+ * ```
132
+ */
133
+ declare function ImageField({ value, width, height, alt, }: ImageFieldProps): react_jsx_runtime.JSX.Element;
134
+
135
+ /**
136
+ * Read-only display component that renders a file reference with an icon,
137
+ * display name, and optional formatted file size.
138
+ *
139
+ * Uses `fileName` if provided, otherwise falls back to the raw `value` string.
140
+ * File sizes are formatted as B/KB/MB. Returns an em-dash for null/undefined values.
141
+ *
142
+ * @param props - See {@link FileFieldProps}.
143
+ * @returns A `<span>` with a file icon, name, and size, or a placeholder for null values.
144
+ *
145
+ * @example
146
+ * ```tsx
147
+ * <FileField value="report.pdf" fileName="Q4 Report.pdf" fileSize={2048576} />
148
+ * // -> "Q4 Report.pdf (2.0 MB)"
149
+ * ```
150
+ */
151
+ declare function FileField({ value, fileName, fileSize, }: FileFieldProps): react_jsx_runtime.JSX.Element;
152
+
153
+ /**
154
+ * Read-only display component for related record references.
155
+ *
156
+ * Extracts the display property (defaults to `"name"`) from the related record
157
+ * object and renders it as plain text or a link. When `linkTo` is provided,
158
+ * the `:id` placeholder is replaced with the record's `id` to form the href.
159
+ * Returns an em-dash for null/undefined values.
160
+ *
161
+ * @param props - See {@link RelationFieldProps}.
162
+ * @returns An `<a>` element if `linkTo` is set and the record has an `id`,
163
+ * a plain `<span>` otherwise, or a placeholder for null values.
164
+ *
165
+ * @example
166
+ * ```tsx
167
+ * <RelationField value={post.author} display="name" linkTo="/users/:id" />
168
+ * // -> <a href="/users/abc123">Jane Doe</a>
169
+ * ```
170
+ */
171
+ declare function RelationField({ value, display, linkTo, }: RelationFieldProps): react_jsx_runtime.JSX.Element;
172
+
173
+ /**
174
+ * Read-only display component that renders a JSON value as formatted code.
175
+ *
176
+ * When `collapsed` is true, shows a single-line preview (truncated at 60 chars)
177
+ * with an "expand" button. When expanded, displays the full pretty-printed JSON
178
+ * in a `<pre>` block. Returns an em-dash for null/undefined values.
179
+ *
180
+ * @param props - See {@link JsonFieldProps}.
181
+ * @returns A `<pre>` with formatted JSON, a collapsed preview, or a
182
+ * placeholder `<span>` for null values.
183
+ *
184
+ * @example
185
+ * ```tsx
186
+ * <JsonField value={{ tags: ["react", "typescript"] }} collapsed />
187
+ * // -> '{"tags":["react","typescript"]}' with expand button
188
+ * ```
189
+ */
190
+ declare function JsonField({ value, collapsed, }: JsonFieldProps): react_jsx_runtime.JSX.Element;
191
+
192
+ type ColumnMeta = {
193
+ dataType: string;
194
+ name: string;
195
+ };
196
+ /**
197
+ * Maps a Drizzle column's metadata to the appropriate TypedField component.
198
+ *
199
+ * Inspects the column's `dataType` and `name` to determine the best display
200
+ * component. The mapping follows these rules:
201
+ *
202
+ * - `boolean` or integer columns named `is*` -> {@link BooleanField}
203
+ * - Columns containing `timestamp`, `date`, or `datetime` -> {@link DateField}
204
+ * - Numeric types (`integer`, `real`, `float`, etc.) -> {@link NumberField}
205
+ * - Columns named `email` or `*Email` -> {@link EmailField}
206
+ * - `json`, `jsonb`, or `blob` -> {@link JsonField}
207
+ * - Everything else -> {@link TextField}
208
+ *
209
+ * @param column - Drizzle column metadata with `dataType` and `name` properties.
210
+ * @returns A React component suitable for displaying the column's values.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * import { fieldForColumn } from "@cfast/ui";
215
+ *
216
+ * const Field = fieldForColumn({ dataType: "timestamp", name: "createdAt" });
217
+ * // Field === DateField
218
+ * ```
219
+ */
220
+ declare function fieldForColumn(column: ColumnMeta): FieldComponent;
221
+ /**
222
+ * Given a Drizzle table, returns a map of column names to their inferred
223
+ * TypedField components.
224
+ *
225
+ * Iterates over the table's entries, identifies columns by duck-typing
226
+ * (`dataType` and `name` properties), and delegates to {@link fieldForColumn}
227
+ * for each one.
228
+ *
229
+ * @param table - A Drizzle table object whose entries expose column metadata.
230
+ * @returns A record mapping column key names to field component types. Each
231
+ * component accepts {@link BaseFieldProps} and a `value` prop.
232
+ *
233
+ * @example
234
+ * ```ts
235
+ * import { fieldsForTable } from "@cfast/ui";
236
+ * import { posts } from "~/db/schema";
237
+ *
238
+ * const fields = fieldsForTable(posts);
239
+ * // fields.title === TextField
240
+ * // fields.createdAt === DateField
241
+ * // fields.published === BooleanField
242
+ *
243
+ * const TitleField = fields.title;
244
+ * <TitleField value={post.title} />;
245
+ * ```
246
+ */
247
+ declare function fieldsForTable(table: {
248
+ [Symbol.iterator]?: never;
249
+ } & Record<string, unknown>): Record<string, FieldComponent>;
250
+
251
+ /**
252
+ * Permission-aware empty state placeholder.
253
+ *
254
+ * Adapts its content based on the user's permissions for the create action:
255
+ *
256
+ * - **Permitted**: shows title, description, and a CTA button
257
+ * - **Forbidden**: shows title and description without the CTA
258
+ * - **Invisible**: shows a generic "Nothing here yet" message
259
+ * - **No createAction**: shows title and description only
260
+ *
261
+ * @param props - See {@link EmptyStateProps}.
262
+ *
263
+ * @example
264
+ * ```tsx
265
+ * <EmptyState
266
+ * title="No posts yet"
267
+ * description="Create your first blog post to get started."
268
+ * createAction={createPost.client}
269
+ * createLabel="New Post"
270
+ * icon={DocumentIcon}
271
+ * />
272
+ * ```
273
+ */
274
+ declare function EmptyState({ title, description, createAction, createLabel, icon: Icon, }: EmptyStateProps): react_jsx_runtime.JSX.Element;
275
+
276
+ /**
277
+ * Thin progress bar fixed to the top of the viewport during React Router navigation.
278
+ *
279
+ * Uses `useNavigation().state` from React Router to detect loading transitions.
280
+ * Visible when `state === "loading"`, hidden when `state === "idle"`. No
281
+ * configuration is required beyond dropping it into your root layout.
282
+ *
283
+ * @param props - See {@link NavigationProgressProps}.
284
+ *
285
+ * @example
286
+ * ```tsx
287
+ * // In your root layout:
288
+ * <NavigationProgress />
289
+ *
290
+ * // With custom color:
291
+ * <NavigationProgress color="#e91e63" />
292
+ * ```
293
+ */
294
+ declare function NavigationProgress({ color, }: NavigationProgressProps): react_jsx_runtime.JSX.Element | null;
295
+
296
+ type PageContainerProps = {
297
+ title?: string;
298
+ breadcrumb?: BreadcrumbItem[];
299
+ actions?: ReactNode;
300
+ tabs?: TabItem[];
301
+ children: ReactNode;
302
+ };
303
+ /**
304
+ * Page wrapper providing a title, breadcrumb trail, tab navigation, and an action toolbar.
305
+ *
306
+ * Renders via the UI plugin's `pageContainer` and `breadcrumb` slots. Used internally
307
+ * by {@link ListView} and {@link DetailView}, but also useful as a standalone page shell
308
+ * for custom pages.
309
+ *
310
+ * @param props - See {@link PageContainerProps}.
311
+ *
312
+ * @example
313
+ * ```tsx
314
+ * <PageContainer
315
+ * title="Edit Post"
316
+ * breadcrumb={[
317
+ * { label: "Posts", to: "/posts" },
318
+ * { label: post.title },
319
+ * ]}
320
+ * actions={<ActionButton action={deletePost} input={{ postId }} />}
321
+ * >
322
+ * ...
323
+ * </PageContainer>
324
+ * ```
325
+ */
326
+ declare function PageContainer({ title, breadcrumb, actions, tabs: _tabs, children, }: PageContainerProps): react_jsx_runtime.JSX.Element;
327
+
328
+ /**
329
+ * Base application layout with sidebar navigation, header, and content area.
330
+ *
331
+ * Delegates rendering to the UI plugin's `appShell` slot. Compose with
332
+ * {@link AppShellSidebar} (`AppShell.Sidebar`) and {@link AppShellHeader}
333
+ * (`AppShell.Header`) for a complete layout.
334
+ *
335
+ * @param props - See {@link AppShellProps}.
336
+ *
337
+ * @example
338
+ * ```tsx
339
+ * <AppShell
340
+ * sidebar={<AppShell.Sidebar items={navigationItems} />}
341
+ * header={<AppShell.Header userMenu={<UserMenu />} />}
342
+ * >
343
+ * {children}
344
+ * </AppShell>
345
+ * ```
346
+ */
347
+ declare function AppShell({ children, sidebar, header }: AppShellProps): react_jsx_runtime.JSX.Element;
348
+ declare namespace AppShell {
349
+ var Sidebar: typeof AppShellSidebar;
350
+ var Header: typeof AppShellHeader;
351
+ }
352
+ /**
353
+ * Sidebar navigation for {@link AppShell} that automatically filters items by permission.
354
+ *
355
+ * Each {@link NavigationItem} can optionally carry an `action` descriptor. Items whose
356
+ * action is invisible or forbidden are hidden from the sidebar automatically.
357
+ *
358
+ * @param props.items - Navigation items to render.
359
+ *
360
+ * @example
361
+ * ```tsx
362
+ * <AppShell.Sidebar items={[
363
+ * { label: "Posts", to: "/posts", icon: DocumentIcon },
364
+ * { label: "Users", to: "/users", icon: UsersIcon, action: manageUsers.client },
365
+ * ]} />
366
+ * ```
367
+ */
368
+ declare function AppShellSidebar({ items }: {
369
+ items: NavigationItem[];
370
+ }): react_jsx_runtime.JSX.Element;
371
+ /**
372
+ * Header bar for {@link AppShell} with flexible content and an optional user menu.
373
+ *
374
+ * Renders a horizontal bar at the top of the shell. Pass a {@link UserMenu}
375
+ * element via the `userMenu` prop for authenticated user controls.
376
+ *
377
+ * @param props.children - Custom header content (logo, search, etc.).
378
+ * @param props.userMenu - User menu element rendered at the far right.
379
+ *
380
+ * @example
381
+ * ```tsx
382
+ * <AppShell.Header userMenu={<UserMenu links={[{ label: "Profile", to: "/profile" }]} />}>
383
+ * <Logo />
384
+ * </AppShell.Header>
385
+ * ```
386
+ */
387
+ declare function AppShellHeader({ children, userMenu, }: {
388
+ children?: ReactNode;
389
+ userMenu?: ReactNode;
390
+ }): react_jsx_runtime.JSX.Element;
391
+
392
+ /**
393
+ * Header dropdown showing the current user's avatar, name, email, role badges, and navigation links.
394
+ *
395
+ * Reads the authenticated user via `useCurrentUser()` from `@cfast/auth`. Renders
396
+ * an {@link AvatarWithInitials} trigger and a dropdown with user info, {@link RoleBadge}
397
+ * chips, permission-filtered navigation links, and an optional sign-out button.
398
+ * Returns `null` when no user is authenticated.
399
+ *
400
+ * @param props - See {@link UserMenuProps}.
401
+ *
402
+ * @example
403
+ * ```tsx
404
+ * <UserMenu
405
+ * links={[
406
+ * { label: "Profile", to: "/profile" },
407
+ * { label: "Admin", to: "/admin", action: adminAccess.client },
408
+ * ]}
409
+ * onSignOut={() => signOut()}
410
+ * />
411
+ * ```
412
+ */
413
+ declare function UserMenu({ links, onSignOut, }: UserMenuProps): react_jsx_runtime.JSX.Element | null;
414
+
415
+ export { AppShell, AppShellHeader, AppShellProps, AppShellSidebar, BooleanField, BooleanFieldProps, BreadcrumbItem, DateField, DateFieldProps, EmailField, EmailFieldProps, EmptyState, EmptyStateProps, FileField, FileFieldProps, ImageField, ImageFieldProps, JsonField, JsonFieldProps, NavigationItem, NavigationProgress, NavigationProgressProps, NumberField, NumberFieldProps, PageContainer, RelationField, RelationFieldProps, TabItem, TextField, TextFieldProps, UrlField, UrlFieldProps, UserMenu, UserMenuProps, fieldForColumn, fieldsForTable };