@opengeni/react 6.1.0-canary.2 → 6.1.0-canary.4
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/README.md +5 -0
- package/dist/{browser-viewer-NTD6UIPR.js → browser-viewer-LGH4IP47.js} +3 -3
- package/dist/chunk-AWEBVNVX.js +1398 -0
- package/dist/chunk-AWEBVNVX.js.map +1 -0
- package/dist/{chunk-NYESIADM.js → chunk-B7TTSUEW.js} +3 -1
- package/dist/chunk-B7TTSUEW.js.map +1 -0
- package/dist/{chunk-UWVY3OXF.js → chunk-BC7BFCMN.js} +277 -455
- package/dist/chunk-BC7BFCMN.js.map +1 -0
- package/dist/chunk-BRM6FVZA.js +302 -0
- package/dist/chunk-BRM6FVZA.js.map +1 -0
- package/dist/{chunk-KZ4QDBGM.js → chunk-GHSSI2BK.js} +925 -1265
- package/dist/chunk-GHSSI2BK.js.map +1 -0
- package/dist/{chunk-NLTS7JHI.js → chunk-JPHDWKZE.js} +5 -5
- package/dist/{chunk-L5VJYZIW.js → chunk-O53CQZ6T.js} +7 -7
- package/dist/{chunk-24M4YBCL.js → chunk-PNAVEK2U.js} +4 -4
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/composer.js +4 -4
- package/dist/connect-setup.d.ts +2 -0
- package/dist/connect.js +19 -8
- package/dist/connect.js.map +1 -1
- package/dist/index.js +27 -27
- package/dist/interaction.js +2 -2
- package/dist/machines.js +2 -2
- package/dist/plugin-discovery.d.ts +2 -0
- package/dist/realtime.js +20 -20
- package/dist/realtime.js.map +1 -1
- package/dist/session-ui.js +7 -7
- package/dist/session.js +3 -3
- package/package.json +3 -3
- package/src/components/markdown.tsx +13 -21
- package/src/components/preview-loading.tsx +154 -0
- package/src/connect-setup.tsx +17 -5
- package/src/hooks/use-composer.ts +6 -0
- package/src/plugin-discovery.tsx +10 -6
- package/src/realtime/realtime-control.tsx +6 -8
- package/styles/compiled.css +48 -8
- package/styles/index.css +45 -0
- package/dist/chunk-G5JFM6ZE.js +0 -911
- package/dist/chunk-G5JFM6ZE.js.map +0 -1
- package/dist/chunk-HQV2I5HV.js +0 -124
- package/dist/chunk-HQV2I5HV.js.map +0 -1
- package/dist/chunk-KZ4QDBGM.js.map +0 -1
- package/dist/chunk-NYESIADM.js.map +0 -1
- package/dist/chunk-UWVY3OXF.js.map +0 -1
- /package/dist/{browser-viewer-NTD6UIPR.js.map → browser-viewer-LGH4IP47.js.map} +0 -0
- /package/dist/{chunk-NLTS7JHI.js.map → chunk-JPHDWKZE.js.map} +0 -0
- /package/dist/{chunk-L5VJYZIW.js.map → chunk-O53CQZ6T.js.map} +0 -0
- /package/dist/{chunk-24M4YBCL.js.map → chunk-PNAVEK2U.js.map} +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
/** Private loading surface: never receives or executes the unfinished fence. */
|
|
4
|
+
export function PreviewLoading() {
|
|
5
|
+
const ref = useRef<HTMLCanvasElement>(null);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const canvas = ref.current;
|
|
8
|
+
if (!canvas) return;
|
|
9
|
+
let ctx: CanvasRenderingContext2D | null;
|
|
10
|
+
try {
|
|
11
|
+
ctx = canvas.getContext("2d");
|
|
12
|
+
} catch {
|
|
13
|
+
return; // The CSS grid and status remain when canvas is unavailable.
|
|
14
|
+
}
|
|
15
|
+
if (!ctx) return;
|
|
16
|
+
const context = ctx;
|
|
17
|
+
const motion = window.matchMedia?.("(prefers-reduced-motion: reduce)");
|
|
18
|
+
let frame: number | undefined;
|
|
19
|
+
let time = 2;
|
|
20
|
+
let last: number | undefined;
|
|
21
|
+
let disposed = false;
|
|
22
|
+
// Without visibility observation, keep a static surface rather than doing
|
|
23
|
+
// unbounded work for previews that may be outside the viewport.
|
|
24
|
+
let visible = false;
|
|
25
|
+
const canAnimate = () => !disposed && visible && !document.hidden && motion?.matches === false;
|
|
26
|
+
|
|
27
|
+
function draw() {
|
|
28
|
+
const w = canvas!.clientWidth;
|
|
29
|
+
const h = canvas!.clientHeight;
|
|
30
|
+
if (!w || !h || document.hidden || disposed) return;
|
|
31
|
+
const d = Math.min(window.devicePixelRatio || 1, 2);
|
|
32
|
+
if (canvas!.width !== Math.round(w * d) || canvas!.height !== Math.round(h * d)) {
|
|
33
|
+
canvas!.width = Math.round(w * d);
|
|
34
|
+
canvas!.height = Math.round(h * d);
|
|
35
|
+
}
|
|
36
|
+
const style = getComputedStyle(canvas!);
|
|
37
|
+
const ink = style.getPropertyValue("--_og-preview-ink").trim() || "#bca3ef";
|
|
38
|
+
const glowColor = style.getPropertyValue("--_og-preview-glow").trim() || "#8f6ccc";
|
|
39
|
+
context.setTransform(d, 0, 0, d, 0, 0);
|
|
40
|
+
context.clearRect(0, 0, w, h);
|
|
41
|
+
const cx = w * (0.5 + 0.13 * Math.sin(time * 0.21));
|
|
42
|
+
const cy = h * (0.5 + 0.12 * Math.cos(time * 0.27));
|
|
43
|
+
const glow = context.createRadialGradient(cx, cy, 0, cx, cy, Math.max(w, h) * 0.65);
|
|
44
|
+
glow.addColorStop(0, glowColor);
|
|
45
|
+
glow.addColorStop(1, "transparent");
|
|
46
|
+
context.globalAlpha = 0.09;
|
|
47
|
+
context.fillStyle = glow;
|
|
48
|
+
context.fillRect(0, 0, w, h);
|
|
49
|
+
const rows = Math.ceil(h / 18) + 7;
|
|
50
|
+
const cols = Math.ceil(w / 18) + 7;
|
|
51
|
+
const points = Array.from({ length: rows }, (_row, r) =>
|
|
52
|
+
Array.from({ length: cols }, (_col, c) => {
|
|
53
|
+
const x = (c - 3) * 18;
|
|
54
|
+
const y = (r - 3) * 18;
|
|
55
|
+
const dist = Math.hypot((x - cx) * 0.8, y - cy);
|
|
56
|
+
const wave = Math.sin(dist * 0.032 - time * 0.95);
|
|
57
|
+
return {
|
|
58
|
+
x: x + ((x - cx) / Math.max(dist, 1)) * wave * 4,
|
|
59
|
+
y: y + ((y - cy) / Math.max(dist, 1)) * wave * 4,
|
|
60
|
+
l: Math.pow((wave + 1) / 2, 5),
|
|
61
|
+
};
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
context.strokeStyle = ink;
|
|
65
|
+
context.fillStyle = ink;
|
|
66
|
+
context.lineWidth = 0.65;
|
|
67
|
+
points.forEach((row, r) =>
|
|
68
|
+
row.forEach((p, c) => {
|
|
69
|
+
context.globalAlpha = 0.035 + p.l * 0.055;
|
|
70
|
+
context.beginPath();
|
|
71
|
+
if (c + 1 < cols) {
|
|
72
|
+
context.moveTo(p.x, p.y);
|
|
73
|
+
context.lineTo(row[c + 1]!.x, row[c + 1]!.y);
|
|
74
|
+
}
|
|
75
|
+
if (r + 1 < rows) {
|
|
76
|
+
context.moveTo(p.x, p.y);
|
|
77
|
+
context.lineTo(points[r + 1]![c]!.x, points[r + 1]![c]!.y);
|
|
78
|
+
}
|
|
79
|
+
context.stroke();
|
|
80
|
+
context.globalAlpha = 0.15 + p.l * 0.55;
|
|
81
|
+
context.beginPath();
|
|
82
|
+
context.arc(p.x, p.y, 0.85 + p.l * 0.65, 0, Math.PI * 2);
|
|
83
|
+
context.fill();
|
|
84
|
+
}),
|
|
85
|
+
);
|
|
86
|
+
context.globalAlpha = 1;
|
|
87
|
+
canvas!.dataset.painted = "true";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function stop() {
|
|
91
|
+
if (frame !== undefined) window.cancelAnimationFrame(frame);
|
|
92
|
+
frame = undefined;
|
|
93
|
+
last = undefined;
|
|
94
|
+
}
|
|
95
|
+
function tick(stamp: number) {
|
|
96
|
+
frame = undefined;
|
|
97
|
+
if (!canAnimate()) return;
|
|
98
|
+
if (last !== undefined) time += Math.min((stamp - last) / 1000, 0.05);
|
|
99
|
+
last = stamp;
|
|
100
|
+
draw();
|
|
101
|
+
frame = window.requestAnimationFrame(tick);
|
|
102
|
+
}
|
|
103
|
+
function refresh() {
|
|
104
|
+
stop();
|
|
105
|
+
if (disposed || document.hidden || (!visible && intersection)) return;
|
|
106
|
+
draw();
|
|
107
|
+
if (canAnimate() && typeof window.requestAnimationFrame === "function") {
|
|
108
|
+
frame = window.requestAnimationFrame(tick);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const intersection =
|
|
112
|
+
typeof IntersectionObserver === "function"
|
|
113
|
+
? new IntersectionObserver(([entry]) => {
|
|
114
|
+
visible = entry?.isIntersecting === true;
|
|
115
|
+
refresh();
|
|
116
|
+
})
|
|
117
|
+
: undefined;
|
|
118
|
+
intersection?.observe(canvas);
|
|
119
|
+
const resize = typeof ResizeObserver === "function" ? new ResizeObserver(refresh) : undefined;
|
|
120
|
+
resize?.observe(canvas);
|
|
121
|
+
// Observe only ancestors, not the document subtree. This also updates the
|
|
122
|
+
// static reduced-motion canvas when a host changes its local theme.
|
|
123
|
+
const theme =
|
|
124
|
+
typeof MutationObserver === "function" ? new MutationObserver(refresh) : undefined;
|
|
125
|
+
for (let ancestor = canvas.parentElement; ancestor; ancestor = ancestor.parentElement) {
|
|
126
|
+
theme?.observe(ancestor, {
|
|
127
|
+
attributes: true,
|
|
128
|
+
attributeFilter: ["class", "style", "data-og-theme"],
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
motion?.addEventListener?.("change", refresh);
|
|
132
|
+
document.addEventListener("visibilitychange", refresh);
|
|
133
|
+
window.addEventListener("resize", refresh);
|
|
134
|
+
// Old hosts get one still frame; observed surfaces wait until onscreen.
|
|
135
|
+
if (!intersection) draw();
|
|
136
|
+
return () => {
|
|
137
|
+
disposed = true;
|
|
138
|
+
stop();
|
|
139
|
+
intersection?.disconnect();
|
|
140
|
+
resize?.disconnect();
|
|
141
|
+
theme?.disconnect();
|
|
142
|
+
motion?.removeEventListener?.("change", refresh);
|
|
143
|
+
document.removeEventListener("visibilitychange", refresh);
|
|
144
|
+
window.removeEventListener("resize", refresh);
|
|
145
|
+
};
|
|
146
|
+
}, []);
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<div className="og-preview-loading">
|
|
150
|
+
<canvas ref={ref} aria-hidden="true" />
|
|
151
|
+
<span className="og-preview-loading-label">Preparing preview…</span>
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
}
|
package/src/connect-setup.tsx
CHANGED
|
@@ -35,6 +35,8 @@ export type ConnectSetupProps = {
|
|
|
35
35
|
controller: ConnectController;
|
|
36
36
|
/** Called synchronously in the click handler so a host can open a popup. */
|
|
37
37
|
onAuthorize: (attempt: ConnectAttempt) => void | Promise<unknown>;
|
|
38
|
+
/** Called synchronously on Continue; hosts can reserve a popup before advancing. */
|
|
39
|
+
onSelectAccount?: (accountId: string) => void | Promise<unknown>;
|
|
38
40
|
/** Host pagination must retain selections across pages and submit the final set. */
|
|
39
41
|
onBrowseResources?: (attempt: ConnectAttempt) => void | Promise<unknown>;
|
|
40
42
|
className?: string;
|
|
@@ -61,11 +63,13 @@ function ScopedSetup({
|
|
|
61
63
|
controller,
|
|
62
64
|
onAuthorize,
|
|
63
65
|
onBrowseResources,
|
|
66
|
+
onSelectAccount,
|
|
64
67
|
className,
|
|
65
68
|
authorizeLabel = "Authorize connection",
|
|
66
69
|
}: ConnectSetupProps) {
|
|
67
70
|
const view = useConnect(controller);
|
|
68
71
|
const [localError, setLocalError] = useState(false);
|
|
72
|
+
const [navigating, setNavigating] = useState(false);
|
|
69
73
|
const invoke = (operation: () => unknown | Promise<unknown>) => {
|
|
70
74
|
setLocalError(false);
|
|
71
75
|
try {
|
|
@@ -91,7 +95,7 @@ function ScopedSetup({
|
|
|
91
95
|
event.preventDefault();
|
|
92
96
|
const form = event.currentTarget;
|
|
93
97
|
const data = new FormData(form);
|
|
94
|
-
if (view.busy) return;
|
|
98
|
+
if (view.busy || navigating) return;
|
|
95
99
|
const key = crypto.randomUUID();
|
|
96
100
|
if (action.type === "credentials") {
|
|
97
101
|
const values = Object.fromEntries(
|
|
@@ -105,7 +109,15 @@ function ScopedSetup({
|
|
|
105
109
|
if (
|
|
106
110
|
action.accounts.some((account) => account.id === accountId && account.status !== "disabled")
|
|
107
111
|
)
|
|
108
|
-
invoke(() =>
|
|
112
|
+
invoke(async () => {
|
|
113
|
+
if (!onSelectAccount) return view.advance({ type: "account", accountId }, key);
|
|
114
|
+
setNavigating(true);
|
|
115
|
+
try {
|
|
116
|
+
await onSelectAccount(accountId);
|
|
117
|
+
} finally {
|
|
118
|
+
setNavigating(false);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
109
121
|
} else if (action.type === "select_resources") {
|
|
110
122
|
if (action.cursor) return;
|
|
111
123
|
const resourceIds = data.getAll("resource").map(String);
|
|
@@ -129,7 +141,7 @@ function ScopedSetup({
|
|
|
129
141
|
<section
|
|
130
142
|
className={["og-connect-setup", className].filter(Boolean).join(" ")}
|
|
131
143
|
aria-label="Connection setup"
|
|
132
|
-
aria-busy={view.busy}
|
|
144
|
+
aria-busy={view.busy || navigating}
|
|
133
145
|
>
|
|
134
146
|
<div className="og-connect-setup-summary">
|
|
135
147
|
<p className="og-connect-setup-scope">
|
|
@@ -154,7 +166,7 @@ function ScopedSetup({
|
|
|
154
166
|
)}
|
|
155
167
|
{!terminal && (
|
|
156
168
|
<form key={`${attempt.id}:${attempt.revision}`} onSubmit={submit} autoComplete="off">
|
|
157
|
-
<fieldset disabled={view.busy}>
|
|
169
|
+
<fieldset disabled={view.busy || navigating}>
|
|
158
170
|
{["credentials", "select_account", "select_resources", "preview"].includes(
|
|
159
171
|
action.type,
|
|
160
172
|
) ? (
|
|
@@ -261,7 +273,7 @@ function ScopedSetup({
|
|
|
261
273
|
className="og-connect-setup-primary"
|
|
262
274
|
onClick={() => invoke(() => onAuthorize(structuredClone(attempt)))}
|
|
263
275
|
>
|
|
264
|
-
{authorizeLabel}
|
|
276
|
+
{navigating ? "Waiting for authorization…" : authorizeLabel}
|
|
265
277
|
</button>
|
|
266
278
|
)}
|
|
267
279
|
{action.type === "wait" && (
|
|
@@ -1478,6 +1478,9 @@ export function useComposer(
|
|
|
1478
1478
|
...(wireInput.connectionAuthorities
|
|
1479
1479
|
? { connectionAuthorities: wireInput.connectionAuthorities }
|
|
1480
1480
|
: {}),
|
|
1481
|
+
...(wireInput.selectedHostMcpDelegations
|
|
1482
|
+
? { selectedHostMcpDelegations: wireInput.selectedHostMcpDelegations }
|
|
1483
|
+
: {}),
|
|
1481
1484
|
...(wireInput.personalResourceAttachment
|
|
1482
1485
|
? { personalResourceAttachment: wireInput.personalResourceAttachment }
|
|
1483
1486
|
: {}),
|
|
@@ -1754,6 +1757,9 @@ export function useComposer(
|
|
|
1754
1757
|
...(input.connectionAuthorities
|
|
1755
1758
|
? { connectionAuthorities: input.connectionAuthorities }
|
|
1756
1759
|
: {}),
|
|
1760
|
+
...(input.selectedHostMcpDelegations
|
|
1761
|
+
? { selectedHostMcpDelegations: input.selectedHostMcpDelegations }
|
|
1762
|
+
: {}),
|
|
1757
1763
|
...(input.personalResourceAttachment
|
|
1758
1764
|
? { personalResourceAttachment: input.personalResourceAttachment }
|
|
1759
1765
|
: {}),
|
package/src/plugin-discovery.tsx
CHANGED
|
@@ -17,6 +17,8 @@ export type PluginDiscoveryProps = {
|
|
|
17
17
|
};
|
|
18
18
|
workspaceId: string;
|
|
19
19
|
query: string;
|
|
20
|
+
/** Initially selected registry. Users can still switch registries or browse all. */
|
|
21
|
+
defaultProvider?: "" | "openai" | "anthropic";
|
|
20
22
|
/** Discovery identities already installed in the current workspace. */
|
|
21
23
|
installedIds?: ReadonlySet<string>;
|
|
22
24
|
resultLimit?: number;
|
|
@@ -24,7 +26,7 @@ export type PluginDiscoveryProps = {
|
|
|
24
26
|
onOpen: (item: PluginDiscoveryItem) => void;
|
|
25
27
|
};
|
|
26
28
|
export function PluginDiscovery(props: PluginDiscoveryProps) {
|
|
27
|
-
const [provider, setProvider] = useState("");
|
|
29
|
+
const [provider, setProvider] = useState(props.defaultProvider ?? "");
|
|
28
30
|
return (
|
|
29
31
|
<section
|
|
30
32
|
className={`og-plugin-discovery ${props.resultLimit ? "og-catalog-overview" : ""}`}
|
|
@@ -34,11 +36,13 @@ export function PluginDiscovery(props: PluginDiscoveryProps) {
|
|
|
34
36
|
<h3>{props.resultLimit ? "Plugins" : "Browse plugins"}</h3>
|
|
35
37
|
{!props.resultLimit ? (
|
|
36
38
|
<div className="og-plugin-filters" role="group" aria-label="Plugin registry">
|
|
37
|
-
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
{(
|
|
40
|
+
[
|
|
41
|
+
{ value: "", label: "All" },
|
|
42
|
+
{ value: "openai", label: "OpenAI plugin registry" },
|
|
43
|
+
{ value: "anthropic", label: "Anthropic plugin registry" },
|
|
44
|
+
] as const
|
|
45
|
+
).map((option) => (
|
|
42
46
|
<button
|
|
43
47
|
key={option.value}
|
|
44
48
|
type="button"
|
|
@@ -1105,16 +1105,14 @@ export function RealtimeVoiceModelPanel(props: {
|
|
|
1105
1105
|
|
|
1106
1106
|
return (
|
|
1107
1107
|
<div className="flex min-h-0 flex-1 flex-col" data-testid="realtime-voice-model-panel">
|
|
1108
|
-
<div className="flex shrink-0 items-
|
|
1108
|
+
<div className="flex min-h-10 shrink-0 items-center gap-2 border-b border-og-border px-2 pb-2">
|
|
1109
1109
|
{props.leading}
|
|
1110
|
-
<div className="min-w-0">
|
|
1111
|
-
<div className="text-og-menu font-medium text-og-fg">Voice model</div>
|
|
1112
|
-
<p className="mt-0.5 text-og-control text-og-fg-subtle">
|
|
1113
|
-
Used when you start a voice conversation.
|
|
1114
|
-
</p>
|
|
1115
|
-
</div>
|
|
1110
|
+
<div className="min-w-0 flex-1 text-og-menu font-medium text-og-fg">Voice model</div>
|
|
1116
1111
|
</div>
|
|
1117
|
-
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain
|
|
1112
|
+
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain p-2">
|
|
1113
|
+
<p className="mb-3 text-og-control text-og-fg-muted">
|
|
1114
|
+
Used when you start a voice conversation.
|
|
1115
|
+
</p>
|
|
1118
1116
|
<RealtimeModelPickerMenu
|
|
1119
1117
|
models={props.models}
|
|
1120
1118
|
selectedModel={props.selectedModel}
|
package/styles/compiled.css
CHANGED
|
@@ -608,6 +608,54 @@
|
|
|
608
608
|
--_og-session-chrome-ease: var(--og-session-chrome-ease, var(--og-ease-out));
|
|
609
609
|
--_og-session-chrome-row-hover: var(--og-session-chrome-row-hover, var(--og-color-surface-3));
|
|
610
610
|
}
|
|
611
|
+
:where(.og-root).og-preview-loading,:where(.og-root) .og-preview-loading {
|
|
612
|
+
--_og-preview-ink: #bca3ef;
|
|
613
|
+
--_og-preview-glow: #8f6ccc;
|
|
614
|
+
position: relative;
|
|
615
|
+
width: 100%;
|
|
616
|
+
overflow: hidden;
|
|
617
|
+
border-radius: 10px;
|
|
618
|
+
background: #17161d;
|
|
619
|
+
container: og-preview / inline-size;
|
|
620
|
+
}
|
|
621
|
+
:where(.og-root):is([data-og-theme="light"], .og-light) .og-preview-loading, :is([data-og-theme="light"], .og-light) :where(.og-root) .og-preview-loading,:where(.og-root) :is([data-og-theme="light"], .og-light) .og-preview-loading {
|
|
622
|
+
--_og-preview-ink: #76629c;
|
|
623
|
+
--_og-preview-glow: #ba8ee0;
|
|
624
|
+
background: #faf9fd;
|
|
625
|
+
}
|
|
626
|
+
:where(.og-root).og-preview-loading canvas,:where(.og-root) .og-preview-loading canvas {
|
|
627
|
+
display: block;
|
|
628
|
+
width: 100%;
|
|
629
|
+
height: 320px;
|
|
630
|
+
background-image: radial-gradient(circle, var(--_og-preview-ink) 1px, transparent 1px);
|
|
631
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
632
|
+
background-image: radial-gradient(circle, color-mix(in srgb, var(--_og-preview-ink) 30%, transparent) 1px, transparent 1px);
|
|
633
|
+
}
|
|
634
|
+
background-size: 18px 18px;
|
|
635
|
+
}
|
|
636
|
+
:where(.og-root).og-preview-loading canvas[data-painted="true"],:where(.og-root) .og-preview-loading canvas[data-painted="true"] {
|
|
637
|
+
background-image: none;
|
|
638
|
+
}
|
|
639
|
+
:where(.og-root).og-preview-loading-label,:where(.og-root) .og-preview-loading-label {
|
|
640
|
+
position: absolute;
|
|
641
|
+
left: 16px;
|
|
642
|
+
bottom: 14px;
|
|
643
|
+
color: var(--og-color-fg-muted);
|
|
644
|
+
font-family: var(--og-font-sans);
|
|
645
|
+
font-size: var(--og-font-size-xs);
|
|
646
|
+
line-height: var(--og-line-height-xs);
|
|
647
|
+
font-weight: 400;
|
|
648
|
+
}
|
|
649
|
+
@container og-preview (max-width: 500px) {
|
|
650
|
+
:where(.og-root).og-preview-loading canvas,:where(.og-root) .og-preview-loading canvas {
|
|
651
|
+
height: 260px;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
@media (max-width: 500px) {
|
|
655
|
+
:where(.og-root).og-preview-loading canvas,:where(.og-root) .og-preview-loading canvas {
|
|
656
|
+
height: 260px;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
611
659
|
.og-root :where([hidden]:not([hidden="until-found"])) {
|
|
612
660
|
display: none !important;
|
|
613
661
|
}
|
|
@@ -1623,9 +1671,6 @@
|
|
|
1623
1671
|
:where(.og-root).min-h-14,:where(.og-root) .min-h-14 {
|
|
1624
1672
|
min-height: calc(var(--spacing) * 14);
|
|
1625
1673
|
}
|
|
1626
|
-
:where(.og-root).min-h-32,:where(.og-root) .min-h-32 {
|
|
1627
|
-
min-height: calc(var(--spacing) * 32);
|
|
1628
|
-
}
|
|
1629
1674
|
:where(.og-root).min-h-56,:where(.og-root) .min-h-56 {
|
|
1630
1675
|
min-height: calc(var(--spacing) * 56);
|
|
1631
1676
|
}
|
|
@@ -5031,11 +5076,6 @@
|
|
|
5031
5076
|
}
|
|
5032
5077
|
}
|
|
5033
5078
|
}
|
|
5034
|
-
:where(.og-root).motion-safe\:animate-spin,:where(.og-root) .motion-safe\:animate-spin {
|
|
5035
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
5036
|
-
animation: og-spin 1s linear infinite;
|
|
5037
|
-
}
|
|
5038
|
-
}
|
|
5039
5079
|
:where(.og-root).motion-reduce\:animate-none,:where(.og-root) .motion-reduce\:animate-none {
|
|
5040
5080
|
@media (prefers-reduced-motion: reduce) {
|
|
5041
5081
|
animation: none;
|
package/styles/index.css
CHANGED
|
@@ -17,6 +17,51 @@
|
|
|
17
17
|
@import "./tokens.css";
|
|
18
18
|
@import "./effective-tokens.css";
|
|
19
19
|
|
|
20
|
+
/* Full-surface preview preparation. Private palette preserves the accepted
|
|
21
|
+
ripple study; the steady label uses the host's typography and text tokens. */
|
|
22
|
+
.og-preview-loading {
|
|
23
|
+
--_og-preview-ink: #bca3ef;
|
|
24
|
+
--_og-preview-glow: #8f6ccc;
|
|
25
|
+
position: relative;
|
|
26
|
+
width: 100%;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
border-radius: 10px;
|
|
29
|
+
background: #17161d;
|
|
30
|
+
container: og-preview / inline-size;
|
|
31
|
+
}
|
|
32
|
+
.og-root:is([data-og-theme="light"], .og-light) .og-preview-loading,
|
|
33
|
+
:is([data-og-theme="light"], .og-light) .og-root .og-preview-loading,
|
|
34
|
+
.og-root :is([data-og-theme="light"], .og-light) .og-preview-loading {
|
|
35
|
+
--_og-preview-ink: #76629c;
|
|
36
|
+
--_og-preview-glow: #ba8ee0;
|
|
37
|
+
background: #faf9fd;
|
|
38
|
+
}
|
|
39
|
+
.og-preview-loading canvas {
|
|
40
|
+
display: block;
|
|
41
|
+
width: 100%;
|
|
42
|
+
height: 320px;
|
|
43
|
+
/* Non-canvas / pre-effect fallback, removed only after a successful paint. */
|
|
44
|
+
background-image: radial-gradient(circle, color-mix(in srgb, var(--_og-preview-ink) 30%, transparent) 1px, transparent 1px);
|
|
45
|
+
background-size: 18px 18px;
|
|
46
|
+
}
|
|
47
|
+
.og-preview-loading canvas[data-painted="true"] { background-image: none; }
|
|
48
|
+
.og-preview-loading-label {
|
|
49
|
+
position: absolute;
|
|
50
|
+
left: 16px;
|
|
51
|
+
bottom: 14px;
|
|
52
|
+
color: var(--og-color-fg-muted);
|
|
53
|
+
font-family: var(--og-font-sans);
|
|
54
|
+
font-size: var(--og-font-size-xs);
|
|
55
|
+
line-height: var(--og-line-height-xs);
|
|
56
|
+
font-weight: 400;
|
|
57
|
+
}
|
|
58
|
+
@container og-preview (max-width: 500px) {
|
|
59
|
+
.og-preview-loading canvas { height: 260px; }
|
|
60
|
+
}
|
|
61
|
+
@media (max-width: 500px) {
|
|
62
|
+
.og-preview-loading canvas { height: 260px; }
|
|
63
|
+
}
|
|
64
|
+
|
|
20
65
|
/* Standalone embeds do not necessarily load Tailwind Preflight. Keep the
|
|
21
66
|
control reset inside SDK roots, before utilities, without resetting the host.
|
|
22
67
|
:where keeps controls at the same specificity as component utilities. */
|