@object-ui/components 4.4.0 → 4.6.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/CHANGELOG.md +49 -0
- package/dist/index.css +69 -2
- package/dist/index.js +2379 -2146
- package/dist/index.umd.cjs +2 -2
- package/dist/packages/components/src/custom/navigation-overlay.d.ts +22 -0
- package/dist/packages/components/src/hooks/related-count-store.d.ts +70 -0
- package/dist/packages/components/src/index.d.ts +1 -0
- package/package.json +5 -5
|
@@ -44,6 +44,28 @@ export interface NavigationOverlayProps {
|
|
|
44
44
|
* Popover trigger element (for popover mode).
|
|
45
45
|
*/
|
|
46
46
|
popoverTrigger?: React.ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* Optional handler invoked when the user clicks the "Expand to full page"
|
|
49
|
+
* affordance in the drawer/modal header. Mirrors Linear / Notion / Airtable
|
|
50
|
+
* peek-to-full-page behavior — the consumer is responsible for closing the
|
|
51
|
+
* overlay and router-pushing to the full record route.
|
|
52
|
+
*
|
|
53
|
+
* When omitted, the expand button is not rendered.
|
|
54
|
+
*/
|
|
55
|
+
onExpand?: () => void;
|
|
56
|
+
/** Optional label for the expand button (accessible name & tooltip). */
|
|
57
|
+
expandLabel?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Optional storage key for persisting the user's manually-resized drawer
|
|
60
|
+
* width (drawer mode only). When provided, the drawer renders a drag
|
|
61
|
+
* handle on its left edge and remembers the resized width in
|
|
62
|
+
* `localStorage` across sessions. Use a stable, scoped key such as
|
|
63
|
+
* `'drawer-width:lead'` so different objects get independent widths.
|
|
64
|
+
*
|
|
65
|
+
* When omitted, the drag handle is hidden and width is fully controlled
|
|
66
|
+
* by the `width` prop / configured ceiling.
|
|
67
|
+
*/
|
|
68
|
+
storageKey?: string;
|
|
47
69
|
}
|
|
48
70
|
/**
|
|
49
71
|
* NavigationOverlay — renders record detail in the configured overlay mode.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* Module-scoped store for related-list counts displayed in tab badges
|
|
9
|
+
* (e.g. "Contacts (12)" on an Account detail). The store deduplicates
|
|
10
|
+
* concurrent probes for the same key, lets the renderer subscribe with
|
|
11
|
+
* `useSyncExternalStore`, and exposes invalidation hooks so other parts
|
|
12
|
+
* of the runtime (bulk delete, inline create, optimistic update) can
|
|
13
|
+
* keep the badges in sync without a full page refetch.
|
|
14
|
+
*
|
|
15
|
+
* Design notes:
|
|
16
|
+
* - One global Map keyed by `${objectName}::${relField}::${parentId}` so
|
|
17
|
+
* a count fetched by one tab strip is reused by every other consumer.
|
|
18
|
+
* - Subscribers receive *all* keyspace changes; coarse-grained but
|
|
19
|
+
* badges are cheap to re-render and avoids per-key subscription noise.
|
|
20
|
+
* - We deliberately avoid Zustand here — the surface area is one Map +
|
|
21
|
+
* an emit() — and the React binding uses the built-in
|
|
22
|
+
* `useSyncExternalStore` so we don't grow the dependency graph.
|
|
23
|
+
*/
|
|
24
|
+
interface ProbeFn {
|
|
25
|
+
(objectName: string, query: {
|
|
26
|
+
where?: Record<string, unknown>;
|
|
27
|
+
limit?: number;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
total?: number;
|
|
30
|
+
data?: unknown[];
|
|
31
|
+
} | unknown[] | {
|
|
32
|
+
length?: number;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
declare function getCount(objectName: string, relField: string | undefined, parentId: string | undefined): number | undefined;
|
|
36
|
+
declare function setCount(objectName: string, relField: string | undefined, parentId: string | undefined, value: number): void;
|
|
37
|
+
/**
|
|
38
|
+
* Probe a count via the supplied finder. Deduplicates concurrent requests
|
|
39
|
+
* for the same key and caches the resulting number until invalidated.
|
|
40
|
+
*/
|
|
41
|
+
declare function fetchCount(probe: ProbeFn, objectName: string, relField: string | undefined, parentId: string | undefined): Promise<number>;
|
|
42
|
+
/**
|
|
43
|
+
* Invalidate every cached count that involves the given object. Called by
|
|
44
|
+
* mutation paths (e.g. ObjectGrid's onBulkDelete callback, drawer save) so
|
|
45
|
+
* the badge updates without forcing a parent re-render.
|
|
46
|
+
*
|
|
47
|
+
* When `parentId` is supplied, only entries whose parentId matches are
|
|
48
|
+
* dropped — useful for "I just created one Contact under Account X".
|
|
49
|
+
*/
|
|
50
|
+
declare function invalidate(objectName: string, parentId?: string): void;
|
|
51
|
+
declare function invalidateAll(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Subscribe to the related-count store and read the count for a single
|
|
54
|
+
* (object, relField, parentId) triple. Returns `undefined` while the
|
|
55
|
+
* probe is in flight or before the first request.
|
|
56
|
+
*/
|
|
57
|
+
export declare function useRelatedCount(objectName: string | undefined, relField: string | undefined, parentId: string | undefined): number | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Imperative store API for non-React callers (mutation handlers, tests).
|
|
60
|
+
* Prefer `useRelatedCount` in components.
|
|
61
|
+
*/
|
|
62
|
+
export declare const RelatedCountStore: {
|
|
63
|
+
get: typeof getCount;
|
|
64
|
+
set: typeof setCount;
|
|
65
|
+
fetch: typeof fetchCount;
|
|
66
|
+
invalidate: typeof invalidate;
|
|
67
|
+
invalidateAll: typeof invalidateAll;
|
|
68
|
+
_reset: () => void;
|
|
69
|
+
};
|
|
70
|
+
export {};
|
|
@@ -12,6 +12,7 @@ export { useResizeObserver } from './hooks/use-resize-observer';
|
|
|
12
12
|
export type { ElementSize } from './hooks/use-resize-observer';
|
|
13
13
|
export { useExportJob } from './hooks/use-export-job';
|
|
14
14
|
export type { UseExportJobOptions, UseExportJobReturn } from './hooks/use-export-job';
|
|
15
|
+
export { useRelatedCount, RelatedCountStore } from './hooks/related-count-store';
|
|
15
16
|
export type { ControlType, ConfigField, ConfigSection, ConfigPanelSchema, } from './types/config-panel';
|
|
16
17
|
export declare function initializeComponents(): boolean;
|
|
17
18
|
export * from './debug';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Standard UI component library for Object UI, built with Shadcn UI + Tailwind CSS",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"tailwind-merge": "^3.6.0",
|
|
70
70
|
"tailwindcss-animate": "^1.0.7",
|
|
71
71
|
"vaul": "^1.1.2",
|
|
72
|
-
"@object-ui/core": "4.
|
|
73
|
-
"@object-ui/i18n": "4.
|
|
74
|
-
"@object-ui/react": "4.
|
|
75
|
-
"@object-ui/types": "4.
|
|
72
|
+
"@object-ui/core": "4.6.0",
|
|
73
|
+
"@object-ui/i18n": "4.6.0",
|
|
74
|
+
"@object-ui/react": "4.6.0",
|
|
75
|
+
"@object-ui/types": "4.6.0"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
78
|
"react": "^18.0.0 || ^19.0.0",
|