@colineapp/ui 0.3.1 → 0.4.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.
- package/AGENTS.md +45 -4
- package/README.md +84 -0
- package/dist/index.d.ts +118 -8
- package/dist/index.js +331 -112
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +10 -5
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,45 @@ 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.
|
|
103
|
+
|
|
104
|
+
## UI 0.4.1 defaults
|
|
105
|
+
|
|
106
|
+
Use `Tabs` / `TabsList` / `TabsTrigger` / `TabsContent` for app views. The raised
|
|
107
|
+
sliding selection and content transition are automatic. Do not recreate tab
|
|
108
|
+
buttons or choose the opt-in line variant for standard Coline navigation.
|
|
109
|
+
Use `FilterMenu` for value filters, and `DropdownMenu` for actions. Both use the
|
|
110
|
+
canonical Coline menu surface and highlight. `pnpm check:parity` enforces the
|
|
111
|
+
vendored dropdown implementation; `pnpm sync:platform` refreshes it.
|
|
112
|
+
Keep animation CSS in the package, respect reduced motion, and verify controls
|
|
113
|
+
in a portalled dialog as well as on the page. A form submit button needs explicit
|
|
114
|
+
`type="submit"`. Do not restyle shared controls with app-specific CSS.
|
package/README.md
CHANGED
|
@@ -64,3 +64,87 @@ 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.
|
|
114
|
+
|
|
115
|
+
## Shared controls and motion (0.4.1)
|
|
116
|
+
|
|
117
|
+
`Tabs` uses the same raised selection as Coline and Upstream. Selection springs
|
|
118
|
+
and content transitions are automatic; no indicator or animation wrapper is
|
|
119
|
+
required. Each tabs group owns its indicator so multiple groups never collide.
|
|
120
|
+
`TabsIndicator` remains available for existing custom compositions.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
<Tabs defaultValue="inbox">
|
|
124
|
+
<TabsList aria-label="Views">
|
|
125
|
+
<TabsTrigger value="inbox">Inbox</TabsTrigger>
|
|
126
|
+
<TabsTrigger value="roadmap">Roadmap</TabsTrigger>
|
|
127
|
+
</TabsList>
|
|
128
|
+
<TabsContent value="inbox">{/* Inbox */}</TabsContent>
|
|
129
|
+
<TabsContent value="roadmap">{/* Roadmap */}</TabsContent>
|
|
130
|
+
</Tabs>
|
|
131
|
+
<FilterMenu
|
|
132
|
+
aria-label="Filter by status"
|
|
133
|
+
value={status}
|
|
134
|
+
onValueChange={setStatus}
|
|
135
|
+
options={[{ value: "all", label: "All statuses" }, { value: "planned", label: "Planned" }]}
|
|
136
|
+
/>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`FilterMenu` composes the exact Coline `DropdownMenu` radio group, surface, and
|
|
140
|
+
sliding highlight. Use `DropdownMenu` directly for action menus. `PageToolbar`
|
|
141
|
+
is borderless. `RecordTable` uses separated, rounded selection/hover rows.
|
|
142
|
+
Dialogs and menus include their animation CSS; the provider respects reduced
|
|
143
|
+
motion, including portals. Buttons default to `type="button"`; use
|
|
144
|
+
`type="submit"` for a form's submit action.
|
|
145
|
+
|
|
146
|
+
Use component defaults rather than copying their CSS into the app. Custom CSS
|
|
147
|
+
variables scoped to `AppPage` do not reach portalled dialogs/menus. Keep decorative
|
|
148
|
+
app variables at `:root` when they must cross portals, and retain host theme tokens.
|
|
149
|
+
App bundles include their dependencies: upgrade, rebuild and push to adopt a UI
|
|
150
|
+
release. Updating npm does not rewrite already-published app bundles.
|
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";
|
|
@@ -167,21 +168,21 @@ declare function TableHead({ className, ...props }: React$1.ComponentProps<"th">
|
|
|
167
168
|
declare function TableCell({ className, ...props }: React$1.ComponentProps<"td">): React$1.JSX.Element;
|
|
168
169
|
declare function TableCaption({ className, ...props }: React$1.ComponentProps<"caption">): React$1.JSX.Element;
|
|
169
170
|
|
|
170
|
-
/**
|
|
171
|
+
/** Same raised selection and spring as Coline and Upstream navigation. */
|
|
171
172
|
declare const TABS_LAYOUT_SPRING: {
|
|
172
173
|
type: "spring";
|
|
173
174
|
stiffness: number;
|
|
174
175
|
damping: number;
|
|
175
176
|
mass: number;
|
|
176
177
|
};
|
|
177
|
-
declare function Tabs({ className, orientation, ...props }: React$1.ComponentProps<typeof Tabs$1.Root>): React$1.JSX.Element;
|
|
178
|
+
declare function Tabs({ className, orientation, value, defaultValue, onValueChange, ...props }: React$1.ComponentProps<typeof Tabs$1.Root>): React$1.JSX.Element;
|
|
178
179
|
declare const tabsListVariants: (props?: ({
|
|
179
180
|
variant?: "default" | "line" | null | undefined;
|
|
180
181
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
181
182
|
declare function TabsList({ className, variant, ...props }: React$1.ComponentProps<typeof Tabs$1.List> & VariantProps<typeof tabsListVariants>): React$1.JSX.Element;
|
|
182
|
-
declare function TabsTrigger({ className, ...props }: React$1.ComponentProps<typeof Tabs$1.Trigger>): React$1.JSX.Element;
|
|
183
|
-
/**
|
|
184
|
-
declare function TabsIndicator({ className, layoutId
|
|
183
|
+
declare function TabsTrigger({ className, children, value, asChild, ...props }: React$1.ComponentProps<typeof Tabs$1.Trigger>): React$1.JSX.Element;
|
|
184
|
+
/** Optional customization; the raised indicator is included automatically. */
|
|
185
|
+
declare function TabsIndicator({ className, layoutId }: {
|
|
185
186
|
className?: string;
|
|
186
187
|
layoutId?: string;
|
|
187
188
|
}): React$1.JSX.Element;
|
|
@@ -200,4 +201,113 @@ 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
|
+
/** A value picker using the same dropdown and sliding highlight as Coline. */
|
|
300
|
+
declare const FilterMenu: React$1.ForwardRefExoticComponent<{
|
|
301
|
+
value: string;
|
|
302
|
+
options: readonly {
|
|
303
|
+
value: string;
|
|
304
|
+
label: string;
|
|
305
|
+
disabled?: boolean;
|
|
306
|
+
}[];
|
|
307
|
+
onValueChange: (value: string) => void;
|
|
308
|
+
"aria-label": string;
|
|
309
|
+
disabled?: boolean;
|
|
310
|
+
className?: string;
|
|
311
|
+
} & React$1.RefAttributes<HTMLButtonElement>>;
|
|
312
|
+
|
|
313
|
+
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, FilterMenu, 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 };
|