@cfast/ui 0.1.0 → 0.2.0

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.
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
2
3
  import { ReactNode, ComponentType } from 'react';
3
4
  import { ActionHookResult, ClientDescriptor } from '@cfast/actions/client';
4
5
 
@@ -52,7 +53,7 @@ type UIPluginComponents = {
52
53
  * A UI plugin providing styled component implementations for plugin slots.
53
54
  *
54
55
  * Created via `createUIPlugin()`. Slots not provided fall back to the headless
55
- * defaults (unstyled HTML elements). The Joy UI plugin (`@cfast/ui/joy`) is the
56
+ * defaults (unstyled HTML elements). The Joy UI plugin (`@cfast/joy`) is the
56
57
  * built-in implementation; third-party plugins can target shadcn, Mantine, or
57
58
  * any other component library.
58
59
  *
@@ -1245,6 +1246,219 @@ type NavigationProgressProps = {
1245
1246
  color?: string;
1246
1247
  };
1247
1248
 
1249
+ /**
1250
+ * Creates a {@link UIPlugin} that maps component slots to styled implementations.
1251
+ *
1252
+ * Slots not provided in the `components` map fall back to the unstyled HTML
1253
+ * defaults from the headless layer. This allows incremental adoption -- implement
1254
+ * only the slots your design system covers.
1255
+ *
1256
+ * @param config - Plugin configuration object.
1257
+ * @param config.components - Partial map of slot names to styled component implementations.
1258
+ * See {@link UIPluginComponents} for available slots.
1259
+ * @returns A {@link UIPlugin} instance to pass to {@link UIPluginProvider}.
1260
+ *
1261
+ * @example
1262
+ * ```ts
1263
+ * import { createUIPlugin } from "@cfast/ui";
1264
+ *
1265
+ * const joyPlugin = createUIPlugin({
1266
+ * components: {
1267
+ * button: JoyButton,
1268
+ * table: JoyTable,
1269
+ * chip: JoyChip,
1270
+ * },
1271
+ * });
1272
+ * ```
1273
+ */
1274
+ declare function createUIPlugin(config: {
1275
+ components: Partial<UIPluginComponents>;
1276
+ }): UIPlugin;
1277
+ /**
1278
+ * React context provider that makes a {@link UIPlugin} available to all `@cfast/ui` components.
1279
+ *
1280
+ * Place this near the root of your component tree (typically in the root layout).
1281
+ * All headless components use {@link useComponent} internally to resolve their
1282
+ * styled implementations from this context.
1283
+ *
1284
+ * @param props - Component props.
1285
+ * @param props.plugin - The UI plugin created by {@link createUIPlugin}.
1286
+ * @param props.children - Child elements that can access the plugin via
1287
+ * {@link useUIPlugin} or {@link useComponent}.
1288
+ * @returns A React element wrapping children with the UI plugin context.
1289
+ *
1290
+ * @example
1291
+ * ```tsx
1292
+ * import { UIPluginProvider, createUIPlugin } from "@cfast/ui";
1293
+ *
1294
+ * const plugin = createUIPlugin({ components: { button: MyButton } });
1295
+ *
1296
+ * function Root() {
1297
+ * return (
1298
+ * <UIPluginProvider plugin={plugin}>
1299
+ * <App />
1300
+ * </UIPluginProvider>
1301
+ * );
1302
+ * }
1303
+ * ```
1304
+ */
1305
+ declare function UIPluginProvider({ plugin, children, }: {
1306
+ plugin: UIPlugin;
1307
+ children: React.ReactNode;
1308
+ }): react_jsx_runtime.JSX.Element;
1309
+ /**
1310
+ * Returns the current {@link UIPlugin} from React context.
1311
+ *
1312
+ * Returns `null` if no {@link UIPluginProvider} is present in the component tree.
1313
+ * Most consumers should use {@link useComponent} instead, which handles the
1314
+ * fallback to headless defaults automatically.
1315
+ *
1316
+ * @returns The active {@link UIPlugin}, or `null` if no provider is mounted.
1317
+ *
1318
+ * @example
1319
+ * ```ts
1320
+ * const plugin = useUIPlugin();
1321
+ * if (plugin?.components.button) {
1322
+ * // A custom button implementation is available
1323
+ * }
1324
+ * ```
1325
+ */
1326
+ declare function useUIPlugin(): UIPlugin | null;
1327
+ /**
1328
+ * Resolves a component for a given {@link UIPluginComponents} slot.
1329
+ *
1330
+ * Looks up the slot in the current {@link UIPlugin} (via {@link useUIPlugin}).
1331
+ * If the plugin provides an implementation for the slot, that component is returned.
1332
+ * Otherwise, the headless HTML default is returned. This ensures every component
1333
+ * renders correctly even without a UI plugin installed.
1334
+ *
1335
+ * @typeParam K - The slot key from {@link UIPluginComponents}.
1336
+ * @param slot - The component slot name to resolve (e.g., `"button"`, `"table"`, `"chip"`).
1337
+ * @returns The component implementation for the given slot.
1338
+ *
1339
+ * @example
1340
+ * ```ts
1341
+ * function MyComponent() {
1342
+ * const Button = useComponent("button");
1343
+ * const Chip = useComponent("chip");
1344
+ *
1345
+ * return <Button onClick={handleClick}>Click me</Button>;
1346
+ * }
1347
+ * ```
1348
+ */
1349
+ declare function useComponent<K extends keyof UIPluginComponents>(slot: K): UIPluginComponents[K];
1350
+
1351
+ /**
1352
+ * Function signature for the imperative confirmation dialog.
1353
+ *
1354
+ * Call with {@link ConfirmOptions} to show a dialog. Resolves to `true` if
1355
+ * the user confirms, or `false` if they cancel or dismiss.
1356
+ */
1357
+ type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;
1358
+ /**
1359
+ * Returns an imperative {@link ConfirmFn} that opens a confirmation dialog
1360
+ * and resolves to `true` (confirmed) or `false` (cancelled/dismissed).
1361
+ *
1362
+ * Must be used within a `ConfirmProvider` -- typically supplied by the
1363
+ * Joy UI plugin or a custom UI plugin implementation.
1364
+ *
1365
+ * @returns A {@link ConfirmFn} that accepts {@link ConfirmOptions} and returns a `Promise<boolean>`.
1366
+ * @throws {Error} If called outside of a `ConfirmProvider`.
1367
+ *
1368
+ * @example
1369
+ * ```ts
1370
+ * function DangerZone() {
1371
+ * const confirm = useConfirm();
1372
+ *
1373
+ * async function handleDelete() {
1374
+ * const ok = await confirm({
1375
+ * title: "Delete account",
1376
+ * description: "This action cannot be undone.",
1377
+ * confirmLabel: "Delete",
1378
+ * variant: "danger",
1379
+ * });
1380
+ * if (ok) { /* proceed *\/ }
1381
+ * }
1382
+ *
1383
+ * return <button onClick={handleDelete}>Delete</button>;
1384
+ * }
1385
+ * ```
1386
+ */
1387
+ declare function useConfirm(): ConfirmFn;
1388
+
1389
+ type ToastContextValue = {
1390
+ show: (options: ToastOptions) => void;
1391
+ };
1392
+ declare const ToastContext: react.Context<ToastContextValue | null>;
1393
+ /**
1394
+ * Returns an imperative {@link ToastApi} for showing toast notifications.
1395
+ *
1396
+ * Provides convenience methods (`success`, `error`, `info`, `warning`) as well
1397
+ * as a generic `show` method that accepts full {@link ToastOptions}.
1398
+ *
1399
+ * Must be used within a `ToastProvider` -- typically supplied by the Joy UI
1400
+ * plugin (backed by Sonner) or a custom UI plugin implementation.
1401
+ *
1402
+ * @returns A {@link ToastApi} object with methods for each notification type.
1403
+ * @throws {Error} If called outside of a `ToastProvider`.
1404
+ *
1405
+ * @example
1406
+ * ```ts
1407
+ * function PublishButton() {
1408
+ * const toast = useToast();
1409
+ *
1410
+ * async function handlePublish() {
1411
+ * try {
1412
+ * await publishPost();
1413
+ * toast.success("Post published");
1414
+ * } catch (err) {
1415
+ * toast.error("Failed to publish post");
1416
+ * }
1417
+ * }
1418
+ *
1419
+ * return <button onClick={handlePublish}>Publish</button>;
1420
+ * }
1421
+ * ```
1422
+ */
1423
+ declare function useToast(): ToastApi;
1424
+
1425
+ /**
1426
+ * Maps action names to their success/error toast messages.
1427
+ *
1428
+ * Each key is an action name from a {@link ClientDescriptor}, and the value
1429
+ * specifies the toast messages to show when that action succeeds or fails.
1430
+ */
1431
+ type ActionToastConfig = Record<string, {
1432
+ success?: string;
1433
+ error?: string;
1434
+ }>;
1435
+ /**
1436
+ * Automatically shows toast notifications when `@cfast/actions` results arrive.
1437
+ *
1438
+ * Watches all configured actions via their {@link ClientDescriptor} and triggers
1439
+ * success or error toasts when their result data changes. Internally uses
1440
+ * {@link useToast} and `useActions` from `@cfast/actions/client`.
1441
+ *
1442
+ * Must be used within both a `ToastProvider` and an actions context
1443
+ * (i.e., inside `app.Provider`).
1444
+ *
1445
+ * @param descriptor - Client-side action descriptor from `@cfast/actions`, typically
1446
+ * `composed.client` from a `createActions()` call.
1447
+ * @param config - Map of action names to toast messages. Only actions listed here
1448
+ * are watched; others are ignored.
1449
+ * @returns void
1450
+ *
1451
+ * @example
1452
+ * ```ts
1453
+ * // In a route component:
1454
+ * useActionToast(composed.client, {
1455
+ * deletePost: { success: "Post deleted", error: "Failed to delete" },
1456
+ * publishPost: { success: "Post published" },
1457
+ * });
1458
+ * ```
1459
+ */
1460
+ declare function useActionToast(descriptor: ClientDescriptor, config: ActionToastConfig): void;
1461
+
1248
1462
  /**
1249
1463
  * Conditionally renders children based on action permission status.
1250
1464
  *
@@ -1266,4 +1480,405 @@ type NavigationProgressProps = {
1266
1480
  */
1267
1481
  declare function PermissionGate({ action, children, fallback, }: PermissionGateProps): react_jsx_runtime.JSX.Element | null;
1268
1482
 
1269
- export { type TableSectionSlotProps as $, type AppShellProps as A, type BooleanFieldProps as B, type ChipSlotProps as C, type DateFieldProps as D, type EmailFieldProps as E, type FileFieldProps as F, type FilterDef as G, type FilterOption as H, type ImageFieldProps as I, type JsonFieldProps as J, type FilterType as K, type FormStatusData as L, type FormStatusProps as M, type NumberFieldProps as N, type ImagePreviewProps as O, type ImpersonationBannerProps as P, type ListViewProps as Q, type RelationFieldProps as R, type PageContainerSlotProps as S, type TextFieldProps as T, type UrlFieldProps as U, PermissionGate as V, type PermissionGateProps as W, type RoleBadgeProps as X, type SidebarSlotProps as Y, type TableCellSlotProps as Z, type TableRowSlotProps as _, type FieldComponent as a, type TableSlotProps as a0, type ToastApi as a1, type ToastOptions as a2, type ToastSlotProps as a3, type ToastType as a4, type TooltipSlotProps as a5, type UIPlugin as a6, type UIPluginComponents as a7, type UserMenuLink as a8, type WhenForbidden as a9, type EmptyStateProps as b, type NavigationProgressProps as c, type BreadcrumbItem as d, type TabItem as e, type NavigationItem as f, type UserMenuProps as g, type ActionButtonProps as h, type AlertSlotProps as i, type AppShellSlotProps as j, type AvatarWithInitialsProps as k, type BaseFieldProps as l, type BreadcrumbSlotProps as m, type BulkAction as n, type ButtonSlotProps as o, type ColumnDef as p, type ColumnShorthand as q, type ConfirmDialogSlotProps as r, type ConfirmOptions as s, type DataTableProps as t, type DetailViewProps as u, type DropZoneProps as v, type DropZoneSlotProps as w, type FileListFile as x, type FileListProps as y, type FilterBarProps as z };
1483
+ /**
1484
+ * Permission-aware button that submits a `@cfast/actions` action.
1485
+ *
1486
+ * Accepts an `ActionHookResult` from `useActions()` and renders a button
1487
+ * via the UI plugin's `button` slot. The button's visibility and disabled
1488
+ * state are controlled by the action's permission status. Extra props are
1489
+ * forwarded to the underlying button component.
1490
+ *
1491
+ * - `whenForbidden="hide"` -- hidden when not permitted
1492
+ * - `whenForbidden="disable"` -- shown but disabled when not permitted (default)
1493
+ * - `whenForbidden="show"` -- shown and clickable regardless of permission
1494
+ *
1495
+ * @param props - See {@link ActionButtonProps}.
1496
+ *
1497
+ * @example
1498
+ * ```tsx
1499
+ * <ActionButton
1500
+ * action={publishPost}
1501
+ * whenForbidden="disable"
1502
+ * confirmation="Publish this post?"
1503
+ * >
1504
+ * Publish
1505
+ * </ActionButton>
1506
+ * ```
1507
+ */
1508
+ declare function ActionButton({ action, children, whenForbidden, confirmation: _confirmation, ...buttonProps }: ActionButtonProps): react_jsx_runtime.JSX.Element | null;
1509
+
1510
+ /**
1511
+ * Provides the {@link useConfirm} context and renders the confirmation dialog.
1512
+ *
1513
+ * Wrap your application (or a subtree) with `ConfirmProvider` to enable the
1514
+ * imperative `useConfirm()` hook. The dialog is rendered using the UI plugin's
1515
+ * `confirmDialog` slot, so it matches your chosen component library.
1516
+ *
1517
+ * @param props.children - The React tree that can call `useConfirm()`.
1518
+ *
1519
+ * @example
1520
+ * ```tsx
1521
+ * // In your root layout:
1522
+ * <ConfirmProvider>
1523
+ * <App />
1524
+ * </ConfirmProvider>
1525
+ *
1526
+ * // In any descendant component:
1527
+ * const confirm = useConfirm();
1528
+ * const ok = await confirm({ title: "Delete?", variant: "danger" });
1529
+ * ```
1530
+ */
1531
+ declare function ConfirmProvider({ children }: {
1532
+ children: ReactNode;
1533
+ }): react_jsx_runtime.JSX.Element;
1534
+
1535
+ /**
1536
+ * Displays action result feedback (success, error, and field-level validation messages).
1537
+ *
1538
+ * Renders alerts via the UI plugin's `alert` slot. Success messages are shown
1539
+ * in green, errors in red, and field-level validation errors as a bulleted list.
1540
+ * Returns `null` when there is no feedback to display.
1541
+ *
1542
+ * @param props - See {@link FormStatusProps}.
1543
+ *
1544
+ * @example
1545
+ * ```tsx
1546
+ * function EditForm() {
1547
+ * const actionData = useActionData();
1548
+ * return (
1549
+ * <Form method="post">
1550
+ * <FormStatus data={actionData} />
1551
+ * ...
1552
+ * </Form>
1553
+ * );
1554
+ * }
1555
+ * ```
1556
+ */
1557
+ declare function FormStatus({ data }: FormStatusProps): react_jsx_runtime.JSX.Element | null;
1558
+
1559
+ /**
1560
+ * Extracts up to two uppercase initials from a full name.
1561
+ *
1562
+ * Splits the name on spaces and takes the first character of each part.
1563
+ *
1564
+ * @param name - The full name to extract initials from.
1565
+ * @returns A string of 1-2 uppercase characters (e.g. `"DS"` for `"Daniel Schmidt"`).
1566
+ *
1567
+ * @example
1568
+ * ```ts
1569
+ * getInitials("Daniel Schmidt"); // "DS"
1570
+ * getInitials("Alice"); // "A"
1571
+ * ```
1572
+ */
1573
+ declare function getInitials(name: string): string;
1574
+ /**
1575
+ * Avatar component with automatic initials fallback.
1576
+ *
1577
+ * Renders an `<img>` when a `src` URL is provided. When `src` is absent or null,
1578
+ * displays the user's initials (derived via {@link getInitials}) inside a circular
1579
+ * badge. This is the headless implementation; styled versions are provided by UI plugins.
1580
+ *
1581
+ * @param props - See {@link AvatarWithInitialsProps}.
1582
+ *
1583
+ * @example
1584
+ * ```tsx
1585
+ * <AvatarWithInitials
1586
+ * src={user.avatarUrl}
1587
+ * name={user.name}
1588
+ * size="sm"
1589
+ * />
1590
+ * ```
1591
+ */
1592
+ declare function AvatarWithInitials({ src, name, size, }: AvatarWithInitialsProps): react_jsx_runtime.JSX.Element;
1593
+
1594
+ /**
1595
+ * Colored badge displaying a user's role name.
1596
+ *
1597
+ * Renders via the UI plugin's `chip` slot. Default color mapping:
1598
+ * admin = danger, editor = primary, author = success, reader = neutral.
1599
+ * Pass a custom `colors` map to override or extend the defaults.
1600
+ *
1601
+ * @param props - See {@link RoleBadgeProps}.
1602
+ *
1603
+ * @example
1604
+ * ```tsx
1605
+ * <RoleBadge role="admin" />
1606
+ * // Custom colors:
1607
+ * <RoleBadge role="moderator" colors={{ moderator: "warning" }} />
1608
+ * ```
1609
+ */
1610
+ declare function RoleBadge({ role, colors }: RoleBadgeProps): react_jsx_runtime.JSX.Element;
1611
+
1612
+ /**
1613
+ * Persistent banner shown when an admin is impersonating another user.
1614
+ *
1615
+ * Reads the current user from `@cfast/auth` via `useCurrentUser()`. When the
1616
+ * user has `isImpersonating` set, renders a warning alert with the impersonated
1617
+ * user's name/email and a "Stop Impersonating" button that posts to `stopAction`.
1618
+ * Hidden when not impersonating.
1619
+ *
1620
+ * @param props - See {@link ImpersonationBannerProps}.
1621
+ *
1622
+ * @example
1623
+ * ```tsx
1624
+ * // In your root layout:
1625
+ * <ImpersonationBanner />
1626
+ *
1627
+ * // With custom stop action URL:
1628
+ * <ImpersonationBanner stopAction="/api/stop-impersonation" />
1629
+ * ```
1630
+ */
1631
+ declare function ImpersonationBanner({ stopAction, }: ImpersonationBannerProps): react_jsx_runtime.JSX.Element | null;
1632
+
1633
+ /**
1634
+ * Data table with column sorting, row selection, and pluggable cell rendering.
1635
+ *
1636
+ * Renders via the UI plugin's table slots (`table`, `tableHead`, `tableBody`,
1637
+ * `tableRow`, `tableCell`). Accepts column definitions as strings (auto-labeled)
1638
+ * or full {@link ColumnDef} objects for custom labels, sorting, and renderers.
1639
+ *
1640
+ * Integrates with `@cfast/pagination` hook results for paginated data and with
1641
+ * `@cfast/actions` for row-level actions.
1642
+ *
1643
+ * @typeParam T - The row data type.
1644
+ * @param props - See {@link DataTableProps}.
1645
+ *
1646
+ * @example
1647
+ * ```tsx
1648
+ * const pagination = usePagination<Post>();
1649
+ *
1650
+ * <DataTable
1651
+ * data={pagination}
1652
+ * columns={["title", "author", { key: "createdAt", sortable: false }]}
1653
+ * selectable
1654
+ * onRowClick={(row) => navigate(`/posts/${row.id}`)}
1655
+ * />
1656
+ * ```
1657
+ */
1658
+ declare function DataTable<T = unknown>({ data, columns: columnsProp, selectable, selectedRows: externalSelectedRows, onSelectionChange, onRowClick, getRowId, emptyMessage, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
1659
+
1660
+ /**
1661
+ * URL-synced filter controls for data tables and list views.
1662
+ *
1663
+ * Each filter serializes its state to URL search params (e.g., `?published=true`).
1664
+ * On filter change, React Router navigates with the updated params, resetting
1665
+ * pagination to page 1. In the loader, `@cfast/pagination`'s `parseParams()`
1666
+ * reads these params and applies them as Drizzle `where` clauses.
1667
+ *
1668
+ * Supports text, select, boolean, and other filter types via {@link FilterDef}.
1669
+ * An optional `searchable` prop adds a full-text search input across specified columns.
1670
+ *
1671
+ * @param props - See {@link FilterBarProps}.
1672
+ *
1673
+ * @example
1674
+ * ```tsx
1675
+ * <FilterBar
1676
+ * filters={[
1677
+ * { column: "published", type: "select", options: [
1678
+ * { label: "Published", value: "true" },
1679
+ * { label: "Draft", value: "false" },
1680
+ * ]},
1681
+ * { column: "createdAt", type: "dateRange" },
1682
+ * ]}
1683
+ * searchable={["title", "content"]}
1684
+ * />
1685
+ * ```
1686
+ */
1687
+ declare function FilterBar({ filters, searchable, }: FilterBarProps): react_jsx_runtime.JSX.Element;
1688
+
1689
+ type BulkActionBarProps = {
1690
+ selectedCount: number;
1691
+ actions: BulkAction[];
1692
+ onAction: (action: BulkAction) => void;
1693
+ onClearSelection: () => void;
1694
+ };
1695
+ /**
1696
+ * Toolbar that appears when rows are selected in a {@link DataTable}.
1697
+ *
1698
+ * Displays the selected row count, action buttons for each {@link BulkAction},
1699
+ * and a "Clear" button to deselect all rows. Actions are rendered via the UI
1700
+ * plugin's `button` slot. Hidden automatically when `selectedCount` is zero.
1701
+ *
1702
+ * @param props - See {@link BulkActionBarProps}.
1703
+ *
1704
+ * @example
1705
+ * ```tsx
1706
+ * <BulkActionBar
1707
+ * selectedCount={selectedRows.length}
1708
+ * actions={[
1709
+ * { label: "Delete", icon: TrashIcon },
1710
+ * { label: "Publish" },
1711
+ * ]}
1712
+ * onAction={(action) => handleBulk(action, selectedRows)}
1713
+ * onClearSelection={() => clearSelection()}
1714
+ * />
1715
+ * ```
1716
+ */
1717
+ declare function BulkActionBar({ selectedCount, actions, onAction, onClearSelection, }: BulkActionBarProps): react_jsx_runtime.JSX.Element | null;
1718
+
1719
+ /** A column definition extended with an inferred TypedField component. */
1720
+ type InferredColumn = ColumnDef & {
1721
+ /** The field component that renders the appropriate display for this column type. */
1722
+ field: ComponentType<{
1723
+ value: unknown;
1724
+ }>;
1725
+ };
1726
+ /**
1727
+ * Inspects a Drizzle table's columns and returns inferred {@link ColumnDef} entries
1728
+ * with appropriate TypedField components attached.
1729
+ *
1730
+ * Uses {@link fieldForColumn} internally to map each Drizzle column's `dataType`
1731
+ * to a display component (e.g., `DateField`, `BooleanField`, `TextField`).
1732
+ * Labels are auto-derived from camelCase column keys.
1733
+ *
1734
+ * Memoized -- only recomputes when the `table` reference or `columns` array changes.
1735
+ *
1736
+ * @param table - A Drizzle table object whose entries expose `dataType` and `name` metadata.
1737
+ * Pass `undefined` to return an empty array (safe for conditional rendering).
1738
+ * @param columns - Optional subset of column names to include. When provided,
1739
+ * only matching columns are returned and their order is preserved.
1740
+ * @returns Array of {@link InferredColumn} definitions, each containing a `field`
1741
+ * component ready for rendering.
1742
+ *
1743
+ * @example
1744
+ * ```ts
1745
+ * import { useColumnInference } from "@cfast/ui";
1746
+ * import { posts } from "~/db/schema";
1747
+ *
1748
+ * const cols = useColumnInference(posts, ["title", "createdAt", "published"]);
1749
+ * // cols[0].field === TextField
1750
+ * // cols[1].field === DateField
1751
+ * // cols[2].field === BooleanField
1752
+ * ```
1753
+ */
1754
+ declare function useColumnInference(table: Record<string, unknown> | undefined, columns?: string[]): InferredColumn[];
1755
+
1756
+ /**
1757
+ * Drag-and-drop file upload area that integrates with `@cfast/storage`.
1758
+ *
1759
+ * Accepts an `upload` result from `useUpload()` (`@cfast/storage/client`).
1760
+ * File type restrictions and max size are inherited from the storage schema.
1761
+ * Renders via the UI plugin's `dropZone` slot and manages drag state,
1762
+ * file validation, and upload progress internally.
1763
+ *
1764
+ * @param props - See {@link DropZoneProps}.
1765
+ *
1766
+ * @example
1767
+ * ```tsx
1768
+ * const upload = useUpload("postCoverImage");
1769
+ *
1770
+ * <DropZone upload={upload} />
1771
+ *
1772
+ * // Allow multiple files:
1773
+ * <DropZone upload={upload} multiple />
1774
+ * ```
1775
+ */
1776
+ declare function DropZone({ upload, multiple, children, }: DropZoneProps): react_jsx_runtime.JSX.Element;
1777
+
1778
+ /**
1779
+ * Displays an image from `@cfast/storage` or a direct URL.
1780
+ *
1781
+ * Resolves the display URL from either a direct `src`, or a `fileKey` + `getUrl`
1782
+ * resolver function (for signed URL generation). Shows a placeholder when no
1783
+ * image is available, or renders the `fallback` element if provided.
1784
+ *
1785
+ * @param props - See {@link ImagePreviewProps}.
1786
+ *
1787
+ * @example
1788
+ * ```tsx
1789
+ * <ImagePreview
1790
+ * fileKey={post.coverImageKey}
1791
+ * getUrl={(key) => storage.getSignedUrl(key)}
1792
+ * width={200}
1793
+ * height={150}
1794
+ * fallback={<PlaceholderImage />}
1795
+ * />
1796
+ * ```
1797
+ */
1798
+ declare function ImagePreview({ fileKey, src, getUrl, width, height, fallback, alt, }: ImagePreviewProps): react_jsx_runtime.JSX.Element;
1799
+
1800
+ /**
1801
+ * Displays a list of uploaded files with metadata, formatted sizes, and download links.
1802
+ *
1803
+ * Each file is rendered as a row showing the file name, size (human-readable), and
1804
+ * a download link (either via `onDownload` callback or the file's direct `url`).
1805
+ * Returns a "No files" placeholder when the list is empty.
1806
+ *
1807
+ * @param props - See {@link FileListProps}.
1808
+ *
1809
+ * @example
1810
+ * ```tsx
1811
+ * <FileList
1812
+ * files={post.attachments}
1813
+ * onDownload={(file) => window.open(storage.getSignedUrl(file.key))}
1814
+ * />
1815
+ * ```
1816
+ */
1817
+ declare function FileList$1({ files, onDownload, }: FileListProps): react_jsx_runtime.JSX.Element;
1818
+
1819
+ /**
1820
+ * Full-page list layout composing filters, data table, pagination, and empty state.
1821
+ *
1822
+ * Combines {@link PageContainer}, {@link FilterBar}, {@link DataTable},
1823
+ * {@link EmptyState}, {@link BulkActionBar}, and pagination controls into a
1824
+ * single component. This is the primary component used by `@cfast/admin` for
1825
+ * every table view, but it is equally useful in application code.
1826
+ *
1827
+ * Supports both offset-based pagination (page numbers) and cursor-based pagination
1828
+ * (load more). The `createAction` prop controls the visibility of the "Create" button
1829
+ * via permission checks.
1830
+ *
1831
+ * @typeParam T - The row data type.
1832
+ * @param props - See {@link ListViewProps}.
1833
+ *
1834
+ * @example
1835
+ * ```tsx
1836
+ * const pagination = useOffsetPagination<Post>();
1837
+ *
1838
+ * <ListView
1839
+ * title="Blog Posts"
1840
+ * data={pagination}
1841
+ * columns={["title", "author", "published", "createdAt"]}
1842
+ * filters={[{ column: "published", type: "select", options: publishedOptions }]}
1843
+ * searchable={["title", "content"]}
1844
+ * createAction={createPost.client}
1845
+ * selectable
1846
+ * bulkActions={[
1847
+ * { label: "Delete", handler: (rows) => bulkDelete(rows) },
1848
+ * ]}
1849
+ * />
1850
+ * ```
1851
+ */
1852
+ declare function ListView<T = unknown>({ title, data, table: _table, columns, actions: _actions, filters, searchable, createAction, createLabel, selectable, bulkActions, breadcrumb, }: ListViewProps<T>): react_jsx_runtime.JSX.Element;
1853
+
1854
+ /**
1855
+ * Read-only detail page for a single record, rendered in a two-column grid.
1856
+ *
1857
+ * Composes {@link PageContainer} with automatic TypedField rendering. When a Drizzle
1858
+ * `table` is provided, field types are inferred from column metadata and rendered with
1859
+ * the appropriate field component (DateField, BooleanField, etc.). Fields can also be
1860
+ * specified manually as strings or full {@link ColumnDef} objects with custom renderers.
1861
+ *
1862
+ * If no `fields` are specified, they are inferred from the record's own keys
1863
+ * (minus any keys listed in `exclude`).
1864
+ *
1865
+ * @typeParam T - The record data type.
1866
+ * @param props - See {@link DetailViewProps}.
1867
+ *
1868
+ * @example
1869
+ * ```tsx
1870
+ * <DetailView
1871
+ * title={post.title}
1872
+ * table={posts}
1873
+ * record={post}
1874
+ * fields={["title", "content", "author", "published", "createdAt"]}
1875
+ * breadcrumb={[
1876
+ * { label: "Posts", to: "/posts" },
1877
+ * { label: post.title },
1878
+ * ]}
1879
+ * />
1880
+ * ```
1881
+ */
1882
+ declare function DetailView<T = unknown>({ title, table, record, fields: fieldsProp, exclude, breadcrumb, }: DetailViewProps<T>): react_jsx_runtime.JSX.Element;
1883
+
1884
+ export { ImagePreview as $, type AppShellProps as A, type BooleanFieldProps as B, type ChipSlotProps as C, type DateFieldProps as D, type EmailFieldProps as E, type FileFieldProps as F, type DetailViewProps as G, DropZone as H, type ImageFieldProps as I, type JsonFieldProps as J, type DropZoneProps as K, type DropZoneSlotProps as L, FileList$1 as M, type NumberFieldProps as N, type FileListFile as O, type FileListProps as P, FilterBar as Q, type RelationFieldProps as R, type FilterBarProps as S, type TextFieldProps as T, type UrlFieldProps as U, type FilterDef as V, type FilterOption as W, type FilterType as X, FormStatus as Y, type FormStatusData as Z, type FormStatusProps as _, type FieldComponent as a, type ImagePreviewProps as a0, ImpersonationBanner as a1, type ImpersonationBannerProps as a2, ListView as a3, type ListViewProps as a4, type PageContainerSlotProps as a5, PermissionGate as a6, type PermissionGateProps as a7, RoleBadge as a8, type RoleBadgeProps as a9, type SidebarSlotProps as aa, type TableCellSlotProps as ab, type TableRowSlotProps as ac, type TableSectionSlotProps as ad, type TableSlotProps as ae, type ToastApi as af, ToastContext as ag, type ToastOptions as ah, type ToastSlotProps as ai, type ToastType as aj, type TooltipSlotProps as ak, type UIPlugin as al, type UIPluginComponents as am, UIPluginProvider as an, type UserMenuLink as ao, type WhenForbidden as ap, createUIPlugin as aq, getInitials as ar, useActionToast as as, useColumnInference as at, useComponent as au, useConfirm as av, useToast as aw, useUIPlugin as ax, type EmptyStateProps as b, type NavigationProgressProps as c, type BreadcrumbItem as d, type TabItem as e, type NavigationItem as f, type UserMenuProps as g, ActionButton as h, type ActionButtonProps as i, type AlertSlotProps as j, type AppShellSlotProps as k, AvatarWithInitials as l, type AvatarWithInitialsProps as m, type BaseFieldProps as n, type BreadcrumbSlotProps as o, type BulkAction as p, BulkActionBar as q, type ButtonSlotProps as r, type ColumnDef as s, type ColumnShorthand as t, type ConfirmDialogSlotProps as u, type ConfirmOptions as v, ConfirmProvider as w, DataTable as x, type DataTableProps as y, DetailView as z };