@cloudgrid-io/ui 0.29.2 → 0.31.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/README.md +63 -0
- package/dist/blocks/agent-prompt.d.ts +17 -1
- package/dist/blocks/agent-prompt.d.ts.map +1 -1
- package/dist/blocks/agent-prompt.js +33 -3
- package/dist/blocks/agent-prompt.js.map +1 -1
- package/dist/blocks/cloudgrid-install.d.ts +67 -0
- package/dist/blocks/cloudgrid-install.d.ts.map +1 -0
- package/dist/blocks/cloudgrid-install.js +192 -0
- package/dist/blocks/cloudgrid-install.js.map +1 -0
- package/dist/blocks/command-field.d.ts +38 -0
- package/dist/blocks/command-field.d.ts.map +1 -0
- package/dist/blocks/command-field.js +70 -0
- package/dist/blocks/command-field.js.map +1 -0
- package/dist/blocks/drop-zone.d.ts +2 -1
- package/dist/blocks/drop-zone.d.ts.map +1 -1
- package/dist/blocks/drop-zone.js.map +1 -1
- package/dist/blocks/entity-card.d.ts +81 -24
- package/dist/blocks/entity-card.d.ts.map +1 -1
- package/dist/blocks/entity-card.js +235 -126
- package/dist/blocks/entity-card.js.map +1 -1
- package/dist/blocks/icons.d.ts +23 -1
- package/dist/blocks/icons.d.ts.map +1 -1
- package/dist/blocks/icons.js +23 -1
- package/dist/blocks/icons.js.map +1 -1
- package/dist/blocks/install-content.d.ts +228 -0
- package/dist/blocks/install-content.d.ts.map +1 -0
- package/dist/blocks/install-content.js +464 -0
- package/dist/blocks/install-content.js.map +1 -0
- package/dist/blocks/logo.d.ts +70 -1
- package/dist/blocks/logo.d.ts.map +1 -1
- package/dist/blocks/logo.js +75 -2
- package/dist/blocks/logo.js.map +1 -1
- package/dist/blocks/phosphor-marks.d.ts +6 -0
- package/dist/blocks/phosphor-marks.d.ts.map +1 -1
- package/dist/blocks/phosphor-marks.js +9 -0
- package/dist/blocks/phosphor-marks.js.map +1 -1
- package/dist/blocks/prompt-block.d.ts +57 -0
- package/dist/blocks/prompt-block.d.ts.map +1 -0
- package/dist/blocks/prompt-block.js +219 -0
- package/dist/blocks/prompt-block.js.map +1 -0
- package/dist/blocks/stage-panel.d.ts +19 -0
- package/dist/blocks/stage-panel.d.ts.map +1 -1
- package/dist/blocks/stage-panel.js +2 -4
- package/dist/blocks/stage-panel.js.map +1 -1
- package/dist/blocks/step-item.d.ts +21 -1
- package/dist/blocks/step-item.d.ts.map +1 -1
- package/dist/blocks/step-item.js +27 -2
- package/dist/blocks/step-item.js.map +1 -1
- package/dist/blocks/tool-logo.d.ts.map +1 -1
- package/dist/blocks/tool-logo.js +10 -6
- package/dist/blocks/tool-logo.js.map +1 -1
- package/dist/blocks/tool-setup.d.ts +95 -9
- package/dist/blocks/tool-setup.d.ts.map +1 -1
- package/dist/blocks/tool-setup.js +129 -49
- package/dist/blocks/tool-setup.js.map +1 -1
- package/dist/brand/mark-180.png +0 -0
- package/dist/brand/mark-192.png +0 -0
- package/dist/brand/mark-32.png +0 -0
- package/dist/brand/mark-512.png +0 -0
- package/dist/brand/mark-inverted-180.png +0 -0
- package/dist/brand/mark-inverted-192.png +0 -0
- package/dist/brand/mark-inverted-32.png +0 -0
- package/dist/brand/mark-inverted-512.png +0 -0
- package/dist/brand/mark-inverted.svg +8 -0
- package/dist/brand/mark.svg +7 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
- package/dist/blocks/plug-method.d.ts +0 -76
- package/dist/blocks/plug-method.d.ts.map +0 -1
- package/dist/blocks/plug-method.js +0 -30
- package/dist/blocks/plug-method.js.map +0 -1
package/README.md
CHANGED
|
@@ -93,6 +93,29 @@ what `text-ink` is doing above. Borders and backgrounds flip on their own. Text
|
|
|
93
93
|
There is no dark mode here, and this is not a substitute for one. Dark surfaces are a
|
|
94
94
|
property of a container, never a page-level theme.
|
|
95
95
|
|
|
96
|
+
## The install panel
|
|
97
|
+
|
|
98
|
+
Every CloudGrid install panel comes from this package, content and design both. Nothing is
|
|
99
|
+
fetched.
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
import { CloudGridInstall, INSTALL_PRESETS, installToolPreset } from "@cloudgrid-io/ui"
|
|
103
|
+
|
|
104
|
+
<CloudGridInstall /> // the whole panel
|
|
105
|
+
<CloudGridInstall preset={INSTALL_PRESETS.onboarding} onValueChange={recordTool} />
|
|
106
|
+
<CloudGridInstall preset={installToolPreset("cursor")} />
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
There are no props for the words. A page chooses what is on screen (`tools`, `methods`,
|
|
110
|
+
`defaultTool`, `defaultMethod`, `showFetchPrompt`, `showFooter`, or a `preset`) and what only
|
|
111
|
+
it can know (the selected tool and method, the heading level, a Continue action). Tool values
|
|
112
|
+
are stable identifiers, safe to record: `claude-code`, `cursor`, `codex`, `antigravity`,
|
|
113
|
+
`gemini`, `chatgpt`, `claude-web`.
|
|
114
|
+
|
|
115
|
+
`CloudGridFetchPrompt` and `CloudGridInstallFooter` render on their own. Without React, take the
|
|
116
|
+
strings from `@cloudgrid-io/ui/install-content` (`INSTALL_TOOLS`, `INSTALL_COMMANDS` and the
|
|
117
|
+
rest).
|
|
118
|
+
|
|
96
119
|
## Entry points
|
|
97
120
|
|
|
98
121
|
| | |
|
|
@@ -104,9 +127,49 @@ property of a container, never a page-level theme.
|
|
|
104
127
|
| `@cloudgrid-io/ui/fonts.css` | the three self-hosted families |
|
|
105
128
|
| `@cloudgrid-io/ui/prose.css` | long-form text |
|
|
106
129
|
| `@cloudgrid-io/ui/tokens.json` | the same values, machine-readable |
|
|
130
|
+
| `@cloudgrid-io/ui/install-content` | the install content as plain data, no React |
|
|
107
131
|
|
|
108
132
|
The JSON sets under `tokens/` are DTCG and are the source the CSS is compiled from.
|
|
109
133
|
|
|
134
|
+
## The CloudGrid sign as files
|
|
135
|
+
|
|
136
|
+
The socket glyph in a rounded square, as static files for a browser tab, a home screen or
|
|
137
|
+
a web manifest. Two colourways: `mark` is the brand sign (purple square, white glyph, what
|
|
138
|
+
the site uses) and `mark-inverted` is white with a purple glyph (what the Console's tab uses).
|
|
139
|
+
|
|
140
|
+
| | |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `@cloudgrid-io/ui/brand/mark.svg` | SVG favicon, purple |
|
|
143
|
+
| `@cloudgrid-io/ui/brand/mark-inverted.svg` | SVG favicon, white |
|
|
144
|
+
| `@cloudgrid-io/ui/brand/mark-32.png`, `mark-inverted-32.png` | PNG favicon fallback |
|
|
145
|
+
| `@cloudgrid-io/ui/brand/mark-180.png`, `mark-inverted-180.png` | `apple-touch-icon`, full bleed: iOS rounds it |
|
|
146
|
+
| `@cloudgrid-io/ui/brand/mark-192.png`, `mark-inverted-192.png` | web manifest |
|
|
147
|
+
| `@cloudgrid-io/ui/brand/mark-512.png`, `mark-inverted-512.png` | web manifest |
|
|
148
|
+
|
|
149
|
+
A browser needs a URL, so copy them into your public folder or import them through your
|
|
150
|
+
bundler:
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
// Next.js app router, e.g. app/layout.tsx
|
|
154
|
+
import favicon from "@cloudgrid-io/ui/brand/mark-inverted.svg"
|
|
155
|
+
import appleTouch from "@cloudgrid-io/ui/brand/mark-inverted-180.png"
|
|
156
|
+
|
|
157
|
+
export const metadata = {
|
|
158
|
+
title: "CloudGrid",
|
|
159
|
+
icons: { icon: favicon.src, apple: appleTouch.src },
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```html
|
|
164
|
+
<link rel="icon" href="/mark-inverted.svg" type="image/svg+xml">
|
|
165
|
+
<link rel="icon" href="/mark-inverted-32.png" sizes="32x32" type="image/png">
|
|
166
|
+
<link rel="apple-touch-icon" href="/mark-inverted-180.png">
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Inside a page, use the component instead: `<LogoMark tone="inverted" size={32} />`. It draws
|
|
170
|
+
the same glyph from the same constant as `Logo`, and the files are generated from that
|
|
171
|
+
constant and the brand token by `scripts/generate-brand-mark.mjs`, so the three cannot drift.
|
|
172
|
+
|
|
110
173
|
## Versioning
|
|
111
174
|
|
|
112
175
|
Semver. Token value changes are minor; removals are major.
|
|
@@ -26,12 +26,28 @@ import * as React from "react";
|
|
|
26
26
|
* The failure path is honest rather than silent: `navigator.clipboard` rejects on
|
|
27
27
|
* insecure origins and without permission, and saying "copy blocked" beats a button
|
|
28
28
|
* that appears to do nothing.
|
|
29
|
+
*
|
|
30
|
+
* ## `variant="outline"` (#262)
|
|
31
|
+
*
|
|
32
|
+
* The install blocks close on this same pill and draw it a second way: a hairline
|
|
33
|
+
* outline over the field ground, the caret in the placeholder colour, and an
|
|
34
|
+
* icon-only copy at the right. It is the same component because it is the same
|
|
35
|
+
* idea — one line, handed to an agent — and a second component would be a second
|
|
36
|
+
* place for the caret, the copy and the announcement to drift.
|
|
37
|
+
*
|
|
38
|
+
* `default` keeps its own ink pill and its blinking caret and renders
|
|
39
|
+
* byte-identical to what it rendered before. `outline` drops the caret rather
|
|
40
|
+
* than recolouring it: a caret says "a shell is waiting for you here", and this
|
|
41
|
+
* treatment sits on the page rather than on ink, where that reads as a stray
|
|
42
|
+
* blinking rectangle in the middle of a sentence.
|
|
29
43
|
*/
|
|
30
|
-
declare function AgentPrompt({ command, label, copyLabel, className, ...props }: Omit<React.ComponentProps<"div">, "ref"> & {
|
|
44
|
+
declare function AgentPrompt({ command, label, copyLabel, variant, className, ...props }: Omit<React.ComponentProps<"div">, "ref"> & {
|
|
31
45
|
command: string;
|
|
32
46
|
/** Small lead-in above the pill, e.g. "Working with an agent? One line:" */
|
|
33
47
|
label?: string;
|
|
34
48
|
copyLabel?: string;
|
|
49
|
+
/** `outline` is the hairline pill the install blocks draw on the page. */
|
|
50
|
+
variant?: "default" | "outline";
|
|
35
51
|
}): React.JSX.Element;
|
|
36
52
|
export { AgentPrompt };
|
|
37
53
|
//# sourceMappingURL=agent-prompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-prompt.d.ts","sourceRoot":"","sources":["../../src/blocks/agent-prompt.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"agent-prompt.d.ts","sourceRoot":"","sources":["../../src/blocks/agent-prompt.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,iBAAS,WAAW,CAAC,EACnB,OAAO,EACP,KAAK,EACL,SAAkB,EAClB,OAAmB,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CAChC,qBAgHA;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { CheckIcon, CopyIcon } from "./icons.js";
|
|
4
5
|
import { cn } from "../lib/cloudgrid-cn.js";
|
|
5
6
|
/**
|
|
6
7
|
* The agent one-liner as an artifact: the sentence you hand to an agent, dressed
|
|
@@ -29,9 +30,28 @@ import { cn } from "../lib/cloudgrid-cn.js";
|
|
|
29
30
|
* The failure path is honest rather than silent: `navigator.clipboard` rejects on
|
|
30
31
|
* insecure origins and without permission, and saying "copy blocked" beats a button
|
|
31
32
|
* that appears to do nothing.
|
|
33
|
+
*
|
|
34
|
+
* ## `variant="outline"` (#262)
|
|
35
|
+
*
|
|
36
|
+
* The install blocks close on this same pill and draw it a second way: a hairline
|
|
37
|
+
* outline over the field ground, the caret in the placeholder colour, and an
|
|
38
|
+
* icon-only copy at the right. It is the same component because it is the same
|
|
39
|
+
* idea — one line, handed to an agent — and a second component would be a second
|
|
40
|
+
* place for the caret, the copy and the announcement to drift.
|
|
41
|
+
*
|
|
42
|
+
* `default` keeps its own ink pill and its blinking caret and renders
|
|
43
|
+
* byte-identical to what it rendered before. `outline` drops the caret rather
|
|
44
|
+
* than recolouring it: a caret says "a shell is waiting for you here", and this
|
|
45
|
+
* treatment sits on the page rather than on ink, where that reads as a stray
|
|
46
|
+
* blinking rectangle in the middle of a sentence.
|
|
32
47
|
*/
|
|
33
|
-
function AgentPrompt({ command, label, copyLabel = "Copy", className, ...props }) {
|
|
48
|
+
function AgentPrompt({ command, label, copyLabel = "Copy", variant = "default", className, ...props }) {
|
|
49
|
+
const outline = variant === "outline";
|
|
34
50
|
const [feedback, setFeedback] = React.useState(null);
|
|
51
|
+
// The icon-only control reports SUCCESS with a tick and a failure with the
|
|
52
|
+
// unchanged copy glyph plus the live region. A tick on a blocked copy is a
|
|
53
|
+
// confirmation of something that did not happen.
|
|
54
|
+
const [copied, setCopied] = React.useState(false);
|
|
35
55
|
const timer = React.useRef(undefined);
|
|
36
56
|
// Cleared on unmount, or a state update fires against a component that is gone
|
|
37
57
|
// when someone navigates within the 1600ms window.
|
|
@@ -40,14 +60,24 @@ function AgentPrompt({ command, label, copyLabel = "Copy", className, ...props }
|
|
|
40
60
|
try {
|
|
41
61
|
await navigator.clipboard.writeText(command);
|
|
42
62
|
setFeedback("copied ✓");
|
|
63
|
+
setCopied(true);
|
|
43
64
|
}
|
|
44
65
|
catch {
|
|
45
66
|
setFeedback("copy blocked by browser");
|
|
67
|
+
setCopied(false);
|
|
46
68
|
}
|
|
47
69
|
clearTimeout(timer.current);
|
|
48
|
-
timer.current = setTimeout(() =>
|
|
70
|
+
timer.current = setTimeout(() => {
|
|
71
|
+
setFeedback(null);
|
|
72
|
+
setCopied(false);
|
|
73
|
+
}, 1600);
|
|
49
74
|
}
|
|
50
|
-
return (_jsxs("div", { "data-slot": "agent-prompt", className: cn("flex flex-col gap-2", className), ...props, children: [label ? _jsx("p", { className: "m-0 text-body-sm text-body", children: label }) : null, _jsxs("div", { "data-cg-surface": "ink", className: "flex items-center gap-3 rounded-pill
|
|
75
|
+
return (_jsxs("div", { "data-slot": "agent-prompt", "data-variant": variant, className: cn("flex flex-col gap-2", outline && "items-center", className), ...props, children: [label ? (_jsx("p", { className: cn("m-0 text-body-sm text-body", outline && "text-caption text-faint"), children: label })) : null, _jsxs("div", { ...(outline ? {} : { "data-cg-surface": "ink" }), className: cn("flex items-center gap-3 rounded-pill px-4 py-2.5", outline
|
|
76
|
+
// See PromptBlock's FIELD note: --cg-surface-subtle is :root-only and
|
|
77
|
+
// freezes to a near-white lavender on ink, --cg-hover is declared in
|
|
78
|
+
// all three scopes.
|
|
79
|
+
? "max-w-full border border-line bg-(--cg-hover)"
|
|
80
|
+
: "bg-code text-ink"), children: [_jsx("span", { "aria-hidden": "true", className: "font-mono text-mono text-faint", children: ">" }), _jsxs("code", { className: cn("flex min-w-0 flex-1 items-center gap-1 font-mono text-mono", outline ? "truncate text-ink" : "break-all"), children: [command, outline ? null : (_jsx("span", { "aria-hidden": "true", className: "inline-block h-[1.1em] w-[0.5ch] shrink-0 bg-ink motion-safe:animate-pulse" }))] }), outline ? (_jsx("button", { type: "button", onClick: copy, className: "shrink-0 text-faint transition-colors hover:text-(--cg-text-accent) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", "aria-label": copyLabel, children: copied ? _jsx(CheckIcon, { className: "size-4" }) : _jsx(CopyIcon, { className: "size-4" }) })) : (_jsx("button", { type: "button", onClick: copy, className: "shrink-0 rounded-md px-2 py-1 font-mono text-caption text-body transition-colors hover:text-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", children: feedback ?? copyLabel }))] }), _jsx("span", { "aria-live": "polite", className: "sr-only", children: feedback })] }));
|
|
51
81
|
}
|
|
52
82
|
export { AgentPrompt };
|
|
53
83
|
//# sourceMappingURL=agent-prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-prompt.js","sourceRoot":"","sources":["../../src/blocks/agent-prompt.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"agent-prompt.js","sourceRoot":"","sources":["../../src/blocks/agent-prompt.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type InstallFilter, type InstallMethodValue, type InstallToolValue } from "./install-content.js";
|
|
3
|
+
import { PageHeading } from "./page-heading.js";
|
|
4
|
+
import { type ToolSetupGroup, type ToolSetupTool } from "./tool-setup.js";
|
|
5
|
+
/**
|
|
6
|
+
* The content's tools as `ToolSetup` takes them, in the order asked for, with
|
|
7
|
+
* every vendor mark and every body rendered.
|
|
8
|
+
*
|
|
9
|
+
* Exported for a page that composes `ToolSetup` itself, which is what the
|
|
10
|
+
* library gallery's `ToolSetup` specimens do. A method missing from `methods`
|
|
11
|
+
* is dropped from each tool, so a tool with nothing left leaves the strip.
|
|
12
|
+
*
|
|
13
|
+
* 15px marks, which is what the strip draws. A mark carries no size of its own,
|
|
14
|
+
* so every call site states one.
|
|
15
|
+
*/
|
|
16
|
+
export declare function installSetupTools(tools?: readonly InstallToolValue[], methods?: readonly InstallMethodValue[]): ToolSetupTool[];
|
|
17
|
+
/** The two runs, each drawn as its glyph and named by its words. */
|
|
18
|
+
export declare function installSetupGroups(): ToolSetupGroup[];
|
|
19
|
+
/**
|
|
20
|
+
* "Not sure? Copy this prompt and paste it to your AI agent." over the one
|
|
21
|
+
* command an agent can act on.
|
|
22
|
+
*
|
|
23
|
+
* The outline pill, as the Console drew it under the panel, so it reads the
|
|
24
|
+
* surface it sits on. `showIntro={false}` is the standalone pill, which is what
|
|
25
|
+
* the old `fetch-prompt` block was.
|
|
26
|
+
*/
|
|
27
|
+
declare function CloudGridFetchPrompt({ showIntro, ...props }: Omit<React.ComponentProps<"div">, "ref" | "children"> & {
|
|
28
|
+
/** The "Not sure?" line over the pill. */
|
|
29
|
+
showIntro?: boolean;
|
|
30
|
+
}): React.JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* The source line: one sentence, then the two repositories.
|
|
33
|
+
*
|
|
34
|
+
* `text-body` and not `text-faint`: faint is large-text-legal only (#232), and
|
|
35
|
+
* this is 15px. Every colour is a token, so it flips on the panel and on ink with
|
|
36
|
+
* the rest of the block; a container that sets `data-cg-surface` still owes its
|
|
37
|
+
* own `text-ink` (rule 3).
|
|
38
|
+
*/
|
|
39
|
+
declare function CloudGridInstallFooter({ className, ...props }: Omit<React.ComponentProps<"footer">, "ref" | "children">): React.JSX.Element;
|
|
40
|
+
declare function CloudGridInstall({ preset, tools, methods, defaultTool, defaultMethod, showFetchPrompt, showFooter, value, onValueChange, method, onMethodChange, level, headingSize, continueLabel, onContinue, canContinue, className, ...props }: Omit<React.ComponentProps<"div">, "ref" | "children" | "defaultValue" | "onChange"> & InstallFilter & {
|
|
41
|
+
/**
|
|
42
|
+
* A named configuration: `INSTALL_PRESETS.hub`, `.onboarding`, `.console`,
|
|
43
|
+
* `.makeGame`, `.makeAppAgent`, `.makeDeckPage`, or `installToolPreset(tool)`.
|
|
44
|
+
* Any filter prop passed alongside overrides that field of it.
|
|
45
|
+
*/
|
|
46
|
+
preset?: InstallFilter;
|
|
47
|
+
/** The selected tool, controlled. Pair with `onValueChange`. */
|
|
48
|
+
value?: InstallToolValue;
|
|
49
|
+
/** Reports the tool on screen, in the content's slugs (`gemini`, `claude-web`). */
|
|
50
|
+
onValueChange?: (value: InstallToolValue) => void;
|
|
51
|
+
/** The selected method, controlled. Pair with `onMethodChange`. */
|
|
52
|
+
method?: InstallMethodValue;
|
|
53
|
+
onMethodChange?: (method: InstallMethodValue) => void;
|
|
54
|
+
/** `2` for a section inside a larger page. */
|
|
55
|
+
level?: 1 | 2;
|
|
56
|
+
headingSize?: React.ComponentProps<typeof PageHeading>["size"];
|
|
57
|
+
/**
|
|
58
|
+
* A Continue button under the panel, for a flow. `null`, the default, draws
|
|
59
|
+
* none: with no handler a button is a dead end, and neither surface that
|
|
60
|
+
* renders this today has anything to continue to from inside it.
|
|
61
|
+
*/
|
|
62
|
+
continueLabel?: string | null;
|
|
63
|
+
onContinue?: () => void;
|
|
64
|
+
canContinue?: boolean;
|
|
65
|
+
}): React.JSX.Element;
|
|
66
|
+
export { CloudGridFetchPrompt, CloudGridInstall, CloudGridInstallFooter };
|
|
67
|
+
//# sourceMappingURL=cloudgrid-install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudgrid-install.d.ts","sourceRoot":"","sources":["../../src/blocks/cloudgrid-install.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,OAAO,EAQL,KAAK,aAAa,EAGlB,KAAK,kBAAkB,EAGvB,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAGxD,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,aAAa,EACnB,MAAM,0BAA0B,CAAA;AAyGjC;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,GAAE,SAAS,gBAAgB,EAAsC,EACtE,OAAO,GAAE,SAAS,kBAAkB,EAAwC,GAC3E,aAAa,EAAE,CAqBjB;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,IAAI,cAAc,EAAE,CAMrD;AAED;;;;;;;GAOG;AACH,iBAAS,oBAAoB,CAAC,EAC5B,SAAgB,EAChB,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,GAAG;IACzD,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,qBAWA;AAED;;;;;;;GAOG;AACH,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,qBA0B1D;AAUD,iBAAS,gBAAgB,CAAC,EACxB,MAAM,EACN,KAAK,EACL,OAAO,EACP,WAAW,EACX,aAAa,EACb,eAAe,EACf,UAAU,EACV,KAAK,EACL,aAAa,EACb,MAAM,EACN,cAAc,EACd,KAAS,EACT,WAAW,EACX,aAAoB,EACpB,UAAU,EACV,WAAkB,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,cAAc,GAAG,UAAU,CAAC,GACpF,aAAa,GAAG;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,gEAAgE;IAChE,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,mFAAmF;IACnF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACjD,mEAAmE;IACnE,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACrD,8CAA8C;IAC9C,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACb,WAAW,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;IAC9D;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,qBAqEF;AAED,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,CAAA"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { AgentPrompt } from "./agent-prompt.js";
|
|
4
|
+
import { Button } from "../ui/button.js";
|
|
5
|
+
import { ChatAppIcon, DownloadIcon, GithubIcon, OpenLiveIcon, TerminalIcon, } from "./icons.js";
|
|
6
|
+
import { INSTALL_FETCH_PROMPT, INSTALL_FOOTER, INSTALL_GROUPS, INSTALL_HEADING, INSTALL_METHODS, INSTALL_PRESETS, INSTALL_TOOLS, } from "./install-content.js";
|
|
7
|
+
import { PageHeading } from "./page-heading.js";
|
|
8
|
+
import { ToolLogo } from "./tool-logo.js";
|
|
9
|
+
import { TOOL_MARKS } from "./tool-marks.js";
|
|
10
|
+
import { ToolSetup, } from "./tool-setup.js";
|
|
11
|
+
import { cn } from "../lib/cloudgrid-cn.js";
|
|
12
|
+
/**
|
|
13
|
+
* THE INSTALL PANEL, COMPLETE. Content and design both from this library (#266).
|
|
14
|
+
*
|
|
15
|
+
* `<CloudGridInstall />` with no props renders the whole thing: the heading, the
|
|
16
|
+
* method pills, the grouped tool strip, every pane, the "Not sure?" fetch prompt
|
|
17
|
+
* and the source footer. Nothing is fetched and nothing is passed in, because the
|
|
18
|
+
* content is `install-content.ts` and ships in the same package.
|
|
19
|
+
*
|
|
20
|
+
* Founder ruling, 2026-10-05: every install panel on every surface takes its
|
|
21
|
+
* content and its design from here. The Console's `/drop` page and onboarding
|
|
22
|
+
* step, and later the landing site, drop this in and choose a configuration.
|
|
23
|
+
*
|
|
24
|
+
* ## Configurations, not content props
|
|
25
|
+
*
|
|
26
|
+
* What a surface MAY choose is which part of the content is on screen: the
|
|
27
|
+
* tools, the methods, the defaults, and whether the fetch prompt and footer show.
|
|
28
|
+
* Pass a named `preset` (`INSTALL_PRESETS.onboarding`, `installToolPreset("cursor")`)
|
|
29
|
+
* and override any field of it with the same-named prop.
|
|
30
|
+
*
|
|
31
|
+
* What a surface may NOT choose is the words. There is no `title`, `sub`, `tools`
|
|
32
|
+
* array or step override, deliberately: a prop that replaces content is a second
|
|
33
|
+
* source of content, and two sources is how the old panel and the library came
|
|
34
|
+
* to say different things about the same setup.
|
|
35
|
+
*
|
|
36
|
+
* ## What a page still passes
|
|
37
|
+
*
|
|
38
|
+
* The things only the page can know. Which tool is selected (`value` /
|
|
39
|
+
* `onValueChange`: onboarding records it as `tool_selected`, in the snapshot's
|
|
40
|
+
* slugs), which method (`method` / `onMethodChange`), the heading's level and
|
|
41
|
+
* size for where it sits, and a Continue action when the panel is a step.
|
|
42
|
+
*
|
|
43
|
+
* ## Not a client module, on purpose
|
|
44
|
+
*
|
|
45
|
+
* Nothing here holds state; `ToolSetup` and `AgentPrompt` carry their own
|
|
46
|
+
* `"use client"`. So a React Server Component can render this with a preset, and
|
|
47
|
+
* the gallery, which is a server module, can call `installSetupTools` below
|
|
48
|
+
* rather than keeping a second copy of the mapping.
|
|
49
|
+
*/
|
|
50
|
+
// Every mark name the content uses is a real key in the vendor-mark set. The
|
|
51
|
+
// content module spells them out so it can stay free of React types; this is the
|
|
52
|
+
// compile-time half of that bargain.
|
|
53
|
+
const MARKS = TOOL_MARKS;
|
|
54
|
+
const ICONS = {
|
|
55
|
+
terminal: TerminalIcon,
|
|
56
|
+
chat: ChatAppIcon,
|
|
57
|
+
github: GithubIcon,
|
|
58
|
+
download: DownloadIcon,
|
|
59
|
+
external: OpenLiveIcon,
|
|
60
|
+
};
|
|
61
|
+
function Glyph({ icon, className }) {
|
|
62
|
+
const Mark = ICONS[icon];
|
|
63
|
+
return _jsx(Mark, { className: className });
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Body runs to nodes. A bold run is a menu path or a folder and reads at medium
|
|
67
|
+
* weight in the ink colour; a code run is a command typed inline and reads in
|
|
68
|
+
* the mono face at the size around it. Both are tokens, so both flip per surface.
|
|
69
|
+
*/
|
|
70
|
+
function Body({ runs }) {
|
|
71
|
+
return (_jsx(_Fragment, { children: runs.map((run, i) => typeof run === "string" ? (_jsx(React.Fragment, { children: run }, i)) : "bold" in run ? (_jsx("b", { className: "font-medium text-ink", children: run.bold }, i)) : (_jsx("code", { "data-slot": "cloudgrid-install-code", className: "font-mono text-ink", children: run.code }, i))) }));
|
|
72
|
+
}
|
|
73
|
+
function toSetupStep(step) {
|
|
74
|
+
return {
|
|
75
|
+
...(step.label ? { label: step.label } : {}),
|
|
76
|
+
title: step.title,
|
|
77
|
+
...(step.body ? { body: _jsx(Body, { runs: step.body }) } : {}),
|
|
78
|
+
...(step.prompt ? { prompt: step.prompt } : {}),
|
|
79
|
+
...(step.code ? { code: step.code } : {}),
|
|
80
|
+
...(step.link
|
|
81
|
+
? {
|
|
82
|
+
link: {
|
|
83
|
+
label: step.link.label,
|
|
84
|
+
href: step.link.href,
|
|
85
|
+
...(step.link.icon ? { icon: _jsx(Glyph, { icon: step.link.icon }) } : {}),
|
|
86
|
+
...(step.link.primary ? { primary: true } : {}),
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
: {}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The content's tools as `ToolSetup` takes them, in the order asked for, with
|
|
94
|
+
* every vendor mark and every body rendered.
|
|
95
|
+
*
|
|
96
|
+
* Exported for a page that composes `ToolSetup` itself, which is what the
|
|
97
|
+
* library gallery's `ToolSetup` specimens do. A method missing from `methods`
|
|
98
|
+
* is dropped from each tool, so a tool with nothing left leaves the strip.
|
|
99
|
+
*
|
|
100
|
+
* 15px marks, which is what the strip draws. A mark carries no size of its own,
|
|
101
|
+
* so every call site states one.
|
|
102
|
+
*/
|
|
103
|
+
export function installSetupTools(tools = INSTALL_TOOLS.map((t) => t.value), methods = INSTALL_METHODS.map((m) => m.value)) {
|
|
104
|
+
return tools.flatMap((value) => {
|
|
105
|
+
const tool = INSTALL_TOOLS.find((t) => t.value === value);
|
|
106
|
+
if (!tool)
|
|
107
|
+
return [];
|
|
108
|
+
const steps = {};
|
|
109
|
+
for (const method of methods) {
|
|
110
|
+
const pane = tool.steps[method];
|
|
111
|
+
if (pane?.length)
|
|
112
|
+
steps[method] = pane.map(toSetupStep);
|
|
113
|
+
}
|
|
114
|
+
if (Object.keys(steps).length === 0)
|
|
115
|
+
return [];
|
|
116
|
+
const { Mark, hex } = MARKS[tool.mark];
|
|
117
|
+
return [
|
|
118
|
+
{
|
|
119
|
+
value: tool.value,
|
|
120
|
+
label: tool.label,
|
|
121
|
+
group: tool.group,
|
|
122
|
+
mark: _jsx(ToolLogo, { name: tool.mark, hex: hex, mark: _jsx(Mark, {}), size: 15 }),
|
|
123
|
+
steps,
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/** The two runs, each drawn as its glyph and named by its words. */
|
|
129
|
+
export function installSetupGroups() {
|
|
130
|
+
return INSTALL_GROUPS.map((group) => ({
|
|
131
|
+
value: group.value,
|
|
132
|
+
label: group.label,
|
|
133
|
+
icon: _jsx(Glyph, { icon: group.icon }),
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* "Not sure? Copy this prompt and paste it to your AI agent." over the one
|
|
138
|
+
* command an agent can act on.
|
|
139
|
+
*
|
|
140
|
+
* The outline pill, as the Console drew it under the panel, so it reads the
|
|
141
|
+
* surface it sits on. `showIntro={false}` is the standalone pill, which is what
|
|
142
|
+
* the old `fetch-prompt` block was.
|
|
143
|
+
*/
|
|
144
|
+
function CloudGridFetchPrompt({ showIntro = true, ...props }) {
|
|
145
|
+
return (_jsx(AgentPrompt, { "data-part": "cloudgrid-fetch-prompt", variant: "outline", ...(showIntro ? { label: INSTALL_FETCH_PROMPT.intro } : {}), command: INSTALL_FETCH_PROMPT.command, copyLabel: "Copy fetch prompt", ...props }));
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The source line: one sentence, then the two repositories.
|
|
149
|
+
*
|
|
150
|
+
* `text-body` and not `text-faint`: faint is large-text-legal only (#232), and
|
|
151
|
+
* this is 15px. Every colour is a token, so it flips on the panel and on ink with
|
|
152
|
+
* the rest of the block; a container that sets `data-cg-surface` still owes its
|
|
153
|
+
* own `text-ink` (rule 3).
|
|
154
|
+
*/
|
|
155
|
+
function CloudGridInstallFooter({ className, ...props }) {
|
|
156
|
+
return (_jsxs("footer", { "data-slot": "cloudgrid-install-footer", className: cn("flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-body-sm text-body", className), ...props, children: [_jsx("span", { children: INSTALL_FOOTER.note }), INSTALL_FOOTER.links.map((link) => (_jsxs("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", "data-slot": "cloudgrid-install-footer-link", className: "inline-flex items-center gap-1.5 text-body underline underline-offset-4 hover:text-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", children: [link.icon ? _jsx(Glyph, { icon: link.icon, className: "size-4 shrink-0" }) : null, link.label] }, link.href)))] }));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Keep the caller's order and drop what does not exist, so a preset naming a
|
|
160
|
+
* method or tool this content does not have cannot put an empty tab on screen.
|
|
161
|
+
*/
|
|
162
|
+
function known(asked, all) {
|
|
163
|
+
return asked ? asked.filter((v) => all.includes(v)) : [...all];
|
|
164
|
+
}
|
|
165
|
+
function CloudGridInstall({ preset, tools, methods, defaultTool, defaultMethod, showFetchPrompt, showFooter, value, onValueChange, method, onMethodChange, level = 1, headingSize, continueLabel = null, onContinue, canContinue = true, className, ...props }) {
|
|
166
|
+
const base = { ...INSTALL_PRESETS.hub, ...preset };
|
|
167
|
+
const toolValues = known(tools ?? base.tools, INSTALL_TOOLS.map((t) => t.value));
|
|
168
|
+
const methodValues = known(methods ?? base.methods, INSTALL_METHODS.map((m) => m.value));
|
|
169
|
+
const withFetchPrompt = showFetchPrompt ?? base.showFetchPrompt ?? true;
|
|
170
|
+
const withFooter = showFooter ?? base.showFooter ?? true;
|
|
171
|
+
const setupTools = installSetupTools(toolValues, methodValues);
|
|
172
|
+
// A default the filter has removed is dropped rather than passed on. Handed
|
|
173
|
+
// through, `ToolSetup` would fall back to the first tab AND report that
|
|
174
|
+
// fallback, which would reach an analytics handler as a selection nobody made.
|
|
175
|
+
const askedTool = defaultTool ?? base.defaultTool;
|
|
176
|
+
const firstTool = setupTools.some((t) => t.value === askedTool) ? askedTool : undefined;
|
|
177
|
+
const askedMethod = defaultMethod ?? base.defaultMethod;
|
|
178
|
+
const firstMethod = askedMethod && methodValues.includes(askedMethod) ? askedMethod : undefined;
|
|
179
|
+
const setupMethods = INSTALL_METHODS.filter((m) => methodValues.includes(m.value))
|
|
180
|
+
// The caller's order, not the content's.
|
|
181
|
+
.sort((a, b) => methodValues.indexOf(a.value) - methodValues.indexOf(b.value));
|
|
182
|
+
return (_jsxs("div", { "data-slot": "cloudgrid-install", className: cn("flex flex-col gap-6", className), ...props, children: [_jsx(ToolSetup, { title: INSTALL_HEADING.title, sub: INSTALL_HEADING.sub, level: level, ...(headingSize ? { headingSize } : {}), tools: setupTools, methods: setupMethods, groups: installSetupGroups(), ...(value !== undefined ? { value } : {}), ...(firstTool ? { defaultValue: firstTool } : {}), ...(onValueChange
|
|
183
|
+
? { onValueChange: (next) => onValueChange(next) }
|
|
184
|
+
: {}), ...(method !== undefined ? { method } : {}), ...(firstMethod ? { defaultMethod: firstMethod } : {}), ...(onMethodChange
|
|
185
|
+
? { onMethodChange: (next) => onMethodChange(next) }
|
|
186
|
+
: {}),
|
|
187
|
+
// The panel's own action row sits under the fetch prompt and the footer,
|
|
188
|
+
// below, so the step's primary action is the last thing on it.
|
|
189
|
+
continueLabel: null }), withFetchPrompt ? _jsx(CloudGridFetchPrompt, {}) : null, withFooter ? _jsx(CloudGridInstallFooter, {}) : null, continueLabel !== null ? (_jsx("div", { "data-slot": "cloudgrid-install-actions", className: "flex flex-col items-start gap-4", children: _jsx(Button, { type: "button", size: "lg", "data-slot": "cloudgrid-install-continue", onClick: onContinue, disabled: !canContinue, children: continueLabel }) })) : null] }));
|
|
190
|
+
}
|
|
191
|
+
export { CloudGridFetchPrompt, CloudGridInstall, CloudGridInstallFooter };
|
|
192
|
+
//# sourceMappingURL=cloudgrid-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudgrid-install.js","sourceRoot":"","sources":["../../src/blocks/cloudgrid-install.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* One command in a hairline field, with the Copy control inside its right edge.
|
|
4
|
+
*
|
|
5
|
+
* The third member of the copy family, and the gap the install blocks (#262)
|
|
6
|
+
* found. The other two both say something this one must not:
|
|
7
|
+
*
|
|
8
|
+
* `CodeBlock` an ink slab with padding for prose. A one-line `npm install`
|
|
9
|
+
* in it is a black rectangle with a sentence of air around it.
|
|
10
|
+
* `AgentPrompt` a pill with a prompt mark and a blinking caret, which says
|
|
11
|
+
* "this is a live shell". The design's field is a value you
|
|
12
|
+
* take away, not a terminal you are looking at.
|
|
13
|
+
*
|
|
14
|
+
* It is NOT `InputGroup` either, for the reason that component's own name gives:
|
|
15
|
+
* that is a form control, it takes input, and a field the user cannot type into
|
|
16
|
+
* should not be announced as one.
|
|
17
|
+
*
|
|
18
|
+
* ## The one line does not wrap, and that is deliberate
|
|
19
|
+
*
|
|
20
|
+
* A JSON blob or a long `npx` line is one token as far as the user is concerned,
|
|
21
|
+
* and wrapping it inside a 40%-width column turns a copyable value into three
|
|
22
|
+
* ragged lines that read like three commands. It scrolls horizontally instead,
|
|
23
|
+
* with the scrollbar hidden the way `Tabs`'s pill strip hides its own: the value
|
|
24
|
+
* is copied by the button, never read to the end by hand.
|
|
25
|
+
*
|
|
26
|
+
* ## Copy feedback is announced, not merely shown
|
|
27
|
+
*
|
|
28
|
+
* `CodeBlock`'s treatment, kept, including the honest failure: `navigator.clipboard`
|
|
29
|
+
* rejects on an insecure origin, in some frames and without permission, and a
|
|
30
|
+
* button that appears to do nothing is worse than one that says it was blocked.
|
|
31
|
+
*/
|
|
32
|
+
declare function CommandField({ command, copyLabel, className, ...props }: Omit<React.ComponentProps<"div">, "ref"> & {
|
|
33
|
+
command: string;
|
|
34
|
+
/** The visible label on the control. Its accessible name names the command. */
|
|
35
|
+
copyLabel?: string;
|
|
36
|
+
}): React.JSX.Element;
|
|
37
|
+
export { CommandField };
|
|
38
|
+
//# sourceMappingURL=command-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-field.d.ts","sourceRoot":"","sources":["../../src/blocks/command-field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,iBAAS,YAAY,CAAC,EACpB,OAAO,EACP,SAAkB,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,qBAmEA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Button } from "../ui/button.js";
|
|
5
|
+
import { cn } from "../lib/cloudgrid-cn.js";
|
|
6
|
+
/**
|
|
7
|
+
* One command in a hairline field, with the Copy control inside its right edge.
|
|
8
|
+
*
|
|
9
|
+
* The third member of the copy family, and the gap the install blocks (#262)
|
|
10
|
+
* found. The other two both say something this one must not:
|
|
11
|
+
*
|
|
12
|
+
* `CodeBlock` an ink slab with padding for prose. A one-line `npm install`
|
|
13
|
+
* in it is a black rectangle with a sentence of air around it.
|
|
14
|
+
* `AgentPrompt` a pill with a prompt mark and a blinking caret, which says
|
|
15
|
+
* "this is a live shell". The design's field is a value you
|
|
16
|
+
* take away, not a terminal you are looking at.
|
|
17
|
+
*
|
|
18
|
+
* It is NOT `InputGroup` either, for the reason that component's own name gives:
|
|
19
|
+
* that is a form control, it takes input, and a field the user cannot type into
|
|
20
|
+
* should not be announced as one.
|
|
21
|
+
*
|
|
22
|
+
* ## The one line does not wrap, and that is deliberate
|
|
23
|
+
*
|
|
24
|
+
* A JSON blob or a long `npx` line is one token as far as the user is concerned,
|
|
25
|
+
* and wrapping it inside a 40%-width column turns a copyable value into three
|
|
26
|
+
* ragged lines that read like three commands. It scrolls horizontally instead,
|
|
27
|
+
* with the scrollbar hidden the way `Tabs`'s pill strip hides its own: the value
|
|
28
|
+
* is copied by the button, never read to the end by hand.
|
|
29
|
+
*
|
|
30
|
+
* ## Copy feedback is announced, not merely shown
|
|
31
|
+
*
|
|
32
|
+
* `CodeBlock`'s treatment, kept, including the honest failure: `navigator.clipboard`
|
|
33
|
+
* rejects on an insecure origin, in some frames and without permission, and a
|
|
34
|
+
* button that appears to do nothing is worse than one that says it was blocked.
|
|
35
|
+
*/
|
|
36
|
+
function CommandField({ command, copyLabel = "Copy", className, ...props }) {
|
|
37
|
+
const [state, setState] = React.useState("idle");
|
|
38
|
+
const timer = React.useRef(undefined);
|
|
39
|
+
React.useEffect(() => () => clearTimeout(timer.current), []);
|
|
40
|
+
async function copy() {
|
|
41
|
+
try {
|
|
42
|
+
await navigator.clipboard.writeText(command);
|
|
43
|
+
setState("copied");
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
setState("blocked");
|
|
47
|
+
}
|
|
48
|
+
clearTimeout(timer.current);
|
|
49
|
+
timer.current = setTimeout(() => setState("idle"), 1600);
|
|
50
|
+
}
|
|
51
|
+
return (_jsxs("div", { "data-slot": "command-field", className: cn(
|
|
52
|
+
// `bg-(--cg-hover)` and not `bg-subtle`: --cg-surface-subtle is declared
|
|
53
|
+
// at :root only, so on ink it stays the lavender #f2f1f7 and the field
|
|
54
|
+
// becomes a near-white slab with white text in it. --cg-hover is the one
|
|
55
|
+
// ground token declared in all three scopes. `PromptBlock`'s FIELD note
|
|
56
|
+
// has the full version, including why it has no generated utility.
|
|
57
|
+
"flex items-center gap-2 rounded-xs border border-line bg-(--cg-hover) py-2 pr-2 pl-3", className), ...props, children: [_jsx("code", { "data-slot": "command-field-value", className: "min-w-0 flex-1 overflow-x-auto font-mono text-mono whitespace-pre text-ink [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: command }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: copy, "data-slot": "command-field-copy", "data-state": state,
|
|
58
|
+
// `bg-transparent` is not cosmetic, and `CodeBlock` carries the same
|
|
59
|
+
// override with the same reasoning (#20): the outline variant sets
|
|
60
|
+
// `bg-background`, which maps to `--cg-surface-page` and is deliberately
|
|
61
|
+
// NOT flipped per surface, while its label colour IS. On ink that is
|
|
62
|
+
// white text on a white pill.
|
|
63
|
+
className: "shrink-0 bg-transparent", "aria-label": `Copy ${command} to the clipboard`, children: state === "copied" ? "Copied" : state === "blocked" ? "Blocked" : copyLabel }), _jsx("span", { "aria-live": "polite", className: "sr-only", children: state === "copied"
|
|
64
|
+
? "Copied to the clipboard"
|
|
65
|
+
: state === "blocked"
|
|
66
|
+
? "The browser blocked the copy"
|
|
67
|
+
: "" })] }));
|
|
68
|
+
}
|
|
69
|
+
export { CommandField };
|
|
70
|
+
//# sourceMappingURL=command-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-field.js","sourceRoot":"","sources":["../../src/blocks/command-field.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,SAAS,YAAY,CAAC,EACpB,OAAO,EACP,SAAS,GAAG,MAAM,EAClB,SAAS,EACT,GAAG,KAAK,EAKT;IACC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAgC,MAAM,CAAC,CAAA;IAC/E,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAA4C,SAAS,CAAC,CAAA;IAEhF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;IAE5D,KAAK,UAAU,IAAI;QACjB,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAC5C,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,SAAS,CAAC,CAAA;QACrB,CAAC;QACD,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC3B,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAA;IAC1D,CAAC;IAED,OAAO,CACL,4BACY,eAAe,EACzB,SAAS,EAAE,EAAE;QACX,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,mEAAmE;QACnE,sFAAsF,EACtF,SAAS,CACV,KACG,KAAK,aAET,4BACY,qBAAqB,EAC/B,SAAS,EAAC,iIAAiI,YAE1I,OAAO,GACH,EAEP,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,IAAI,eACH,oBAAoB,gBAClB,KAAK;gBACjB,qEAAqE;gBACrE,mEAAmE;gBACnE,yEAAyE;gBACzE,qEAAqE;gBACrE,8BAA8B;gBAC9B,SAAS,EAAC,yBAAyB,gBAGvB,QAAQ,OAAO,mBAAmB,YAE7C,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GACrE,EAET,4BAAgB,QAAQ,EAAC,SAAS,EAAC,SAAS,YACzC,KAAK,KAAK,QAAQ;oBACjB,CAAC,CAAC,yBAAyB;oBAC3B,CAAC,CAAC,KAAK,KAAK,SAAS;wBACnB,CAAC,CAAC,8BAA8B;wBAChC,CAAC,CAAC,EAAE,GACH,IACH,CACP,CAAA;AACH,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -4,7 +4,8 @@ import * as React from "react";
|
|
|
4
4
|
*
|
|
5
5
|
* Built from scratch rather than on a Base UI primitive because there is not one.
|
|
6
6
|
* `@base-ui/react@1.7.0` exports 82 subpaths and none of them is file, drop or
|
|
7
|
-
* drag shaped, so this is the same category as
|
|
7
|
+
* drag shaped, so this is the same category as CodeBlock: a block that owns a
|
|
8
|
+
* gesture rather than a control that owns a value.
|
|
8
9
|
*
|
|
9
10
|
* ## The keyboard path is a real file input
|
|
10
11
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-zone.d.ts","sourceRoot":"","sources":["../../src/blocks/drop-zone.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B
|
|
1
|
+
{"version":3,"file":"drop-zone.d.ts","sourceRoot":"","sources":["../../src/blocks/drop-zone.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,KAAK,aAAa,GAAG;IACnB,qDAAqD;IACrD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAA;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAA;IAClC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,wDAAwD;IACxD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,yBAAyB;IACzB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,uCAAuC;IACvC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAoBD,iBAAS,QAAQ,CAAC,EAChB,MAAM,EACN,QAAQ,EACR,MAAM,EACN,QAAgB,EAChB,QAAgB,EAChB,OAAe,EACf,KAAgC,EAChC,IAAgC,EAChC,MAA2C,EAC3C,IAAI,EACJ,EAAE,EACF,SAAS,GACV,EAAE,aAAa,qBA8Kf;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA;AACnB,YAAY,EAAE,aAAa,EAAE,CAAA"}
|