@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/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ function cn(...inputs) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
// src/provider.tsx
|
|
11
|
+
import { MotionConfig } from "framer-motion";
|
|
11
12
|
import * as React from "react";
|
|
12
13
|
import {
|
|
13
14
|
connectGuestBridge
|
|
@@ -24,18 +25,22 @@ function applyTheme(theme, colorScheme) {
|
|
|
24
25
|
root.classList.toggle("dark", colorScheme === "dark");
|
|
25
26
|
}
|
|
26
27
|
function ColineAppProvider({ children }) {
|
|
28
|
+
const [connectionError, setConnectionError] = React.useState(null);
|
|
27
29
|
const [runtime, setRuntime] = React.useState(null);
|
|
28
30
|
React.useEffect(() => {
|
|
29
31
|
let disposed = false;
|
|
32
|
+
let activeBridge = null;
|
|
30
33
|
let removeThemeListener = null;
|
|
31
34
|
void connectGuestBridge().then((bridge) => {
|
|
32
|
-
if (disposed)
|
|
35
|
+
if (disposed) {
|
|
36
|
+
bridge.dispose();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
activeBridge = bridge;
|
|
33
40
|
applyTheme(bridge.theme, bridge.colorScheme);
|
|
34
41
|
removeThemeListener = bridge.onThemeChange((theme, colorScheme) => {
|
|
35
42
|
applyTheme(theme, colorScheme);
|
|
36
|
-
setRuntime(
|
|
37
|
-
(current) => current ? { ...current, colorScheme } : current
|
|
38
|
-
);
|
|
43
|
+
setRuntime((current) => current ? { ...current, colorScheme } : current);
|
|
39
44
|
});
|
|
40
45
|
setRuntime({
|
|
41
46
|
bridge,
|
|
@@ -43,9 +48,12 @@ function ColineAppProvider({ children }) {
|
|
|
43
48
|
context: bridge.context,
|
|
44
49
|
colorScheme: bridge.colorScheme
|
|
45
50
|
});
|
|
51
|
+
}).catch((error) => {
|
|
52
|
+
if (!disposed) setConnectionError(error instanceof Error ? error.message : String(error));
|
|
46
53
|
});
|
|
47
54
|
return () => {
|
|
48
55
|
disposed = true;
|
|
56
|
+
activeBridge?.dispose();
|
|
49
57
|
removeThemeListener?.();
|
|
50
58
|
};
|
|
51
59
|
}, []);
|
|
@@ -58,9 +66,9 @@ function ColineAppProvider({ children }) {
|
|
|
58
66
|
return () => observer.disconnect();
|
|
59
67
|
}, [runtime]);
|
|
60
68
|
if (!runtime) {
|
|
61
|
-
return
|
|
69
|
+
return /* @__PURE__ */ jsx("p", { role: connectionError ? "alert" : "status", children: connectionError ?? "Connecting to Coline\u2026" });
|
|
62
70
|
}
|
|
63
|
-
return /* @__PURE__ */ jsx(ColineRuntimeContext.Provider, { value: runtime, children });
|
|
71
|
+
return /* @__PURE__ */ jsx(ColineRuntimeContext.Provider, { value: runtime, children: /* @__PURE__ */ jsx(MotionConfig, { reducedMotion: "user", children }) });
|
|
64
72
|
}
|
|
65
73
|
function useColine() {
|
|
66
74
|
const runtime = React.useContext(ColineRuntimeContext);
|
|
@@ -158,7 +166,7 @@ import { cva as cva2 } from "class-variance-authority";
|
|
|
158
166
|
import { Slot as Slot2 } from "radix-ui";
|
|
159
167
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
160
168
|
var buttonVariants = cva2(
|
|
161
|
-
"group/button inline-flex shrink-0 items-center justify-center rounded-4xl border border-white/20 text-sm font-medium whitespace-nowrap transition-[color,background-color,border-color] duration-
|
|
169
|
+
"coline-button group/button inline-flex shrink-0 items-center justify-center rounded-4xl border border-white/20 text-sm font-medium whitespace-nowrap transition-[color,background-color,border-color,transform,box-shadow] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] outline-none select-none focus-visible:border-ring disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] aria-invalid:ring-destructive/20 dark:border-white/[0.06] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
162
170
|
{
|
|
163
171
|
variants: {
|
|
164
172
|
variant: {
|
|
@@ -191,6 +199,7 @@ var Button = React3.forwardRef(function Button2({
|
|
|
191
199
|
variant = "default",
|
|
192
200
|
size = "default",
|
|
193
201
|
asChild = false,
|
|
202
|
+
type,
|
|
194
203
|
...props
|
|
195
204
|
}, ref) {
|
|
196
205
|
const Comp = asChild ? Slot2.Root : "button";
|
|
@@ -198,6 +207,7 @@ var Button = React3.forwardRef(function Button2({
|
|
|
198
207
|
Comp,
|
|
199
208
|
{
|
|
200
209
|
ref,
|
|
210
|
+
...!asChild ? { type: type ?? "button" } : type ? { type } : {},
|
|
201
211
|
"data-slot": "button",
|
|
202
212
|
"data-variant": variant,
|
|
203
213
|
"data-size": size,
|
|
@@ -332,6 +342,11 @@ function Checkbox({
|
|
|
332
342
|
import "react";
|
|
333
343
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
334
344
|
import { IconX } from "@tabler/icons-react";
|
|
345
|
+
|
|
346
|
+
// src/components/liquid-menu-surface.ts
|
|
347
|
+
var liquidMenuSurfaceClasses = "rounded-2xl bg-popover/75 dark:bg-zinc-900/75 backdrop-blur-[3px] border border-black/[0.08] text-popover-foreground shadow-[0_4px_16px_-4px_rgba(0,0,0,0.08),0_16px_48px_-12px_rgba(0,0,0,0.28)] dark:border-white/[0.09] dark:bg-[#141417] dark:shadow-[0_4px_16px_-4px_rgba(0,0,0,0.4),0_16px_48px_-12px_rgba(0,0,0,0.7)]";
|
|
348
|
+
|
|
349
|
+
// src/components/dialog.tsx
|
|
335
350
|
import { jsx as jsx6, jsxs } from "react/jsx-runtime";
|
|
336
351
|
function Dialog({
|
|
337
352
|
...props
|
|
@@ -362,7 +377,7 @@ function DialogOverlay({
|
|
|
362
377
|
{
|
|
363
378
|
"data-slot": "dialog-overlay",
|
|
364
379
|
className: cn(
|
|
365
|
-
"fixed inset-0 isolate z-50 bg-black/30 supports-backdrop-filter:backdrop-blur-sm",
|
|
380
|
+
"coline-dialog-overlay fixed inset-0 isolate z-50 bg-black/30 supports-backdrop-filter:backdrop-blur-sm",
|
|
366
381
|
className
|
|
367
382
|
),
|
|
368
383
|
...props
|
|
@@ -383,15 +398,16 @@ function DialogContent({
|
|
|
383
398
|
"data-slot": "dialog-content",
|
|
384
399
|
className: cn(
|
|
385
400
|
// Mobile: bottom-sheet style, pinned to bottom with slide-up
|
|
386
|
-
"fixed z-50 grid w-full gap-4
|
|
387
|
-
|
|
401
|
+
"coline-dialog-content fixed z-50 grid w-full gap-4 p-4 text-sm outline-none",
|
|
402
|
+
liquidMenuSurfaceClasses,
|
|
403
|
+
"inset-x-0 bottom-0 max-h-[85dvh] overflow-y-auto rounded-b-none pb-[max(1rem,env(safe-area-inset-bottom))]",
|
|
388
404
|
// Desktop: centered modal
|
|
389
|
-
"sm:inset-x-auto sm:bottom-auto sm:top-1/2 sm:left-1/2 sm:max-w-md sm:max-h-[calc(100dvh-4rem)] sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-
|
|
405
|
+
"sm:inset-x-auto sm:bottom-auto sm:top-1/2 sm:left-1/2 sm:max-w-md sm:max-h-[calc(100dvh-4rem)] sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-2xl sm:p-6 sm:gap-6 sm:pb-6",
|
|
390
406
|
className
|
|
391
407
|
),
|
|
392
408
|
...props,
|
|
393
409
|
children: [
|
|
394
|
-
/* @__PURE__ */ jsx6("div", { className: "mx-auto h-1 w-10 shrink-0 rounded-full bg-muted-foreground/30 sm:hidden" }),
|
|
410
|
+
/* @__PURE__ */ jsx6("div", { className: "mx-auto h-1 w-10 shrink-0 rounded-full bg-muted-foreground/30 sm:hidden", "aria-hidden": "true" }),
|
|
395
411
|
children,
|
|
396
412
|
showCloseButton && /* @__PURE__ */ jsx6(DialogPrimitive.Close, { "data-slot": "dialog-close", asChild: true, children: /* @__PURE__ */ jsxs(
|
|
397
413
|
Button,
|
|
@@ -415,7 +431,7 @@ function DialogHeader({ className, ...props }) {
|
|
|
415
431
|
"div",
|
|
416
432
|
{
|
|
417
433
|
"data-slot": "dialog-header",
|
|
418
|
-
className: cn("flex flex-col gap-2", className),
|
|
434
|
+
className: cn("flex flex-col gap-2 pr-8", className),
|
|
419
435
|
...props
|
|
420
436
|
}
|
|
421
437
|
);
|
|
@@ -477,9 +493,6 @@ import * as React8 from "react";
|
|
|
477
493
|
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
|
|
478
494
|
import { IconCheck as IconCheck2, IconChevronRight } from "@tabler/icons-react";
|
|
479
495
|
|
|
480
|
-
// src/components/liquid-menu-surface.ts
|
|
481
|
-
var liquidMenuSurfaceClasses = "rounded-2xl bg-popover/75 dark:bg-zinc-900/75 backdrop-blur-[3px] border border-black/[0.08] text-popover-foreground shadow-[0_4px_16px_-4px_rgba(0,0,0,0.08),0_16px_48px_-12px_rgba(0,0,0,0.28)] dark:border-white/[0.09] dark:bg-[#141417] dark:shadow-[0_4px_16px_-4px_rgba(0,0,0,0.4),0_16px_48px_-12px_rgba(0,0,0,0.7)]";
|
|
482
|
-
|
|
483
496
|
// src/components/menu-highlight.tsx
|
|
484
497
|
import * as React7 from "react";
|
|
485
498
|
import { motion } from "framer-motion";
|
|
@@ -1639,115 +1652,73 @@ function TableCaption({
|
|
|
1639
1652
|
}
|
|
1640
1653
|
|
|
1641
1654
|
// src/components/tabs.tsx
|
|
1642
|
-
import "react";
|
|
1655
|
+
import * as React18 from "react";
|
|
1643
1656
|
import { cva as cva4 } from "class-variance-authority";
|
|
1644
1657
|
import { Tabs as TabsPrimitive } from "radix-ui";
|
|
1645
|
-
import { motion as motion2 } from "framer-motion";
|
|
1646
|
-
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1647
|
-
var TABS_LAYOUT_SPRING = {
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
...props
|
|
1657
|
-
}) {
|
|
1658
|
-
return /* @__PURE__ */ jsx20(
|
|
1658
|
+
import { motion as motion2, useReducedMotion } from "framer-motion";
|
|
1659
|
+
import { Fragment, jsx as jsx20, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1660
|
+
var TABS_LAYOUT_SPRING = { type: "spring", stiffness: 300, damping: 26, mass: 1 };
|
|
1661
|
+
var TabsContext = React18.createContext(null);
|
|
1662
|
+
var ListVariantContext = React18.createContext("default");
|
|
1663
|
+
function Tabs({ className, orientation = "horizontal", value, defaultValue, onValueChange, ...props }) {
|
|
1664
|
+
const [localValue, setLocalValue] = React18.useState(defaultValue);
|
|
1665
|
+
const id = React18.useId();
|
|
1666
|
+
const activeValue = value ?? localValue;
|
|
1667
|
+
const context = React18.useMemo(() => ({ value: activeValue, id }), [activeValue, id]);
|
|
1668
|
+
return /* @__PURE__ */ jsx20(TabsContext.Provider, { value: context, children: /* @__PURE__ */ jsx20(
|
|
1659
1669
|
TabsPrimitive.Root,
|
|
1660
1670
|
{
|
|
1671
|
+
...props,
|
|
1672
|
+
...activeValue === void 0 ? {} : { value: activeValue },
|
|
1673
|
+
orientation,
|
|
1674
|
+
onValueChange: (next) => {
|
|
1675
|
+
if (value === void 0) setLocalValue(next);
|
|
1676
|
+
onValueChange?.(next);
|
|
1677
|
+
},
|
|
1661
1678
|
"data-slot": "tabs",
|
|
1662
|
-
"
|
|
1663
|
-
className: cn(
|
|
1664
|
-
"group/tabs flex gap-2 data-horizontal:flex-col",
|
|
1665
|
-
className
|
|
1666
|
-
),
|
|
1667
|
-
...props
|
|
1668
|
-
}
|
|
1669
|
-
);
|
|
1670
|
-
}
|
|
1671
|
-
var tabsListVariants = cva4(
|
|
1672
|
-
"group/tabs-list relative inline-flex w-fit items-center justify-center rounded-4xl p-[3px] text-muted-foreground group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col group-data-vertical/tabs:rounded-2xl data-[variant=line]:rounded-none",
|
|
1673
|
-
{
|
|
1674
|
-
variants: {
|
|
1675
|
-
variant: {
|
|
1676
|
-
default: "bg-muted/70 border border-black/4 shadow-[inset_0_1px_2px_rgba(0,0,0,0.06)] dark:bg-white/4 dark:border-white/4 dark:shadow-[inset_0_1px_3px_rgba(0,0,0,0.3)]",
|
|
1677
|
-
line: "gap-1 bg-transparent"
|
|
1678
|
-
}
|
|
1679
|
-
},
|
|
1680
|
-
defaultVariants: {
|
|
1681
|
-
variant: "default"
|
|
1679
|
+
className: cn("coline-tabs", className)
|
|
1682
1680
|
}
|
|
1683
|
-
}
|
|
1684
|
-
);
|
|
1685
|
-
function TabsList({
|
|
1686
|
-
className,
|
|
1687
|
-
variant = "default",
|
|
1688
|
-
...props
|
|
1689
|
-
}) {
|
|
1690
|
-
return /* @__PURE__ */ jsx20(
|
|
1691
|
-
TabsPrimitive.List,
|
|
1692
|
-
{
|
|
1693
|
-
"data-slot": "tabs-list",
|
|
1694
|
-
"data-variant": variant,
|
|
1695
|
-
className: cn(tabsListVariants({ variant }), className),
|
|
1696
|
-
...props
|
|
1697
|
-
}
|
|
1698
|
-
);
|
|
1681
|
+
) });
|
|
1699
1682
|
}
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
})
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
);
|
|
1683
|
+
var tabsListVariants = cva4("coline-tabs-list", {
|
|
1684
|
+
variants: { variant: { default: "coline-tabs-raised", line: "coline-tabs-line" } },
|
|
1685
|
+
defaultVariants: { variant: "default" }
|
|
1686
|
+
});
|
|
1687
|
+
function TabsList({ className, variant = "default", ...props }) {
|
|
1688
|
+
return /* @__PURE__ */ jsx20(ListVariantContext.Provider, { value: variant ?? "default", children: /* @__PURE__ */ jsx20(TabsPrimitive.List, { ...props, "data-slot": "tabs-list", "data-variant": variant, className: cn(tabsListVariants({ variant }), className) }) });
|
|
1689
|
+
}
|
|
1690
|
+
function hasIndicator(children) {
|
|
1691
|
+
return React18.Children.toArray(children).some((child) => React18.isValidElement(child) && (child.type === TabsIndicator || hasIndicator(child.props.children)));
|
|
1692
|
+
}
|
|
1693
|
+
function TabsTrigger({ className, children, value, asChild = false, ...props }) {
|
|
1694
|
+
const tabs = React18.useContext(TabsContext);
|
|
1695
|
+
const variant = React18.useContext(ListVariantContext);
|
|
1696
|
+
const indicator = tabs?.value === value && variant === "default" && !hasIndicator(children) ? /* @__PURE__ */ jsx20(TabsIndicator, {}) : null;
|
|
1697
|
+
const content = asChild && React18.isValidElement(children) ? React18.cloneElement(children, void 0, indicator, children.props.children) : /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
1698
|
+
indicator,
|
|
1699
|
+
children
|
|
1700
|
+
] });
|
|
1701
|
+
return /* @__PURE__ */ jsx20(TabsPrimitive.Trigger, { ...props, value, asChild, "data-slot": "tabs-trigger", className: cn("coline-tabs-trigger", className), children: content });
|
|
1718
1702
|
}
|
|
1719
|
-
function TabsIndicator({
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1703
|
+
function TabsIndicator({ className, layoutId = "selection" }) {
|
|
1704
|
+
const tabs = React18.useContext(TabsContext);
|
|
1705
|
+
const fallbackId = React18.useId();
|
|
1706
|
+
const reducedMotion = useReducedMotion();
|
|
1723
1707
|
return /* @__PURE__ */ jsx20(
|
|
1724
1708
|
motion2.div,
|
|
1725
1709
|
{
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
),
|
|
1732
|
-
transition: TABS_LAYOUT_SPRING
|
|
1710
|
+
"aria-hidden": "true",
|
|
1711
|
+
"data-slot": "tabs-indicator",
|
|
1712
|
+
layout: true,
|
|
1713
|
+
layoutId: `${tabs?.id ?? fallbackId}-${layoutId}`,
|
|
1714
|
+
initial: false,
|
|
1715
|
+
className: cn("coline-tabs-indicator", className),
|
|
1716
|
+
transition: reducedMotion ? { duration: 0 } : TABS_LAYOUT_SPRING
|
|
1733
1717
|
}
|
|
1734
1718
|
);
|
|
1735
1719
|
}
|
|
1736
|
-
function TabsContent({
|
|
1737
|
-
className,
|
|
1738
|
-
...props
|
|
1739
|
-
}) {
|
|
1740
|
-
return /* @__PURE__ */ jsx20(
|
|
1741
|
-
TabsPrimitive.Content,
|
|
1742
|
-
{
|
|
1743
|
-
"data-slot": "tabs-content",
|
|
1744
|
-
className: cn(
|
|
1745
|
-
"flex-1 text-sm outline-none animate-in fade-in-0 slide-in-from-bottom-0.5 duration-100 ease-out",
|
|
1746
|
-
className
|
|
1747
|
-
),
|
|
1748
|
-
...props
|
|
1749
|
-
}
|
|
1750
|
-
);
|
|
1720
|
+
function TabsContent({ className, ...props }) {
|
|
1721
|
+
return /* @__PURE__ */ jsx20(TabsPrimitive.Content, { ...props, "data-slot": "tabs-content", className: cn("coline-tabs-content", className) });
|
|
1751
1722
|
}
|
|
1752
1723
|
|
|
1753
1724
|
// src/components/textarea.tsx
|
|
@@ -1857,8 +1828,247 @@ function TooltipContent({
|
|
|
1857
1828
|
}
|
|
1858
1829
|
) });
|
|
1859
1830
|
}
|
|
1831
|
+
|
|
1832
|
+
// src/live-collection.ts
|
|
1833
|
+
import * as React22 from "react";
|
|
1834
|
+
import {
|
|
1835
|
+
createLiveCollection
|
|
1836
|
+
} from "@colineapp/sdk/v2";
|
|
1837
|
+
function useLiveCollection(name, query, options) {
|
|
1838
|
+
const coline = useColine();
|
|
1839
|
+
const context = useColineContext();
|
|
1840
|
+
const key = JSON.stringify({
|
|
1841
|
+
query,
|
|
1842
|
+
options: { actorUserId: context.actor?.userId, installId: context.app.installId, ...options }
|
|
1843
|
+
});
|
|
1844
|
+
const live = React22.useMemo(() => {
|
|
1845
|
+
const input = JSON.parse(key);
|
|
1846
|
+
return createLiveCollection(coline, name, input.query, input.options);
|
|
1847
|
+
}, [coline, name, key]);
|
|
1848
|
+
React22.useEffect(() => {
|
|
1849
|
+
void live.start();
|
|
1850
|
+
return () => live.stop();
|
|
1851
|
+
}, [live]);
|
|
1852
|
+
const snapshot = React22.useSyncExternalStore(live.subscribe, live.getSnapshot, live.getSnapshot);
|
|
1853
|
+
return {
|
|
1854
|
+
...snapshot,
|
|
1855
|
+
insert: live.insert,
|
|
1856
|
+
update: live.update,
|
|
1857
|
+
delete: live.delete,
|
|
1858
|
+
setAccess: live.setAccess,
|
|
1859
|
+
refresh: live.refresh
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
// src/patterns/workspace.tsx
|
|
1864
|
+
import * as React23 from "react";
|
|
1865
|
+
import { Fragment as Fragment2, jsx as jsx24, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1866
|
+
function AppPage({
|
|
1867
|
+
title,
|
|
1868
|
+
description,
|
|
1869
|
+
eyebrow,
|
|
1870
|
+
actions,
|
|
1871
|
+
children,
|
|
1872
|
+
width = "wide",
|
|
1873
|
+
className
|
|
1874
|
+
}) {
|
|
1875
|
+
return /* @__PURE__ */ jsxs7("main", { className: cn("coline-page", className), "data-width": width, children: [
|
|
1876
|
+
/* @__PURE__ */ jsxs7("header", { className: "coline-page-header", children: [
|
|
1877
|
+
/* @__PURE__ */ jsxs7("div", { className: "coline-page-heading", children: [
|
|
1878
|
+
eyebrow && /* @__PURE__ */ jsx24("div", { className: "coline-eyebrow", children: eyebrow }),
|
|
1879
|
+
/* @__PURE__ */ jsx24("h1", { children: title }),
|
|
1880
|
+
description && /* @__PURE__ */ jsx24("p", { className: "coline-page-description", children: description })
|
|
1881
|
+
] }),
|
|
1882
|
+
actions && /* @__PURE__ */ jsx24("div", { className: "coline-page-actions", children: actions })
|
|
1883
|
+
] }),
|
|
1884
|
+
children
|
|
1885
|
+
] });
|
|
1886
|
+
}
|
|
1887
|
+
function PageToolbar({
|
|
1888
|
+
children,
|
|
1889
|
+
label = "View controls",
|
|
1890
|
+
className
|
|
1891
|
+
}) {
|
|
1892
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("coline-toolbar", className), role: "group", "aria-label": label, children });
|
|
1893
|
+
}
|
|
1894
|
+
function EmptyState({
|
|
1895
|
+
title,
|
|
1896
|
+
description,
|
|
1897
|
+
action,
|
|
1898
|
+
icon
|
|
1899
|
+
}) {
|
|
1900
|
+
return /* @__PURE__ */ jsxs7("section", { className: "coline-empty", children: [
|
|
1901
|
+
icon && /* @__PURE__ */ jsx24("div", { className: "coline-empty-icon", "aria-hidden": "true", children: icon }),
|
|
1902
|
+
/* @__PURE__ */ jsx24("h2", { children: title }),
|
|
1903
|
+
description && /* @__PURE__ */ jsx24("p", { children: description }),
|
|
1904
|
+
action && /* @__PURE__ */ jsx24("div", { children: action })
|
|
1905
|
+
] });
|
|
1906
|
+
}
|
|
1907
|
+
function AppErrorState({ message, onRetry }) {
|
|
1908
|
+
return /* @__PURE__ */ jsxs7("section", { className: "coline-error", role: "alert", children: [
|
|
1909
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1910
|
+
/* @__PURE__ */ jsx24("h2", { children: "Something went wrong" }),
|
|
1911
|
+
/* @__PURE__ */ jsx24("p", { children: message })
|
|
1912
|
+
] }),
|
|
1913
|
+
onRetry && /* @__PURE__ */ jsx24(Button, { variant: "outline", onClick: onRetry, children: "Try again" })
|
|
1914
|
+
] });
|
|
1915
|
+
}
|
|
1916
|
+
function AppLoadingState({
|
|
1917
|
+
label = "Loading",
|
|
1918
|
+
rows = 5
|
|
1919
|
+
}) {
|
|
1920
|
+
return /* @__PURE__ */ jsxs7("div", { className: "coline-loading", role: "status", "aria-label": label, children: [
|
|
1921
|
+
Array.from({ length: Math.max(1, Math.min(rows, 12)) }, (_, i) => /* @__PURE__ */ jsx24("div", { style: { width: `${92 - i % 3 * 14}%` } }, i)),
|
|
1922
|
+
/* @__PURE__ */ jsx24("span", { className: "coline-sr-only", children: label })
|
|
1923
|
+
] });
|
|
1924
|
+
}
|
|
1925
|
+
function StatusBadge({
|
|
1926
|
+
children,
|
|
1927
|
+
tone = "neutral"
|
|
1928
|
+
}) {
|
|
1929
|
+
return /* @__PURE__ */ jsxs7("span", { className: "coline-status", "data-tone": tone, children: [
|
|
1930
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": "true" }),
|
|
1931
|
+
children
|
|
1932
|
+
] });
|
|
1933
|
+
}
|
|
1934
|
+
function SplitView({
|
|
1935
|
+
list,
|
|
1936
|
+
detail,
|
|
1937
|
+
label = "Details"
|
|
1938
|
+
}) {
|
|
1939
|
+
return /* @__PURE__ */ jsxs7("div", { className: "coline-split", "data-open": Boolean(detail), children: [
|
|
1940
|
+
/* @__PURE__ */ jsx24("section", { className: "coline-split-list", children: list }),
|
|
1941
|
+
detail && /* @__PURE__ */ jsx24("aside", { className: "coline-split-detail", "aria-label": label, children: detail })
|
|
1942
|
+
] });
|
|
1943
|
+
}
|
|
1944
|
+
function DetailPanel({
|
|
1945
|
+
title,
|
|
1946
|
+
subtitle,
|
|
1947
|
+
onClose,
|
|
1948
|
+
children,
|
|
1949
|
+
actions
|
|
1950
|
+
}) {
|
|
1951
|
+
return /* @__PURE__ */ jsxs7("section", { className: "coline-detail", children: [
|
|
1952
|
+
/* @__PURE__ */ jsxs7("header", { children: [
|
|
1953
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1954
|
+
subtitle && /* @__PURE__ */ jsx24("div", { className: "coline-eyebrow", children: subtitle }),
|
|
1955
|
+
/* @__PURE__ */ jsx24("h2", { children: title })
|
|
1956
|
+
] }),
|
|
1957
|
+
onClose && /* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close details", children: "Close" })
|
|
1958
|
+
] }),
|
|
1959
|
+
/* @__PURE__ */ jsx24("div", { className: "coline-detail-body", children }),
|
|
1960
|
+
actions && /* @__PURE__ */ jsx24("footer", { children: actions })
|
|
1961
|
+
] });
|
|
1962
|
+
}
|
|
1963
|
+
function RecordTable({
|
|
1964
|
+
records,
|
|
1965
|
+
columns,
|
|
1966
|
+
rowKey,
|
|
1967
|
+
onOpen,
|
|
1968
|
+
label = "Records",
|
|
1969
|
+
empty
|
|
1970
|
+
}) {
|
|
1971
|
+
if (!records.length)
|
|
1972
|
+
return /* @__PURE__ */ jsx24(Fragment2, { children: empty ?? /* @__PURE__ */ jsx24(EmptyState, { title: "No results", description: "Try changing your filters." }) });
|
|
1973
|
+
return /* @__PURE__ */ jsx24("div", { className: "coline-table-scroll", children: /* @__PURE__ */ jsxs7("table", { className: "coline-record-table", "aria-label": label, children: [
|
|
1974
|
+
/* @__PURE__ */ jsx24("thead", { children: /* @__PURE__ */ jsx24("tr", { children: columns.map((column) => /* @__PURE__ */ jsx24(
|
|
1975
|
+
"th",
|
|
1976
|
+
{
|
|
1977
|
+
scope: "col",
|
|
1978
|
+
"data-secondary": column.secondary || void 0,
|
|
1979
|
+
"data-align": column.align,
|
|
1980
|
+
children: column.label
|
|
1981
|
+
},
|
|
1982
|
+
column.key
|
|
1983
|
+
)) }) }),
|
|
1984
|
+
/* @__PURE__ */ jsx24("tbody", { children: records.map((record) => /* @__PURE__ */ jsx24("tr", { children: columns.map((column, i) => /* @__PURE__ */ jsx24(
|
|
1985
|
+
"td",
|
|
1986
|
+
{
|
|
1987
|
+
"data-secondary": column.secondary || void 0,
|
|
1988
|
+
"data-align": column.align,
|
|
1989
|
+
children: i === 0 && onOpen ? /* @__PURE__ */ jsx24(
|
|
1990
|
+
"button",
|
|
1991
|
+
{
|
|
1992
|
+
type: "button",
|
|
1993
|
+
className: "coline-row-open",
|
|
1994
|
+
onClick: () => onOpen(record),
|
|
1995
|
+
children: column.render(record)
|
|
1996
|
+
}
|
|
1997
|
+
) : column.render(record)
|
|
1998
|
+
},
|
|
1999
|
+
column.key
|
|
2000
|
+
)) }, rowKey(record))) })
|
|
2001
|
+
] }) });
|
|
2002
|
+
}
|
|
2003
|
+
function Board({
|
|
2004
|
+
children,
|
|
2005
|
+
label = "Board"
|
|
2006
|
+
}) {
|
|
2007
|
+
return /* @__PURE__ */ jsx24("div", { className: "coline-board", role: "region", "aria-label": label, tabIndex: 0, children });
|
|
2008
|
+
}
|
|
2009
|
+
function BoardColumn({
|
|
2010
|
+
title,
|
|
2011
|
+
count,
|
|
2012
|
+
children,
|
|
2013
|
+
action
|
|
2014
|
+
}) {
|
|
2015
|
+
return /* @__PURE__ */ jsxs7("section", { className: "coline-board-column", children: [
|
|
2016
|
+
/* @__PURE__ */ jsxs7("header", { children: [
|
|
2017
|
+
/* @__PURE__ */ jsx24("h2", { children: title }),
|
|
2018
|
+
count !== void 0 && /* @__PURE__ */ jsx24("span", { className: "coline-count", children: count }),
|
|
2019
|
+
action
|
|
2020
|
+
] }),
|
|
2021
|
+
/* @__PURE__ */ jsx24("div", { className: "coline-board-items", children })
|
|
2022
|
+
] });
|
|
2023
|
+
}
|
|
2024
|
+
function BoardCard({
|
|
2025
|
+
title,
|
|
2026
|
+
children,
|
|
2027
|
+
footer,
|
|
2028
|
+
onOpen
|
|
2029
|
+
}) {
|
|
2030
|
+
return /* @__PURE__ */ jsxs7("article", { className: "coline-board-card", children: [
|
|
2031
|
+
/* @__PURE__ */ jsx24("h3", { children: onOpen ? /* @__PURE__ */ jsx24("button", { type: "button", className: "coline-row-open", onClick: onOpen, children: title }) : title }),
|
|
2032
|
+
children && /* @__PURE__ */ jsx24("div", { className: "coline-board-card-body", children }),
|
|
2033
|
+
footer && /* @__PURE__ */ jsx24("footer", { children: footer })
|
|
2034
|
+
] });
|
|
2035
|
+
}
|
|
2036
|
+
function SettingsSection({
|
|
2037
|
+
title,
|
|
2038
|
+
description,
|
|
2039
|
+
children
|
|
2040
|
+
}) {
|
|
2041
|
+
const id = React23.useId();
|
|
2042
|
+
return /* @__PURE__ */ jsxs7("section", { className: "coline-settings-section", "aria-labelledby": id, children: [
|
|
2043
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
2044
|
+
/* @__PURE__ */ jsx24("h2", { id, children: title }),
|
|
2045
|
+
description && /* @__PURE__ */ jsx24("p", { children: description })
|
|
2046
|
+
] }),
|
|
2047
|
+
/* @__PURE__ */ jsx24("div", { className: "coline-settings-fields", children })
|
|
2048
|
+
] });
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
// src/patterns/filter-menu.tsx
|
|
2052
|
+
import * as React24 from "react";
|
|
2053
|
+
import { IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
2054
|
+
import { jsx as jsx25, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2055
|
+
var FilterMenu = React24.forwardRef(function FilterMenu2({ value, options, onValueChange, className, disabled, "aria-label": label }, ref) {
|
|
2056
|
+
return /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
|
|
2057
|
+
/* @__PURE__ */ jsx25(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(Button, { ref, variant: "outline", disabled, "aria-label": label, className: cn("coline-filter-menu", className), children: [
|
|
2058
|
+
/* @__PURE__ */ jsx25("span", { children: options.find((option) => option.value === value)?.label ?? label }),
|
|
2059
|
+
/* @__PURE__ */ jsx25(IconChevronDown2, { "aria-hidden": "true" })
|
|
2060
|
+
] }) }),
|
|
2061
|
+
/* @__PURE__ */ jsx25(DropdownMenuContent, { children: /* @__PURE__ */ jsx25(DropdownMenuRadioGroup, { "aria-label": label, value, onValueChange, children: options.map((option) => /* @__PURE__ */ jsx25(DropdownMenuRadioItem, { value: option.value, disabled: option.disabled ?? false, children: option.label }, option.value)) }) })
|
|
2062
|
+
] });
|
|
2063
|
+
});
|
|
1860
2064
|
export {
|
|
2065
|
+
AppErrorState,
|
|
2066
|
+
AppLoadingState,
|
|
2067
|
+
AppPage,
|
|
1861
2068
|
Badge,
|
|
2069
|
+
Board,
|
|
2070
|
+
BoardCard,
|
|
2071
|
+
BoardColumn,
|
|
1862
2072
|
Button,
|
|
1863
2073
|
Card,
|
|
1864
2074
|
CardAction,
|
|
@@ -1869,6 +2079,7 @@ export {
|
|
|
1869
2079
|
CardTitle,
|
|
1870
2080
|
Checkbox,
|
|
1871
2081
|
ColineAppProvider,
|
|
2082
|
+
DetailPanel,
|
|
1872
2083
|
Dialog,
|
|
1873
2084
|
DialogClose,
|
|
1874
2085
|
DialogContent,
|
|
@@ -1894,6 +2105,7 @@ export {
|
|
|
1894
2105
|
DropdownMenuSubContent,
|
|
1895
2106
|
DropdownMenuSubTrigger,
|
|
1896
2107
|
DropdownMenuTrigger,
|
|
2108
|
+
EmptyState,
|
|
1897
2109
|
Field,
|
|
1898
2110
|
FieldContent,
|
|
1899
2111
|
FieldDescription,
|
|
@@ -1904,8 +2116,10 @@ export {
|
|
|
1904
2116
|
FieldSeparator,
|
|
1905
2117
|
FieldSet,
|
|
1906
2118
|
FieldTitle,
|
|
2119
|
+
FilterMenu,
|
|
1907
2120
|
Input,
|
|
1908
2121
|
Label,
|
|
2122
|
+
PageToolbar,
|
|
1909
2123
|
Popover,
|
|
1910
2124
|
PopoverAnchor,
|
|
1911
2125
|
PopoverContent,
|
|
@@ -1914,6 +2128,7 @@ export {
|
|
|
1914
2128
|
PopoverTitle,
|
|
1915
2129
|
PopoverTrigger,
|
|
1916
2130
|
Progress,
|
|
2131
|
+
RecordTable,
|
|
1917
2132
|
Select,
|
|
1918
2133
|
SelectContent,
|
|
1919
2134
|
SelectGroup,
|
|
@@ -1925,8 +2140,11 @@ export {
|
|
|
1925
2140
|
SelectTrigger,
|
|
1926
2141
|
SelectValue,
|
|
1927
2142
|
Separator,
|
|
2143
|
+
SettingsSection,
|
|
1928
2144
|
Skeleton,
|
|
1929
2145
|
Slider,
|
|
2146
|
+
SplitView,
|
|
2147
|
+
StatusBadge,
|
|
1930
2148
|
Switch,
|
|
1931
2149
|
TABS_LAYOUT_SPRING,
|
|
1932
2150
|
Table,
|
|
@@ -1956,6 +2174,7 @@ export {
|
|
|
1956
2174
|
useColine,
|
|
1957
2175
|
useColineContext,
|
|
1958
2176
|
useColineQuery,
|
|
1959
|
-
useColorScheme
|
|
2177
|
+
useColorScheme,
|
|
2178
|
+
useLiveCollection
|
|
1960
2179
|
};
|
|
1961
2180
|
//# sourceMappingURL=index.js.map
|