@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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,8 @@
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';
1
+ 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 './client-CIx8_tmv.js';
2
+ export { h as ActionButton, i as ActionButtonProps, j as AlertSlotProps, k as AppShellSlotProps, l as AvatarWithInitials, m as AvatarWithInitialsProps, n as BaseFieldProps, o as BreadcrumbSlotProps, p as BulkAction, q as BulkActionBar, r as ButtonSlotProps, C as ChipSlotProps, s as ColumnDef, t as ColumnShorthand, u as ConfirmDialogSlotProps, v as ConfirmOptions, w as ConfirmProvider, x as DataTable, y as DataTableProps, z as DetailView, G as DetailViewProps, H as DropZone, K as DropZoneProps, L as DropZoneSlotProps, M as FileList, O as FileListFile, P as FileListProps, Q as FilterBar, S as FilterBarProps, V as FilterDef, W as FilterOption, X as FilterType, Y as FormStatus, Z as FormStatusData, _ as FormStatusProps, $ as ImagePreview, a0 as ImagePreviewProps, a1 as ImpersonationBanner, a2 as ImpersonationBannerProps, a3 as ListView, a4 as ListViewProps, a5 as PageContainerSlotProps, a6 as PermissionGate, a7 as PermissionGateProps, a8 as RoleBadge, a9 as RoleBadgeProps, aa as SidebarSlotProps, ab as TableCellSlotProps, ac as TableRowSlotProps, ad as TableSectionSlotProps, ae as TableSlotProps, af as ToastApi, ag as ToastContext, ah as ToastOptions, ai as ToastSlotProps, aj as ToastType, ak as TooltipSlotProps, al as UIPlugin, am as UIPluginComponents, an as UIPluginProvider, ao as UserMenuLink, ap as WhenForbidden, aq as createUIPlugin, ar as getInitials, as as useActionToast, at as useColumnInference, au as useComponent, av as useConfirm, aw as useToast, ax as useUIPlugin } from './client-CIx8_tmv.js';
4
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
4
  import { ReactNode } from 'react';
6
- import '@cfast/actions/client';
5
+ import { ClientDescriptor, ActionHookResult } from '@cfast/actions/client';
7
6
 
8
7
  /**
9
8
  * Read-only display component that formats date values.
@@ -412,4 +411,52 @@ declare function AppShellHeader({ children, userMenu, }: {
412
411
  */
413
412
  declare function UserMenu({ links, onSignOut, }: UserMenuProps): react_jsx_runtime.JSX.Element | null;
414
413
 
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 };
414
+ /**
415
+ * Safely retrieves a property from an unknown record-like value by string key.
416
+ *
417
+ * Isolates the single unavoidable `Record<string, unknown>` assertion needed
418
+ * when accessing dynamic keys on generic row/record objects (e.g., in DataTable
419
+ * and DetailView). Using this helper keeps the rest of the codebase cast-free.
420
+ *
421
+ * Returns `undefined` for non-object or null values.
422
+ *
423
+ * @param obj - A value expected to be a record-like object.
424
+ * @param key - The property name to look up.
425
+ * @returns The property value, or `undefined` if the key does not exist or obj is not an object.
426
+ *
427
+ * @internal
428
+ */
429
+ declare function getField(obj: unknown, key: string): unknown;
430
+ /**
431
+ * Extracts a string or number `id` from an unknown value.
432
+ *
433
+ * Returns the `id` property when it is a `string` or `number`, otherwise
434
+ * falls back to `0`. Isolates the dynamic-key access so callers avoid casts.
435
+ *
436
+ * @param obj - A value expected to be a record-like object with an `id` property.
437
+ * @returns The `id` value as a `string | number`, or `0` if missing/wrong type.
438
+ *
439
+ * @internal
440
+ */
441
+ declare function getRecordId(obj: unknown): string | number;
442
+
443
+ /**
444
+ * Returns the permission status and submit function for the first action in a descriptor.
445
+ *
446
+ * Convenience wrapper around `useActions()` for single-action descriptors
447
+ * (e.g. a create action passed to EmptyState or a navigation item guard).
448
+ *
449
+ * @param descriptor - Client-side action descriptor from `@cfast/actions`
450
+ * @returns The ActionHookResult with `permitted`, `invisible`, `pending`, and `submit`
451
+ *
452
+ * @example
453
+ * ```ts
454
+ * const status = useActionStatus(createPost.client);
455
+ * if (status.permitted) {
456
+ * status.submit({ title: "New Post" });
457
+ * }
458
+ * ```
459
+ */
460
+ declare function useActionStatus(descriptor: ClientDescriptor): ActionHookResult;
461
+
462
+ 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, getField, getRecordId, useActionStatus };
package/dist/index.js CHANGED
@@ -1,43 +1,43 @@
1
1
  import {
2
2
  ActionButton,
3
+ AvatarWithInitials,
4
+ BooleanField,
3
5
  BulkActionBar,
4
6
  ConfirmProvider,
5
7
  DataTable,
8
+ DateField,
6
9
  DetailView,
7
10
  DropZone,
11
+ EmailField,
8
12
  EmptyState,
9
13
  FileList,
10
14
  FilterBar,
11
15
  FormStatus,
12
16
  ImagePreview,
13
17
  ImpersonationBanner,
14
- ListView,
15
- PageContainer,
16
- RoleBadge,
17
- useActionToast,
18
- useColumnInference,
19
- useConfirm
20
- } from "./chunk-JEGEIQ3R.js";
21
- import {
22
- AvatarWithInitials,
23
- BooleanField,
24
- DateField,
25
- EmailField,
26
18
  JsonField,
19
+ ListView,
27
20
  NumberField,
21
+ PageContainer,
28
22
  PermissionGate,
23
+ RoleBadge,
29
24
  TextField,
25
+ ToastContext,
30
26
  UIPluginProvider,
31
27
  createUIPlugin,
32
28
  fieldForColumn,
33
29
  fieldsForTable,
34
30
  getField,
35
31
  getInitials,
32
+ getRecordId,
36
33
  useActionStatus,
34
+ useActionToast,
35
+ useColumnInference,
37
36
  useComponent,
37
+ useConfirm,
38
38
  useToast,
39
39
  useUIPlugin
40
- } from "./chunk-RDTUEOLK.js";
40
+ } from "./chunk-PWBG6CGF.js";
41
41
 
42
42
  // src/fields/url-field.tsx
43
43
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -280,13 +280,17 @@ export {
280
280
  RelationField,
281
281
  RoleBadge,
282
282
  TextField,
283
+ ToastContext,
283
284
  UIPluginProvider,
284
285
  UrlField,
285
286
  UserMenu,
286
287
  createUIPlugin,
287
288
  fieldForColumn,
288
289
  fieldsForTable,
290
+ getField,
289
291
  getInitials,
292
+ getRecordId,
293
+ useActionStatus,
290
294
  useActionToast,
291
295
  useColumnInference,
292
296
  useComponent,
package/llms.txt CHANGED
@@ -6,11 +6,11 @@
6
6
 
7
7
  Use `@cfast/ui` when building data-driven pages in a cfast app. It sits between your primitive component library (MUI Joy UI) and your application code, providing "smart" components that integrate with `@cfast/db`, `@cfast/actions`, `@cfast/permissions`, `@cfast/pagination`, `@cfast/auth`, and `@cfast/storage`.
8
8
 
9
- Import styled components from `@cfast/ui/joy`. Import headless components and hooks from `@cfast/ui`.
9
+ Import styled components from `@cfast/joy`. Import headless components and hooks from `@cfast/ui`.
10
10
 
11
11
  ## Key concepts
12
12
 
13
- - **Headless core + UI plugins**: `@cfast/ui` exports hooks and logic. `@cfast/ui/joy` exports Joy UI styled implementations. Custom plugins can provide other UI libraries via `createUIPlugin()`.
13
+ - **Headless core + UI plugins**: `@cfast/ui` exports hooks and logic. `@cfast/joy` exports Joy UI styled implementations. Custom plugins can provide other UI libraries via `createUIPlugin()`.
14
14
  - **Permission-aware**: Components like `ActionButton`, `PermissionGate`, `EmptyState`, sidebar nav items, and `BulkActionBar` automatically hide/disable based on `@cfast/actions` permission status.
15
15
  - **Schema-driven**: Pass a Drizzle `table` to `DataTable`, `FilterBar`, `DetailView`, or `useColumnInference()` and columns/fields/filters are inferred from column types.
16
16
  - **URL-synced**: `FilterBar` serializes filter state to URL search params. `DataTable` sorting syncs to URL params. Both work with `@cfast/pagination`'s `parseParams()` in loaders.
@@ -36,7 +36,7 @@ useColumnInference(table: Record<string, unknown> | undefined, columns?: string[
36
36
  // Maps Drizzle table columns to TypedField components. Memoized.
37
37
  ```
38
38
 
39
- ### Components (from `@cfast/ui/joy`)
39
+ ### Components (from `@cfast/joy`)
40
40
 
41
41
  **Data display:**
42
42
  - `DataTable` -- table with sorting, selection, row actions, skeleton loading. Accepts `data` (pagination result), `table` (Drizzle), `columns`, `actions`, `selectable`.
@@ -93,7 +93,7 @@ useComponent(slotName: string): ComponentType
93
93
  ### Full list page
94
94
 
95
95
  ```typescript
96
- import { ListView } from "@cfast/ui/joy";
96
+ import { ListView } from "@cfast/joy";
97
97
  import { usePagination } from "@cfast/pagination";
98
98
  import { posts } from "~/db/schema";
99
99
 
@@ -118,7 +118,7 @@ function PostsPage() {
118
118
  ### Permission-aware button with confirmation
119
119
 
120
120
  ```typescript
121
- import { ActionButton } from "@cfast/ui/joy";
121
+ import { ActionButton } from "@cfast/joy";
122
122
 
123
123
  <ActionButton
124
124
  action={deletePost}
@@ -152,7 +152,7 @@ useActionToast(composed.client, {
152
152
 
153
153
  ## Common Mistakes
154
154
 
155
- - Importing from `@cfast/ui/joy` on the server -- Joy components are client-only. Use headless exports from `@cfast/ui` for server-safe code.
155
+ - Importing from `@cfast/joy` on the server -- Joy components are client-only. Use headless exports from `@cfast/ui` for server-safe code.
156
156
  - Forgetting `<ToastProvider>` in root layout -- `useToast()` and `useActionToast()` throw without it.
157
157
  - Forgetting `<ConfirmProvider>` -- `useConfirm()` and `ActionButton` with `confirmation` need it.
158
158
  - Passing raw data arrays to `DataTable` instead of a pagination result from `usePagination()`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfast/ui",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Permission-aware React components with UI library plugins",
5
5
  "keywords": [
6
6
  "cfast",
@@ -23,10 +23,6 @@
23
23
  "import": "./dist/index.js",
24
24
  "types": "./dist/index.d.ts"
25
25
  },
26
- "./joy": {
27
- "import": "./dist/joy.js",
28
- "types": "./dist/joy.d.ts"
29
- },
30
26
  "./client": {
31
27
  "import": "./dist/client.js",
32
28
  "types": "./dist/client.d.ts"
@@ -41,28 +37,16 @@
41
37
  "access": "public"
42
38
  },
43
39
  "scripts": {
44
- "build": "tsup src/index.ts src/joy.ts src/client.ts --format esm --dts",
45
- "dev": "tsup src/index.ts src/joy.ts src/client.ts --format esm --dts --watch",
40
+ "build": "tsup src/index.ts src/client.ts --format esm --dts",
41
+ "dev": "tsup src/index.ts src/client.ts --format esm --dts --watch",
46
42
  "typecheck": "tsc --noEmit",
47
43
  "lint": "eslint src/",
48
- "test": "vitest run",
49
- "storybook": "storybook dev -p 6006",
50
- "build-storybook": "storybook build"
44
+ "test": "vitest run"
51
45
  },
52
46
  "peerDependencies": {
53
- "@mui/joy": ">=5.0.0-beta.0",
54
47
  "react": ">=19",
55
48
  "react-dom": ">=19",
56
- "react-router": ">=7",
57
- "sonner": ">=2"
58
- },
59
- "peerDependenciesMeta": {
60
- "@mui/joy": {
61
- "optional": true
62
- },
63
- "sonner": {
64
- "optional": true
65
- }
49
+ "react-router": ">=7"
66
50
  },
67
51
  "dependencies": {
68
52
  "@cfast/actions": "workspace:*",
@@ -73,12 +57,6 @@
73
57
  "@cfast/storage": "workspace:*"
74
58
  },
75
59
  "devDependencies": {
76
- "@emotion/react": "^11.14.0",
77
- "@emotion/styled": "^11.14.1",
78
- "@mui/joy": "^5.0.0-beta.52",
79
- "@mui/material": "^6.5.0",
80
- "@storybook/react": "^8.6.14",
81
- "@storybook/react-vite": "^8.6.14",
82
60
  "@testing-library/react": "^16.3.0",
83
61
  "@types/react": "^19.1.6",
84
62
  "@types/react-dom": "^19.1.6",
@@ -87,8 +65,6 @@
87
65
  "react": "^19.1.0",
88
66
  "react-dom": "^19.1.0",
89
67
  "react-router": "^7.12.0",
90
- "sonner": "^2.0.3",
91
- "storybook": "^8.6.14",
92
68
  "tsup": "^8",
93
69
  "typescript": "^5.7",
94
70
  "vitest": "^4.1.0"