elowen-plugin-ui-kit 0.10.0 → 0.11.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/index.d.ts +47 -1
- package/package.json +1 -1
- package/theme.css +119 -2
package/index.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export interface PluginConfigField {
|
|
|
53
53
|
display?: { control?: 'input' | 'slider'; unit?: string; divisor?: number };
|
|
54
54
|
browse?: 'directory';
|
|
55
55
|
default?: string | number | boolean | string[];
|
|
56
|
-
providerType?: string;
|
|
56
|
+
providerType?: string | string[];
|
|
57
57
|
options?: { value: string; label: string }[];
|
|
58
58
|
language?: string;
|
|
59
59
|
help?: string;
|
|
@@ -128,6 +128,52 @@ export interface ConfirmDialogProps {
|
|
|
128
128
|
onClose: () => void;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/** The durable operation row a progress window renders, as the daemon publishes it. List projections
|
|
132
|
+
* omit `logTail`; the single-operation read and the live `environment-operation` frame carry it.
|
|
133
|
+
* The status union is the daemon's own (`EnvironmentOperation` in the wire contract): an environment
|
|
134
|
+
* operation is never cancelled, and a status this side invents is one a bundle would render as "still
|
|
135
|
+
* preparing" forever. */
|
|
136
|
+
export interface EnvironmentOperationView {
|
|
137
|
+
id: string;
|
|
138
|
+
projectId: number;
|
|
139
|
+
generation: number;
|
|
140
|
+
action: { kind: string };
|
|
141
|
+
status: 'pending' | 'running' | 'succeeded' | 'failed';
|
|
142
|
+
error: string | null;
|
|
143
|
+
/** The declared step list, in order. Each entry is a stable id the host localizes. */
|
|
144
|
+
steps: string[];
|
|
145
|
+
stepIndex: number;
|
|
146
|
+
stepTotal: number;
|
|
147
|
+
stepLabel: string | null;
|
|
148
|
+
percent: number | null;
|
|
149
|
+
logTail?: string[];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Public props of `ElowenUiRuntime.components.OperationProgressDialog`: one installer-style window over
|
|
153
|
+
* a durable environment operation, rendered as `Modal` content by the host.
|
|
154
|
+
*
|
|
155
|
+
* Dismissing it while the work runs HIDES it — the operation outlives the tab that started it — so
|
|
156
|
+
* `onClose` reports whether it was still running and the call site decides whether to keep following. */
|
|
157
|
+
export interface OperationProgressDialogProps {
|
|
158
|
+
open: boolean;
|
|
159
|
+
/** What the person asked for, in their words. The dialog adds the step, never the intent. */
|
|
160
|
+
title: string;
|
|
161
|
+
operation: EnvironmentOperationView | null;
|
|
162
|
+
logTail?: string[];
|
|
163
|
+
/** A transport failure of the read that follows the operation, distinct from a failed operation. */
|
|
164
|
+
loadError?: string | null;
|
|
165
|
+
/** Run the same intent again. Omitted, the retry action is not offered. */
|
|
166
|
+
onRetry?: () => void;
|
|
167
|
+
/** The stale-environment repair. Offered only while `recreatable` holds. */
|
|
168
|
+
onRecreate?: () => void;
|
|
169
|
+
recreatable?: boolean;
|
|
170
|
+
onClose: (info: { running: boolean }) => void;
|
|
171
|
+
/** Fired once when a succeeded operation closes itself. */
|
|
172
|
+
onSettled?: () => void;
|
|
173
|
+
/** How long a success stays on screen before it closes itself. */
|
|
174
|
+
successDelayMs?: number;
|
|
175
|
+
}
|
|
176
|
+
|
|
131
177
|
/** Project metadata exposed to a contextual plugin panel. The Project remains core-owned; a panel uses
|
|
132
178
|
* this identity to address only its own project-scoped API data. */
|
|
133
179
|
export interface PluginUiProject {
|
package/package.json
CHANGED
package/theme.css
CHANGED
|
@@ -55,6 +55,46 @@
|
|
|
55
55
|
--color-sidebar-accent-foreground: var(--color-foreground);
|
|
56
56
|
--color-sidebar-border: var(--color-border);
|
|
57
57
|
--color-sidebar-ring: var(--color-ring);
|
|
58
|
+
/* NOT a shadcn token. The rule down the column's OUTER edge, and it now ALIASES
|
|
59
|
+
--color-sidebar-border rather than holding a colour of its own: the frame the top bar draws across
|
|
60
|
+
the window turns the corner and runs the full height of the column, so the vertical line and the
|
|
61
|
+
horizontal one have to resolve to one value or the frame changes colour where they meet. Owner
|
|
62
|
+
decision, 6 Sep 2026, overriding the transparent outer edge of 5 Sep — the column is framed on its
|
|
63
|
+
right the way the page is framed on top. The name stays because the two edges are still separate
|
|
64
|
+
DECISIONS: a design that wants its column to melt into the canvas sets this one token to
|
|
65
|
+
`transparent` and keeps the internal hairlines (header, footer, search field). */
|
|
66
|
+
--color-sidebar-rule: var(--color-sidebar-border);
|
|
67
|
+
|
|
68
|
+
/* The column's GEOMETRY, as measured off the Cloudflare dashboard (plans/cloudflare-sidebar-spec.md).
|
|
69
|
+
Separate tokens from the colours above because they are a different kind of decision: a skin
|
|
70
|
+
repaints the sidebar constantly and moves these almost never, and the primitive's collapsed rail
|
|
71
|
+
has to agree with the shell's flex basis or the fold animates to the wrong width.
|
|
72
|
+
`--sidebar-width-icon` is read by `components/ui/shadcn/sidebar.tsx`, which upstream injects as an
|
|
73
|
+
inline style — it is declared here so a skin can still override it. Its value is the reference's
|
|
74
|
+
measured 57px and it is stated ONCE, here: both Studio skins used to restate the same number, which
|
|
75
|
+
is two sources of truth for one measurement and a drift nothing would have caught. */
|
|
76
|
+
--sidebar-width: 16.25rem; /* 260px, the expanded column */
|
|
77
|
+
--sidebar-width-icon: 3.5625rem; /* 57px, the collapsed rail */
|
|
78
|
+
--sidebar-width-mobile: 18rem; /* the off-canvas presentation, wider than the desktop column */
|
|
79
|
+
--sidebar-row-height: 2.125rem; /* 34px, `min-h-8.5` in the reference */
|
|
80
|
+
--sidebar-row-radius: 0.5rem; /* 8px, `rounded-lg` in the reference's own scale */
|
|
81
|
+
--sidebar-row-inset: 0.75rem; /* 12px horizontal padding inside a row */
|
|
82
|
+
--sidebar-sub-indent: 1.75rem; /* 28px, `pl-7` per nesting level */
|
|
83
|
+
--sidebar-text: 0.8125rem; /* 13px, every row and group label */
|
|
84
|
+
--sidebar-header-height: 3.625rem; /* 58px, the switcher row above the header hairline */
|
|
85
|
+
--sidebar-switcher-height: 2.5rem; /* 40px, the switcher itself, centred inside that header */
|
|
86
|
+
/* The page's top bar is the SAME height as the sidebar header, because the hairline under each is ONE
|
|
87
|
+
line across the whole window: the column's header and the page's bar are two halves of one frame,
|
|
88
|
+
and 58px beside a 50px bar is what left a visible step where the two met. Stated as an ALIAS rather
|
|
89
|
+
than as a second 58px — they are one measurement, so a design that retunes the frame moves both by
|
|
90
|
+
moving the sidebar header. */
|
|
91
|
+
--topbar-height: var(--sidebar-header-height);
|
|
92
|
+
--sidebar-footer-height: 3rem; /* 48px, the fold's row below the footer hairline */
|
|
93
|
+
--sidebar-search-height: 2rem; /* 32px, the command palette's field under the header */
|
|
94
|
+
/* The disclosure caret's own duration. Not `--motion-base`: the Studio skins retune that to 150ms for
|
|
95
|
+
navigation, and the reference turns this caret in 200ms regardless of how fast the rest of the
|
|
96
|
+
column moves. A rotation is the one motion in the menu the eye follows to its end. */
|
|
97
|
+
--sidebar-caret-motion: 200ms;
|
|
58
98
|
|
|
59
99
|
--color-border: #242424;
|
|
60
100
|
/* NOT a shadcn token: the heavier rule, for a scrollbar thumb and a focused edge. */
|
|
@@ -90,6 +130,25 @@
|
|
|
90
130
|
--color-warning: #edae49;
|
|
91
131
|
--color-info: #62a8ea;
|
|
92
132
|
|
|
133
|
+
/* Code and diff surfaces. Mirrored from the host so a plugin sheet compiled against this kit resolves
|
|
134
|
+
the same values; the app renders diffs itself, so a plugin bundle has none of its own to paint. */
|
|
135
|
+
--color-diff-canvas: #0d0d10;
|
|
136
|
+
--color-diff-add: color-mix(in srgb, #005f00 30%, var(--color-diff-canvas));
|
|
137
|
+
--color-diff-add-marker: #50c850;
|
|
138
|
+
--color-diff-del: color-mix(in srgb, #5f0000 30%, var(--color-diff-canvas));
|
|
139
|
+
--color-diff-del-marker: #dc5a5a;
|
|
140
|
+
--color-diff-del-foreground: #f8f8f2;
|
|
141
|
+
--color-diff-gutter: #7d7d88;
|
|
142
|
+
|
|
143
|
+
--color-code-plain: #f8f8f2;
|
|
144
|
+
--color-code-keyword: #f92672;
|
|
145
|
+
--color-code-string: #e6db74;
|
|
146
|
+
--color-code-number: #ae81ff;
|
|
147
|
+
--color-code-comment: #75715e;
|
|
148
|
+
--color-code-type: #66d9ef;
|
|
149
|
+
--color-code-function: #a6e22e;
|
|
150
|
+
--color-code-punct: #f8f8f2;
|
|
151
|
+
|
|
93
152
|
/* The categorical series. Charts and legends read these and never a literal, so a repaint moves the
|
|
94
153
|
whole set. 1–3 are the brand ramp; 4 and 5 are deliberately UNLIKE it, so a swatch stays
|
|
95
154
|
distinguishable from its neighbours without borrowing `destructive` or `success` and implying a
|
|
@@ -111,8 +170,55 @@
|
|
|
111
170
|
--radius-2xl: 1.25rem;
|
|
112
171
|
|
|
113
172
|
--font-mono: var(--font-geist-mono), ui-monospace, "SF Mono", monospace;
|
|
114
|
-
|
|
115
|
-
|
|
173
|
+
|
|
174
|
+
/* Inter Variable is the app's ONE sans face, headings included. It is self-hosted
|
|
175
|
+
(`@fontsource-variable/inter`, imported in app/layout.tsx), so no rule here reaches Google Fonts.
|
|
176
|
+
|
|
177
|
+
`--font-geist-sans` is a COMPATIBILITY ALIAS, not a Geist reference: Geist Sans is no longer loaded,
|
|
178
|
+
but plugin stylesheets compiled against an older plugin-ui-kit still say `var(--font-geist-sans)`,
|
|
179
|
+
and an undefined variable inside a font-family list invalidates the whole declaration — the plugin
|
|
180
|
+
would fall back to the browser default rather than to Inter. Declaring it here keeps those bundles
|
|
181
|
+
rendering in the app's face. It is not a name new code should use; `--font-sans` is.
|
|
182
|
+
|
|
183
|
+
`--font-display` is `--font-sans` on purpose. It stays a separate token because a skin is entitled
|
|
184
|
+
to give headings a face of their own, but the built-in designs no longer do. */
|
|
185
|
+
--font-geist-sans: "Inter Variable", Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
186
|
+
--font-sans: var(--font-geist-sans);
|
|
187
|
+
--font-display: var(--font-sans);
|
|
188
|
+
|
|
189
|
+
/* Inter is drawn on a wider sidebearing than the reference design wants. The measured dashboard runs
|
|
190
|
+
-0.16px at 16px and -0.13px at 13px, which is the same optical correction expressed twice; as a
|
|
191
|
+
ratio it is -0.01em, so ONE token tracks both sizes and every other size in between. */
|
|
192
|
+
--tracking-ui: -0.01em;
|
|
193
|
+
|
|
194
|
+
/* ---- The type scale -------------------------------------------------------------------------
|
|
195
|
+
Five steps, measured off the reference dashboard (plans/cloudflare-sidebar-spec.md). Each one is a
|
|
196
|
+
Tailwind v4 TEXT token, which means it carries its line height, its weight and — where it differs
|
|
197
|
+
from the inherited ratio — its tracking with it. That is the property the app was missing: a
|
|
198
|
+
heading used to be assembled from a size here, a weight there and a letter-spacing somewhere else,
|
|
199
|
+
so every surface that wanted "a section title" wrote its own three-quarters of one, and no two
|
|
200
|
+
agreed. A rule now reads `var(--text-section-title)` and the rest of the step is one variable away.
|
|
201
|
+
|
|
202
|
+
`--text-page-title` is the ONE step that states its tracking absolutely. `--tracking-ui` above is a
|
|
203
|
+
RATIO, which is what makes the reference's -0.16px at 16px and -0.13px at 13px the same correction;
|
|
204
|
+
at 30px that ratio gives -0.3px, while the reference still runs -0.16px on its page title. A ratio
|
|
205
|
+
cannot express both, so the outlier says so here rather than in whichever stylesheet noticed. */
|
|
206
|
+
--text-page-title: 1.875rem; /* 30px, the single <h1> a page has */
|
|
207
|
+
--text-page-title--line-height: 2.25rem; /* 36px */
|
|
208
|
+
--text-page-title--font-weight: 600;
|
|
209
|
+
--text-page-title--letter-spacing: -0.16px;
|
|
210
|
+
--text-section-title: 1rem; /* 16px, the heading of a section card */
|
|
211
|
+
--text-section-title--line-height: 1.5rem;
|
|
212
|
+
--text-section-title--font-weight: 600;
|
|
213
|
+
--text-card-title: 0.875rem; /* 14px, the name of one record inside a card */
|
|
214
|
+
--text-card-title--line-height: 1.25rem;
|
|
215
|
+
--text-card-title--font-weight: 500;
|
|
216
|
+
--text-meta: 0.8125rem; /* 13px, the quiet line under a title */
|
|
217
|
+
--text-meta--line-height: 1.25rem;
|
|
218
|
+
--text-meta--font-weight: 400;
|
|
219
|
+
--text-body: 1rem; /* 16px/24px, the document's own step */
|
|
220
|
+
--text-body--line-height: 1.5rem;
|
|
221
|
+
--text-body--font-weight: 400;
|
|
116
222
|
|
|
117
223
|
--text-display: clamp(2rem, 1.55rem + 1.5vw, 3.25rem);
|
|
118
224
|
--text-caption: 0.6875rem;
|
|
@@ -146,6 +252,17 @@
|
|
|
146
252
|
turn the effect off by mixing to 100% and setting the blur to 0 without touching a component. */
|
|
147
253
|
--shadow-lift: 0 1px 0 rgb(255 255 255 / 0.05), 0 24px 60px rgb(0 0 0 / 0.34);
|
|
148
254
|
--glow-accent: 0 0 0 1px rgb(var(--primary-rgb) / 0.28), 0 0 30px rgb(var(--primary-rgb) / 0.18);
|
|
255
|
+
|
|
256
|
+
/* NOT a shadcn token. The resting depth of the ONE loud control on a page: a 1px ring in the brand
|
|
257
|
+
colour plus a short drop under it. The reference dashboard's primary button is not a flat rectangle
|
|
258
|
+
of blue — it has a defined edge and something beneath it, and that is most of why it reads as the
|
|
259
|
+
action rather than as a coloured label.
|
|
260
|
+
|
|
261
|
+
A separate token from `--glow-accent`, which is the FOCUS/ACTIVE halo and is therefore soft and
|
|
262
|
+
wide; this one is tight, opaque and always on. Composed from `--primary-rgb` so a white-label theme
|
|
263
|
+
retints it by moving that one variable, and each design states its own drop, because the value that
|
|
264
|
+
reads on a near-white page is a no-op on a true-black one. */
|
|
265
|
+
--shadow-primary: 0 0 0 1px rgb(var(--primary-rgb) / 0.9), 0 1px 2px rgb(0 0 0 / 0.4);
|
|
149
266
|
--glass-surface: color-mix(in srgb, var(--color-card) 62%, transparent);
|
|
150
267
|
--glass-border: color-mix(in srgb, var(--color-foreground) 10%, transparent);
|
|
151
268
|
--glass-blur: 18px;
|