@colineapp/ui 0.3.1 → 0.4.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/AGENTS.md +33 -4
- package/README.md +47 -0
- package/dist/index.d.ts +99 -3
- package/dist/index.js +246 -6
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -4
package/AGENTS.md
CHANGED
|
@@ -58,10 +58,9 @@ as `Button`, `Card`, `Input`, `Textarea`, `Badge`, `Dialog`, `Select`,
|
|
|
58
58
|
`Checkbox`, `Switch`, `Tabs`, `Table`, `Skeleton`, and `Tooltip`. Check the
|
|
59
59
|
component source and declaration output before documenting a new prop.
|
|
60
60
|
|
|
61
|
-
The
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
source.
|
|
61
|
+
The CLI bundles `main.tsx`, installed client dependencies, and imported CSS.
|
|
62
|
+
Coline rebuilds the uploaded artifact; the sandbox does not install packages.
|
|
63
|
+
Browser-compatible npm dependencies can be added to the app package.
|
|
65
64
|
|
|
66
65
|
## Verification and release
|
|
67
66
|
|
|
@@ -71,3 +70,33 @@ source.
|
|
|
71
70
|
- Update README examples and the scaffold skill when an app-facing contract
|
|
72
71
|
changes. The generated app must be able to use the documented API after a
|
|
73
72
|
clean `npm install`.
|
|
73
|
+
|
|
74
|
+
## SDK 0.4 / CLI 2.4 workflow
|
|
75
|
+
|
|
76
|
+
Run `coline-app check` before pushing: it checks types, the manifest, hosted logic,
|
|
77
|
+
and the React bundle without uploading. `dev --internal` updates one development
|
|
78
|
+
version; install it in the workspace and reload after changes. The CLI bundles
|
|
79
|
+
from the app's installed dependencies and preserves imported CSS and inline assets.
|
|
80
|
+
CLI 2.5 compiles app-specific Tailwind v4 and ordinary CSS automatically.
|
|
81
|
+
Import UI styles, then app.css; use complete class names. Local `preview` uses
|
|
82
|
+
the public test workspace and sandbox bridge, requires no credentials, and can
|
|
83
|
+
capture light/dark/mobile/error states with `--screenshots <directory>`.
|
|
84
|
+
|
|
85
|
+
The starter includes a React home and editor, tree mobile fallback, and a tool.
|
|
86
|
+
Use `coline.tools.invoke` or `actions.invokeTool` to run the same declared tool
|
|
87
|
+
from UI that Kairo runs. Save with `expectedVersion` to detect concurrent edits.
|
|
88
|
+
Homes/editors can write within grants; previews and server render handlers cannot.
|
|
89
|
+
`createTestWorkspace(app).client()` tests the interactive contract and
|
|
90
|
+
`grantedPermissions` simulates revoked consent.
|
|
91
|
+
|
|
92
|
+
New `tasks`, `calendar`, `messages`, and `references` capabilities require their
|
|
93
|
+
explicit manifest permissions and retain the invoking user's workspace access.
|
|
94
|
+
Use `files.list({ scope: "workspace" })` for shared files; document writes stay
|
|
95
|
+
with the owning app. Collections are install-private. Code integration and a
|
|
96
|
+
native mobile React runtime are separate work.
|
|
97
|
+
|
|
98
|
+
`src/live-collection.ts` wraps the SDK's canonical live-record implementation.
|
|
99
|
+
Keep state/conflict/sync logic in the SDK; React owns only subscriptions and
|
|
100
|
+
lifecycle. Inline serializable query objects must not restart the view on each
|
|
101
|
+
render. React Strict Mode cleanup/start must remain supported. Never infer record
|
|
102
|
+
permission from optimistic state or broadcast private fields to an install room.
|
package/README.md
CHANGED
|
@@ -64,3 +64,50 @@ Used inside a Coline App's react-tier surface (`{ tier: "react", entry:
|
|
|
64
64
|
Full guides at [coline.app/developers/docs](https://coline.app/developers/docs).
|
|
65
65
|
|
|
66
66
|
MIT © Coline
|
|
67
|
+
|
|
68
|
+
## SDK 0.4 / CLI 2.5 workflow
|
|
69
|
+
|
|
70
|
+
Run `coline-app check` before pushing: it checks types, the manifest, hosted logic,
|
|
71
|
+
and the React bundle without uploading. `dev --internal` updates one development
|
|
72
|
+
version; install it in the workspace and reload after changes. The CLI bundles
|
|
73
|
+
from the app's installed dependencies and preserves imported CSS and inline assets.
|
|
74
|
+
App-specific Tailwind v4 utilities compile automatically with CLI 2.5. Import
|
|
75
|
+
`@colineapp/ui/styles.css` and then `./app.css`; use complete class names.
|
|
76
|
+
|
|
77
|
+
The starter includes a React home and editor, tree mobile fallback, and a tool.
|
|
78
|
+
Use `coline.tools.invoke` or `actions.invokeTool` to run the same declared tool
|
|
79
|
+
from UI that Kairo runs. Save with `expectedVersion` to detect concurrent edits.
|
|
80
|
+
Homes/editors can write within grants; previews and server render handlers cannot.
|
|
81
|
+
`createTestWorkspace(app).client()` tests the interactive contract and
|
|
82
|
+
`grantedPermissions` simulates revoked consent.
|
|
83
|
+
|
|
84
|
+
New `tasks`, `calendar`, `messages`, and `references` capabilities require their
|
|
85
|
+
explicit manifest permissions and retain the invoking user's workspace access.
|
|
86
|
+
Use `files.list({ scope: "workspace" })` for shared files; document writes stay
|
|
87
|
+
with the owning app. Collections are install-private. Code integration and a
|
|
88
|
+
native mobile React runtime are separate work.
|
|
89
|
+
|
|
90
|
+
### Live data
|
|
91
|
+
|
|
92
|
+
`useLiveCollection<RecordType>("collection", { where, orderBy, limit })` returns
|
|
93
|
+
`records`, `pending`, `status`, `error`, `nextCursor`, `insert`, `update`, `delete`,
|
|
94
|
+
`setAccess`, and `refresh`. Inline query objects are supported. Mutations update
|
|
95
|
+
local UI immediately and reject on conflicts or permission failures; catch their
|
|
96
|
+
promises to present the error. The hook owns subscription cleanup and reconnect
|
|
97
|
+
recovery. Use filtered/paged views (at most 200 records), not an entire workspace
|
|
98
|
+
in one hook. Structured-record sync does not imply CRDT text editing or offline
|
|
99
|
+
write persistence.
|
|
100
|
+
|
|
101
|
+
## Screen patterns
|
|
102
|
+
|
|
103
|
+
Use `AppPage` and `PageToolbar` for consistent hierarchy, `RecordTable` with
|
|
104
|
+
`SplitView`/`DetailPanel` for queues, `Board`/`BoardColumn`/`BoardCard` for stages,
|
|
105
|
+
and `SettingsSection` for configuration. `EmptyState`, `AppErrorState`,
|
|
106
|
+
`AppLoadingState`, and `StatusBadge` cover common states. Their CSS ships in
|
|
107
|
+
`@colineapp/ui/styles.css`; they require no app-side utility generation.
|
|
108
|
+
|
|
109
|
+
Patterns compose around your domain and capabilities. They do not supply data,
|
|
110
|
+
routing, drag-and-drop, or persistence. `RecordTable` provides a first-cell button
|
|
111
|
+
when `onOpen` is set (don't nest a second control there); secondary columns hide
|
|
112
|
+
at narrow widths. Split details stack on mobile; the app owns focus management.
|
|
113
|
+
See the scaffold's `examples/` for complete interactive references.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ClassValue } from 'clsx';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
3
|
import { SandboxContext } from '@colineapp/app-runtime';
|
|
4
|
-
import
|
|
4
|
+
import * as _colineapp_sdk_v2 from '@colineapp/sdk/v2';
|
|
5
|
+
import { ColineCapabilities, ColineRecordQuery, LiveCollectionOptions } from '@colineapp/sdk/v2';
|
|
5
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
6
7
|
import { VariantProps } from 'class-variance-authority';
|
|
7
8
|
import { Checkbox as Checkbox$1, Dialog as Dialog$1, DropdownMenu as DropdownMenu$1, Label as Label$1, Popover as Popover$1, Progress as Progress$1, Select as Select$1, Separator as Separator$1, Slider as Slider$1, Switch as Switch$1, Tabs as Tabs$1, Toggle as Toggle$1, Tooltip as Tooltip$1 } from 'radix-ui';
|
|
@@ -10,7 +11,7 @@ declare function cn(...inputs: ClassValue[]): string;
|
|
|
10
11
|
|
|
11
12
|
declare function ColineAppProvider({ children }: {
|
|
12
13
|
children: React$1.ReactNode;
|
|
13
|
-
}): React$1.JSX.Element
|
|
14
|
+
}): React$1.JSX.Element;
|
|
14
15
|
declare function useColine(): ColineCapabilities;
|
|
15
16
|
declare function useColineContext(): SandboxContext;
|
|
16
17
|
declare function useColorScheme(): "light" | "dark";
|
|
@@ -200,4 +201,99 @@ declare function Tooltip({ ...props }: React$1.ComponentProps<typeof Tooltip$1.R
|
|
|
200
201
|
declare function TooltipTrigger({ ...props }: React$1.ComponentProps<typeof Tooltip$1.Trigger>): React$1.JSX.Element;
|
|
201
202
|
declare function TooltipContent({ className, sideOffset, children, ...props }: React$1.ComponentProps<typeof Tooltip$1.Content>): React$1.JSX.Element;
|
|
202
203
|
|
|
203
|
-
|
|
204
|
+
/** Inline query objects are safe: equivalent inputs retain the same live view. */
|
|
205
|
+
declare function useLiveCollection<T extends Record<string, unknown>>(name: string, query?: ColineRecordQuery<T>, options?: LiveCollectionOptions): {
|
|
206
|
+
insert: (data: T, access?: _colineapp_sdk_v2.ColineRecordAccess) => Promise<_colineapp_sdk_v2.ColineRecordEnvelope<T> | null>;
|
|
207
|
+
update: (id: string, patch: Partial<T>) => Promise<_colineapp_sdk_v2.ColineRecordEnvelope<T> | null>;
|
|
208
|
+
delete: (id: string) => Promise<_colineapp_sdk_v2.ColineRecordEnvelope<T> | null>;
|
|
209
|
+
setAccess: (id: string, access: _colineapp_sdk_v2.ColineRecordAccess) => Promise<_colineapp_sdk_v2.ColineRecordEnvelope<T> | null>;
|
|
210
|
+
refresh: () => Promise<void>;
|
|
211
|
+
records: readonly _colineapp_sdk_v2.ColineRecordEnvelope<T>[];
|
|
212
|
+
nextCursor: string | null;
|
|
213
|
+
status: "loading" | "ready" | "syncing" | "error";
|
|
214
|
+
pending: number;
|
|
215
|
+
error: Error | null;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
declare function AppPage({ title, description, eyebrow, actions, children, width, className, }: {
|
|
219
|
+
title: string;
|
|
220
|
+
description?: React$1.ReactNode;
|
|
221
|
+
eyebrow?: React$1.ReactNode;
|
|
222
|
+
actions?: React$1.ReactNode;
|
|
223
|
+
children: React$1.ReactNode;
|
|
224
|
+
width?: "wide" | "reading";
|
|
225
|
+
className?: string;
|
|
226
|
+
}): React$1.JSX.Element;
|
|
227
|
+
declare function PageToolbar({ children, label, className, }: {
|
|
228
|
+
children: React$1.ReactNode;
|
|
229
|
+
label?: string;
|
|
230
|
+
className?: string;
|
|
231
|
+
}): React$1.JSX.Element;
|
|
232
|
+
declare function EmptyState({ title, description, action, icon, }: {
|
|
233
|
+
title: string;
|
|
234
|
+
description?: React$1.ReactNode;
|
|
235
|
+
action?: React$1.ReactNode;
|
|
236
|
+
icon?: React$1.ReactNode;
|
|
237
|
+
}): React$1.JSX.Element;
|
|
238
|
+
declare function AppErrorState({ message, onRetry }: {
|
|
239
|
+
message: string;
|
|
240
|
+
onRetry?: () => void;
|
|
241
|
+
}): React$1.JSX.Element;
|
|
242
|
+
declare function AppLoadingState({ label, rows, }: {
|
|
243
|
+
label?: string;
|
|
244
|
+
rows?: number;
|
|
245
|
+
}): React$1.JSX.Element;
|
|
246
|
+
declare function StatusBadge({ children, tone, }: {
|
|
247
|
+
children: React$1.ReactNode;
|
|
248
|
+
tone?: "neutral" | "info" | "success" | "warning" | "danger";
|
|
249
|
+
}): React$1.JSX.Element;
|
|
250
|
+
declare function SplitView({ list, detail, label, }: {
|
|
251
|
+
list: React$1.ReactNode;
|
|
252
|
+
detail?: React$1.ReactNode;
|
|
253
|
+
label?: string;
|
|
254
|
+
}): React$1.JSX.Element;
|
|
255
|
+
declare function DetailPanel({ title, subtitle, onClose, children, actions, }: {
|
|
256
|
+
title: string;
|
|
257
|
+
subtitle?: React$1.ReactNode;
|
|
258
|
+
onClose?: () => void;
|
|
259
|
+
children: React$1.ReactNode;
|
|
260
|
+
actions?: React$1.ReactNode;
|
|
261
|
+
}): React$1.JSX.Element;
|
|
262
|
+
interface RecordColumn<T> {
|
|
263
|
+
key: string;
|
|
264
|
+
label: string;
|
|
265
|
+
render: (record: T) => React$1.ReactNode;
|
|
266
|
+
secondary?: boolean;
|
|
267
|
+
align?: "start" | "end";
|
|
268
|
+
}
|
|
269
|
+
declare function RecordTable<T>({ records, columns, rowKey, onOpen, label, empty, }: {
|
|
270
|
+
records: readonly T[];
|
|
271
|
+
columns: readonly RecordColumn<T>[];
|
|
272
|
+
rowKey: (record: T) => string;
|
|
273
|
+
onOpen?: (record: T) => void;
|
|
274
|
+
label?: string;
|
|
275
|
+
empty?: React$1.ReactNode;
|
|
276
|
+
}): React$1.JSX.Element;
|
|
277
|
+
declare function Board({ children, label, }: {
|
|
278
|
+
children: React$1.ReactNode;
|
|
279
|
+
label?: string;
|
|
280
|
+
}): React$1.JSX.Element;
|
|
281
|
+
declare function BoardColumn({ title, count, children, action, }: {
|
|
282
|
+
title: string;
|
|
283
|
+
count?: number;
|
|
284
|
+
children: React$1.ReactNode;
|
|
285
|
+
action?: React$1.ReactNode;
|
|
286
|
+
}): React$1.JSX.Element;
|
|
287
|
+
declare function BoardCard({ title, children, footer, onOpen, }: {
|
|
288
|
+
title: string;
|
|
289
|
+
children?: React$1.ReactNode;
|
|
290
|
+
footer?: React$1.ReactNode;
|
|
291
|
+
onOpen?: () => void;
|
|
292
|
+
}): React$1.JSX.Element;
|
|
293
|
+
declare function SettingsSection({ title, description, children, }: {
|
|
294
|
+
title: string;
|
|
295
|
+
description?: string;
|
|
296
|
+
children: React$1.ReactNode;
|
|
297
|
+
}): React$1.JSX.Element;
|
|
298
|
+
|
|
299
|
+
export { AppErrorState, AppLoadingState, AppPage, Badge, Board, BoardCard, BoardColumn, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColineAppProvider, type ColineQueryState, DetailPanel, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Input, Label, PageToolbar, Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, type RecordColumn, RecordTable, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SettingsSection, Skeleton, Slider, SplitView, StatusBadge, Switch, TABS_LAYOUT_SPRING, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsIndicator, TabsList, TabsTrigger, Textarea, Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cn, tabsListVariants, toggleVariants, useColine, useColineContext, useColineQuery, useColorScheme, useLiveCollection };
|
package/dist/index.js
CHANGED
|
@@ -24,18 +24,22 @@ function applyTheme(theme, colorScheme) {
|
|
|
24
24
|
root.classList.toggle("dark", colorScheme === "dark");
|
|
25
25
|
}
|
|
26
26
|
function ColineAppProvider({ children }) {
|
|
27
|
+
const [connectionError, setConnectionError] = React.useState(null);
|
|
27
28
|
const [runtime, setRuntime] = React.useState(null);
|
|
28
29
|
React.useEffect(() => {
|
|
29
30
|
let disposed = false;
|
|
31
|
+
let activeBridge = null;
|
|
30
32
|
let removeThemeListener = null;
|
|
31
33
|
void connectGuestBridge().then((bridge) => {
|
|
32
|
-
if (disposed)
|
|
34
|
+
if (disposed) {
|
|
35
|
+
bridge.dispose();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
activeBridge = bridge;
|
|
33
39
|
applyTheme(bridge.theme, bridge.colorScheme);
|
|
34
40
|
removeThemeListener = bridge.onThemeChange((theme, colorScheme) => {
|
|
35
41
|
applyTheme(theme, colorScheme);
|
|
36
|
-
setRuntime(
|
|
37
|
-
(current) => current ? { ...current, colorScheme } : current
|
|
38
|
-
);
|
|
42
|
+
setRuntime((current) => current ? { ...current, colorScheme } : current);
|
|
39
43
|
});
|
|
40
44
|
setRuntime({
|
|
41
45
|
bridge,
|
|
@@ -43,9 +47,12 @@ function ColineAppProvider({ children }) {
|
|
|
43
47
|
context: bridge.context,
|
|
44
48
|
colorScheme: bridge.colorScheme
|
|
45
49
|
});
|
|
50
|
+
}).catch((error) => {
|
|
51
|
+
if (!disposed) setConnectionError(error instanceof Error ? error.message : String(error));
|
|
46
52
|
});
|
|
47
53
|
return () => {
|
|
48
54
|
disposed = true;
|
|
55
|
+
activeBridge?.dispose();
|
|
49
56
|
removeThemeListener?.();
|
|
50
57
|
};
|
|
51
58
|
}, []);
|
|
@@ -58,7 +65,7 @@ function ColineAppProvider({ children }) {
|
|
|
58
65
|
return () => observer.disconnect();
|
|
59
66
|
}, [runtime]);
|
|
60
67
|
if (!runtime) {
|
|
61
|
-
return
|
|
68
|
+
return /* @__PURE__ */ jsx("p", { role: connectionError ? "alert" : "status", children: connectionError ?? "Connecting to Coline\u2026" });
|
|
62
69
|
}
|
|
63
70
|
return /* @__PURE__ */ jsx(ColineRuntimeContext.Provider, { value: runtime, children });
|
|
64
71
|
}
|
|
@@ -1857,8 +1864,233 @@ function TooltipContent({
|
|
|
1857
1864
|
}
|
|
1858
1865
|
) });
|
|
1859
1866
|
}
|
|
1867
|
+
|
|
1868
|
+
// src/live-collection.ts
|
|
1869
|
+
import * as React22 from "react";
|
|
1870
|
+
import {
|
|
1871
|
+
createLiveCollection
|
|
1872
|
+
} from "@colineapp/sdk/v2";
|
|
1873
|
+
function useLiveCollection(name, query, options) {
|
|
1874
|
+
const coline = useColine();
|
|
1875
|
+
const context = useColineContext();
|
|
1876
|
+
const key = JSON.stringify({
|
|
1877
|
+
query,
|
|
1878
|
+
options: { actorUserId: context.actor?.userId, installId: context.app.installId, ...options }
|
|
1879
|
+
});
|
|
1880
|
+
const live = React22.useMemo(() => {
|
|
1881
|
+
const input = JSON.parse(key);
|
|
1882
|
+
return createLiveCollection(coline, name, input.query, input.options);
|
|
1883
|
+
}, [coline, name, key]);
|
|
1884
|
+
React22.useEffect(() => {
|
|
1885
|
+
void live.start();
|
|
1886
|
+
return () => live.stop();
|
|
1887
|
+
}, [live]);
|
|
1888
|
+
const snapshot = React22.useSyncExternalStore(live.subscribe, live.getSnapshot, live.getSnapshot);
|
|
1889
|
+
return {
|
|
1890
|
+
...snapshot,
|
|
1891
|
+
insert: live.insert,
|
|
1892
|
+
update: live.update,
|
|
1893
|
+
delete: live.delete,
|
|
1894
|
+
setAccess: live.setAccess,
|
|
1895
|
+
refresh: live.refresh
|
|
1896
|
+
};
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
// src/patterns/workspace.tsx
|
|
1900
|
+
import * as React23 from "react";
|
|
1901
|
+
import { Fragment, jsx as jsx24, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1902
|
+
function AppPage({
|
|
1903
|
+
title,
|
|
1904
|
+
description,
|
|
1905
|
+
eyebrow,
|
|
1906
|
+
actions,
|
|
1907
|
+
children,
|
|
1908
|
+
width = "wide",
|
|
1909
|
+
className
|
|
1910
|
+
}) {
|
|
1911
|
+
return /* @__PURE__ */ jsxs6("main", { className: cn("coline-page", className), "data-width": width, children: [
|
|
1912
|
+
/* @__PURE__ */ jsxs6("header", { className: "coline-page-header", children: [
|
|
1913
|
+
/* @__PURE__ */ jsxs6("div", { className: "coline-page-heading", children: [
|
|
1914
|
+
eyebrow && /* @__PURE__ */ jsx24("div", { className: "coline-eyebrow", children: eyebrow }),
|
|
1915
|
+
/* @__PURE__ */ jsx24("h1", { children: title }),
|
|
1916
|
+
description && /* @__PURE__ */ jsx24("p", { className: "coline-page-description", children: description })
|
|
1917
|
+
] }),
|
|
1918
|
+
actions && /* @__PURE__ */ jsx24("div", { className: "coline-page-actions", children: actions })
|
|
1919
|
+
] }),
|
|
1920
|
+
children
|
|
1921
|
+
] });
|
|
1922
|
+
}
|
|
1923
|
+
function PageToolbar({
|
|
1924
|
+
children,
|
|
1925
|
+
label = "View controls",
|
|
1926
|
+
className
|
|
1927
|
+
}) {
|
|
1928
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("coline-toolbar", className), role: "group", "aria-label": label, children });
|
|
1929
|
+
}
|
|
1930
|
+
function EmptyState({
|
|
1931
|
+
title,
|
|
1932
|
+
description,
|
|
1933
|
+
action,
|
|
1934
|
+
icon
|
|
1935
|
+
}) {
|
|
1936
|
+
return /* @__PURE__ */ jsxs6("section", { className: "coline-empty", children: [
|
|
1937
|
+
icon && /* @__PURE__ */ jsx24("div", { className: "coline-empty-icon", "aria-hidden": "true", children: icon }),
|
|
1938
|
+
/* @__PURE__ */ jsx24("h2", { children: title }),
|
|
1939
|
+
description && /* @__PURE__ */ jsx24("p", { children: description }),
|
|
1940
|
+
action && /* @__PURE__ */ jsx24("div", { children: action })
|
|
1941
|
+
] });
|
|
1942
|
+
}
|
|
1943
|
+
function AppErrorState({ message, onRetry }) {
|
|
1944
|
+
return /* @__PURE__ */ jsxs6("section", { className: "coline-error", role: "alert", children: [
|
|
1945
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
1946
|
+
/* @__PURE__ */ jsx24("h2", { children: "Something went wrong" }),
|
|
1947
|
+
/* @__PURE__ */ jsx24("p", { children: message })
|
|
1948
|
+
] }),
|
|
1949
|
+
onRetry && /* @__PURE__ */ jsx24(Button, { variant: "outline", onClick: onRetry, children: "Try again" })
|
|
1950
|
+
] });
|
|
1951
|
+
}
|
|
1952
|
+
function AppLoadingState({
|
|
1953
|
+
label = "Loading",
|
|
1954
|
+
rows = 5
|
|
1955
|
+
}) {
|
|
1956
|
+
return /* @__PURE__ */ jsxs6("div", { className: "coline-loading", role: "status", "aria-label": label, children: [
|
|
1957
|
+
Array.from({ length: Math.max(1, Math.min(rows, 12)) }, (_, i) => /* @__PURE__ */ jsx24("div", { style: { width: `${92 - i % 3 * 14}%` } }, i)),
|
|
1958
|
+
/* @__PURE__ */ jsx24("span", { className: "coline-sr-only", children: label })
|
|
1959
|
+
] });
|
|
1960
|
+
}
|
|
1961
|
+
function StatusBadge({
|
|
1962
|
+
children,
|
|
1963
|
+
tone = "neutral"
|
|
1964
|
+
}) {
|
|
1965
|
+
return /* @__PURE__ */ jsxs6("span", { className: "coline-status", "data-tone": tone, children: [
|
|
1966
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": "true" }),
|
|
1967
|
+
children
|
|
1968
|
+
] });
|
|
1969
|
+
}
|
|
1970
|
+
function SplitView({
|
|
1971
|
+
list,
|
|
1972
|
+
detail,
|
|
1973
|
+
label = "Details"
|
|
1974
|
+
}) {
|
|
1975
|
+
return /* @__PURE__ */ jsxs6("div", { className: "coline-split", "data-open": Boolean(detail), children: [
|
|
1976
|
+
/* @__PURE__ */ jsx24("section", { className: "coline-split-list", children: list }),
|
|
1977
|
+
detail && /* @__PURE__ */ jsx24("aside", { className: "coline-split-detail", "aria-label": label, children: detail })
|
|
1978
|
+
] });
|
|
1979
|
+
}
|
|
1980
|
+
function DetailPanel({
|
|
1981
|
+
title,
|
|
1982
|
+
subtitle,
|
|
1983
|
+
onClose,
|
|
1984
|
+
children,
|
|
1985
|
+
actions
|
|
1986
|
+
}) {
|
|
1987
|
+
return /* @__PURE__ */ jsxs6("section", { className: "coline-detail", children: [
|
|
1988
|
+
/* @__PURE__ */ jsxs6("header", { children: [
|
|
1989
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
1990
|
+
subtitle && /* @__PURE__ */ jsx24("div", { className: "coline-eyebrow", children: subtitle }),
|
|
1991
|
+
/* @__PURE__ */ jsx24("h2", { children: title })
|
|
1992
|
+
] }),
|
|
1993
|
+
onClose && /* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close details", children: "Close" })
|
|
1994
|
+
] }),
|
|
1995
|
+
/* @__PURE__ */ jsx24("div", { className: "coline-detail-body", children }),
|
|
1996
|
+
actions && /* @__PURE__ */ jsx24("footer", { children: actions })
|
|
1997
|
+
] });
|
|
1998
|
+
}
|
|
1999
|
+
function RecordTable({
|
|
2000
|
+
records,
|
|
2001
|
+
columns,
|
|
2002
|
+
rowKey,
|
|
2003
|
+
onOpen,
|
|
2004
|
+
label = "Records",
|
|
2005
|
+
empty
|
|
2006
|
+
}) {
|
|
2007
|
+
if (!records.length)
|
|
2008
|
+
return /* @__PURE__ */ jsx24(Fragment, { children: empty ?? /* @__PURE__ */ jsx24(EmptyState, { title: "No results", description: "Try changing your filters." }) });
|
|
2009
|
+
return /* @__PURE__ */ jsx24("div", { className: "coline-table-scroll", children: /* @__PURE__ */ jsxs6("table", { className: "coline-record-table", "aria-label": label, children: [
|
|
2010
|
+
/* @__PURE__ */ jsx24("thead", { children: /* @__PURE__ */ jsx24("tr", { children: columns.map((column) => /* @__PURE__ */ jsx24(
|
|
2011
|
+
"th",
|
|
2012
|
+
{
|
|
2013
|
+
scope: "col",
|
|
2014
|
+
"data-secondary": column.secondary || void 0,
|
|
2015
|
+
"data-align": column.align,
|
|
2016
|
+
children: column.label
|
|
2017
|
+
},
|
|
2018
|
+
column.key
|
|
2019
|
+
)) }) }),
|
|
2020
|
+
/* @__PURE__ */ jsx24("tbody", { children: records.map((record) => /* @__PURE__ */ jsx24("tr", { children: columns.map((column, i) => /* @__PURE__ */ jsx24(
|
|
2021
|
+
"td",
|
|
2022
|
+
{
|
|
2023
|
+
"data-secondary": column.secondary || void 0,
|
|
2024
|
+
"data-align": column.align,
|
|
2025
|
+
children: i === 0 && onOpen ? /* @__PURE__ */ jsx24(
|
|
2026
|
+
"button",
|
|
2027
|
+
{
|
|
2028
|
+
type: "button",
|
|
2029
|
+
className: "coline-row-open",
|
|
2030
|
+
onClick: () => onOpen(record),
|
|
2031
|
+
children: column.render(record)
|
|
2032
|
+
}
|
|
2033
|
+
) : column.render(record)
|
|
2034
|
+
},
|
|
2035
|
+
column.key
|
|
2036
|
+
)) }, rowKey(record))) })
|
|
2037
|
+
] }) });
|
|
2038
|
+
}
|
|
2039
|
+
function Board({
|
|
2040
|
+
children,
|
|
2041
|
+
label = "Board"
|
|
2042
|
+
}) {
|
|
2043
|
+
return /* @__PURE__ */ jsx24("div", { className: "coline-board", role: "region", "aria-label": label, tabIndex: 0, children });
|
|
2044
|
+
}
|
|
2045
|
+
function BoardColumn({
|
|
2046
|
+
title,
|
|
2047
|
+
count,
|
|
2048
|
+
children,
|
|
2049
|
+
action
|
|
2050
|
+
}) {
|
|
2051
|
+
return /* @__PURE__ */ jsxs6("section", { className: "coline-board-column", children: [
|
|
2052
|
+
/* @__PURE__ */ jsxs6("header", { children: [
|
|
2053
|
+
/* @__PURE__ */ jsx24("h2", { children: title }),
|
|
2054
|
+
count !== void 0 && /* @__PURE__ */ jsx24("span", { className: "coline-count", children: count }),
|
|
2055
|
+
action
|
|
2056
|
+
] }),
|
|
2057
|
+
/* @__PURE__ */ jsx24("div", { className: "coline-board-items", children })
|
|
2058
|
+
] });
|
|
2059
|
+
}
|
|
2060
|
+
function BoardCard({
|
|
2061
|
+
title,
|
|
2062
|
+
children,
|
|
2063
|
+
footer,
|
|
2064
|
+
onOpen
|
|
2065
|
+
}) {
|
|
2066
|
+
return /* @__PURE__ */ jsxs6("article", { className: "coline-board-card", children: [
|
|
2067
|
+
/* @__PURE__ */ jsx24("h3", { children: onOpen ? /* @__PURE__ */ jsx24("button", { type: "button", className: "coline-row-open", onClick: onOpen, children: title }) : title }),
|
|
2068
|
+
children && /* @__PURE__ */ jsx24("div", { className: "coline-board-card-body", children }),
|
|
2069
|
+
footer && /* @__PURE__ */ jsx24("footer", { children: footer })
|
|
2070
|
+
] });
|
|
2071
|
+
}
|
|
2072
|
+
function SettingsSection({
|
|
2073
|
+
title,
|
|
2074
|
+
description,
|
|
2075
|
+
children
|
|
2076
|
+
}) {
|
|
2077
|
+
const id = React23.useId();
|
|
2078
|
+
return /* @__PURE__ */ jsxs6("section", { className: "coline-settings-section", "aria-labelledby": id, children: [
|
|
2079
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
2080
|
+
/* @__PURE__ */ jsx24("h2", { id, children: title }),
|
|
2081
|
+
description && /* @__PURE__ */ jsx24("p", { children: description })
|
|
2082
|
+
] }),
|
|
2083
|
+
/* @__PURE__ */ jsx24("div", { className: "coline-settings-fields", children })
|
|
2084
|
+
] });
|
|
2085
|
+
}
|
|
1860
2086
|
export {
|
|
2087
|
+
AppErrorState,
|
|
2088
|
+
AppLoadingState,
|
|
2089
|
+
AppPage,
|
|
1861
2090
|
Badge,
|
|
2091
|
+
Board,
|
|
2092
|
+
BoardCard,
|
|
2093
|
+
BoardColumn,
|
|
1862
2094
|
Button,
|
|
1863
2095
|
Card,
|
|
1864
2096
|
CardAction,
|
|
@@ -1869,6 +2101,7 @@ export {
|
|
|
1869
2101
|
CardTitle,
|
|
1870
2102
|
Checkbox,
|
|
1871
2103
|
ColineAppProvider,
|
|
2104
|
+
DetailPanel,
|
|
1872
2105
|
Dialog,
|
|
1873
2106
|
DialogClose,
|
|
1874
2107
|
DialogContent,
|
|
@@ -1894,6 +2127,7 @@ export {
|
|
|
1894
2127
|
DropdownMenuSubContent,
|
|
1895
2128
|
DropdownMenuSubTrigger,
|
|
1896
2129
|
DropdownMenuTrigger,
|
|
2130
|
+
EmptyState,
|
|
1897
2131
|
Field,
|
|
1898
2132
|
FieldContent,
|
|
1899
2133
|
FieldDescription,
|
|
@@ -1906,6 +2140,7 @@ export {
|
|
|
1906
2140
|
FieldTitle,
|
|
1907
2141
|
Input,
|
|
1908
2142
|
Label,
|
|
2143
|
+
PageToolbar,
|
|
1909
2144
|
Popover,
|
|
1910
2145
|
PopoverAnchor,
|
|
1911
2146
|
PopoverContent,
|
|
@@ -1914,6 +2149,7 @@ export {
|
|
|
1914
2149
|
PopoverTitle,
|
|
1915
2150
|
PopoverTrigger,
|
|
1916
2151
|
Progress,
|
|
2152
|
+
RecordTable,
|
|
1917
2153
|
Select,
|
|
1918
2154
|
SelectContent,
|
|
1919
2155
|
SelectGroup,
|
|
@@ -1925,8 +2161,11 @@ export {
|
|
|
1925
2161
|
SelectTrigger,
|
|
1926
2162
|
SelectValue,
|
|
1927
2163
|
Separator,
|
|
2164
|
+
SettingsSection,
|
|
1928
2165
|
Skeleton,
|
|
1929
2166
|
Slider,
|
|
2167
|
+
SplitView,
|
|
2168
|
+
StatusBadge,
|
|
1930
2169
|
Switch,
|
|
1931
2170
|
TABS_LAYOUT_SPRING,
|
|
1932
2171
|
Table,
|
|
@@ -1956,6 +2195,7 @@ export {
|
|
|
1956
2195
|
useColine,
|
|
1957
2196
|
useColineContext,
|
|
1958
2197
|
useColineQuery,
|
|
1959
|
-
useColorScheme
|
|
2198
|
+
useColorScheme,
|
|
2199
|
+
useLiveCollection
|
|
1960
2200
|
};
|
|
1961
2201
|
//# sourceMappingURL=index.js.map
|