@w6w/ui 0.1.0 → 0.2.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/CHANGELOG.md +40 -0
- package/README.md +25 -8
- package/dist/AppPicker.d.ts +1 -0
- package/dist/ConfirmModal-ChoiGy2K.cjs +11 -0
- package/dist/ConfirmModal-ChoiGy2K.cjs.map +1 -0
- package/dist/{ConfirmModal-sY1tzkBO.js → ConfirmModal-Wx3i8F1n.js} +4470 -4446
- package/dist/ConfirmModal-Wx3i8F1n.js.map +1 -0
- package/dist/ConnectionHeader.d.ts +19 -0
- package/dist/EditConnectionModal.d.ts +21 -0
- package/dist/app-pages.d.ts +3 -0
- package/dist/code.cjs +1 -1
- package/dist/code.mjs +1 -0
- package/dist/code.mjs.map +1 -1
- package/dist/components/AuthFieldsForm.d.ts +8 -1
- package/dist/components/CallableList.d.ts +57 -0
- package/dist/components/ConnectionList.d.ts +44 -0
- package/dist/components/ListItem.d.ts +16 -6
- package/dist/components/ReliabilityChart.d.ts +10 -0
- package/dist/components/ReliabilityList.d.ts +47 -0
- package/dist/connection-app-meta.d.ts +32 -0
- package/dist/flow.cjs +1 -1
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.d.ts +3 -1
- package/dist/flow.mjs +50 -49
- package/dist/flow.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.mjs +1701 -891
- package/dist/index.mjs.map +1 -1
- package/dist/provider.d.ts +21 -1
- package/dist/reliability-board-layout.d.ts +121 -0
- package/dist/types.d.ts +8 -0
- package/package.json +3 -2
- package/src/code.css +23 -4
- package/src/styles/_callable-list.scss +60 -0
- package/src/styles/_connections.scss +100 -0
- package/src/styles/_flow.scss +4 -4
- package/src/styles/_lists.scss +4 -0
- package/src/styles/_reliability.scss +339 -0
- package/src/styles/_tokens.scss +23 -4
- package/src/styles.css +4386 -3108
- package/src/styles.scss +3 -0
- package/dist/ConfirmModal-DJPYXE9t.cjs +0 -11
- package/dist/ConfirmModal-DJPYXE9t.cjs.map +0 -1
- package/dist/ConfirmModal-sY1tzkBO.js.map +0 -1
- package/dist/ui.css +0 -1
package/dist/provider.d.ts
CHANGED
|
@@ -119,12 +119,21 @@ export interface ListAppsPageOptions {
|
|
|
119
119
|
compact?: boolean;
|
|
120
120
|
/** Abort this request. Local request control only; never a wire field. */
|
|
121
121
|
signal?: AbortSignal;
|
|
122
|
+
/** Snapshot id from a prior {@link AppsPageResult.snapshot}. Navigation normally uses `cursor` alone. */
|
|
123
|
+
snapshot?: string;
|
|
124
|
+
/** Absolute offset into the snapshot. */
|
|
125
|
+
offset?: number;
|
|
122
126
|
}
|
|
123
127
|
/** One page of apps, as returned by {@link W6WApi.listAppsPage}. */
|
|
124
128
|
export interface AppsPageResult {
|
|
125
129
|
apps: AppSummary[];
|
|
126
130
|
/** Present unless this is the last page. */
|
|
127
131
|
nextCursor?: string;
|
|
132
|
+
snapshot?: string;
|
|
133
|
+
total?: number;
|
|
134
|
+
offset?: number;
|
|
135
|
+
limit?: number;
|
|
136
|
+
expiresAt?: string;
|
|
128
137
|
}
|
|
129
138
|
export interface W6WApi {
|
|
130
139
|
/**
|
|
@@ -174,6 +183,16 @@ export interface W6WApi {
|
|
|
174
183
|
displayName?: string;
|
|
175
184
|
profile?: Record<string, unknown>;
|
|
176
185
|
}): Promise<ConnectionSummary>;
|
|
186
|
+
/**
|
|
187
|
+
* Rename a connection and/or replace some of its credential fields (`PATCH /connections/:id`).
|
|
188
|
+
* Send only the fields being changed: the server merges a partial `credential` over the stored
|
|
189
|
+
* one. Optional: when absent, `EditConnectionModal` shows no Save button (a one-line notice
|
|
190
|
+
* instead) and hosts should not offer an Edit action. It never throws for the absence.
|
|
191
|
+
*/
|
|
192
|
+
updateConnection?(id: string, body: {
|
|
193
|
+
displayName?: string;
|
|
194
|
+
credential?: Record<string, unknown>;
|
|
195
|
+
}): Promise<ConnectionSummary>;
|
|
177
196
|
/**
|
|
178
197
|
* Start an OAuth 2.0 flow. Server builds the provider's authorize URL and
|
|
179
198
|
* returns it; the caller opens it in a popup and awaits the server's
|
|
@@ -375,7 +394,8 @@ export interface W6WUIProviderProps {
|
|
|
375
394
|
api: W6WApi;
|
|
376
395
|
/**
|
|
377
396
|
* Force the theme every `@w6w/ui` component resolves to — both the CSS
|
|
378
|
-
* tokens (`styles.css`'s `:where([data-theme=...])` blocks
|
|
397
|
+
* tokens (`styles.css`'s `:where([data-theme=...])` blocks; `color-scheme` is
|
|
398
|
+
* declared on component roots, never on the host `<html>`) and the
|
|
379
399
|
* JS-side theme-aware components (`AppIcon`, `CodeEditor`, `JsonEditor`,
|
|
380
400
|
* `WorkflowFlowEditor`, via `useEffectiveTheme`) — instead of each one
|
|
381
401
|
* independently falling back to `data-theme` on `<html>` or the visitor's
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the reliability board arranges itself — the decisions that are arithmetic
|
|
3
|
+
* rather than markup, kept pure (no React, no DOM) so they test without a DOM
|
|
4
|
+
* and so `@w6w/embed` can import them beside the components.
|
|
5
|
+
*
|
|
6
|
+
* **None of these decide a STATE.** Every state read below arrived already
|
|
7
|
+
* decided by the server; nothing here compares a ratio, applies a threshold to
|
|
8
|
+
* call data, or invents a fifth word. What these decide is where a row is PUT,
|
|
9
|
+
* which is presentation.
|
|
10
|
+
*/
|
|
11
|
+
/** The four words the server uses for a health verdict. */
|
|
12
|
+
export type ReliabilityViewState = "ok" | "degraded" | "down" | "unknown";
|
|
13
|
+
/**
|
|
14
|
+
* The row shape the reliability components render — owned by `@w6w/ui` so it
|
|
15
|
+
* imports nothing from the SDK. The SDK's `ReliabilityService` assigns to it
|
|
16
|
+
* structurally; the generic functions below keep the caller's richer row type.
|
|
17
|
+
*/
|
|
18
|
+
export interface ReliabilityServiceView {
|
|
19
|
+
appId: string;
|
|
20
|
+
displayName: string;
|
|
21
|
+
/** Inline icon fields — the board never asks a catalog for them. */
|
|
22
|
+
iconSrc?: string;
|
|
23
|
+
iconSrcDark?: string;
|
|
24
|
+
brandColor?: string;
|
|
25
|
+
/** "Did YOUR calls succeed". */
|
|
26
|
+
state: ReliabilityViewState;
|
|
27
|
+
calls: number;
|
|
28
|
+
errors: {
|
|
29
|
+
e4xx: number;
|
|
30
|
+
e429: number;
|
|
31
|
+
eAuth: number;
|
|
32
|
+
e5xx: number;
|
|
33
|
+
};
|
|
34
|
+
p95Ms: number | null;
|
|
35
|
+
ongoingOutageId: string | null;
|
|
36
|
+
/** One entry per calendar day, oldest first, exactly as the server sent it. */
|
|
37
|
+
uptime: readonly {
|
|
38
|
+
day: string;
|
|
39
|
+
state: ReliabilityViewState;
|
|
40
|
+
}[];
|
|
41
|
+
/** "What does the vendor say about itself"; `null` when no public check exists. */
|
|
42
|
+
vendorStatus: {
|
|
43
|
+
state: ReliabilityViewState;
|
|
44
|
+
message: string | null;
|
|
45
|
+
} | null;
|
|
46
|
+
/** The server's tier for the row — read, never re-derived. */
|
|
47
|
+
attention: "now" | "recent" | "none";
|
|
48
|
+
}
|
|
49
|
+
/** One point of the performance scatter — a service with both a call volume and a measured p95. */
|
|
50
|
+
export interface PerformancePoint {
|
|
51
|
+
appId: string;
|
|
52
|
+
displayName: string;
|
|
53
|
+
calls: number;
|
|
54
|
+
p95Ms: number;
|
|
55
|
+
state: ReliabilityViewState;
|
|
56
|
+
/** Total errors across all four kinds — drives the point's size, not its position. */
|
|
57
|
+
errorCount: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Every service with at least one timed call, as a (calls, p95) point — what
|
|
61
|
+
* the performance chart plots. Excludes `p95Ms: null`: there is no Y position
|
|
62
|
+
* for a service with nothing timed.
|
|
63
|
+
*/
|
|
64
|
+
export declare function performancePoints(services: readonly ReliabilityServiceView[]): PerformancePoint[];
|
|
65
|
+
/**
|
|
66
|
+
* Does this service want the reader's attention? READS the tier the server
|
|
67
|
+
* sent (`attention`), never re-derives it from `state` or `vendorStatus`: the
|
|
68
|
+
* server's `boardRank` is the one implementation, and a second copy here would
|
|
69
|
+
* drift. `now` and `recent` both count; they differ in tense only.
|
|
70
|
+
*/
|
|
71
|
+
export declare function needsAttention(service: Pick<ReliabilityServiceView, "attention">): boolean;
|
|
72
|
+
/** The board in its three groups, each keeping the server's own ordering. */
|
|
73
|
+
export interface BoardPartition<T extends ReliabilityServiceView = ReliabilityServiceView> {
|
|
74
|
+
/** Broken right now, on either signal. */
|
|
75
|
+
now: T[];
|
|
76
|
+
/** Clear now, but this window holds a failed stretch or an open advisory. */
|
|
77
|
+
recent: T[];
|
|
78
|
+
/** Everything else, in the server's recency order. */
|
|
79
|
+
clear: T[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Group the board without reordering within any group. Bucketing is not
|
|
83
|
+
* sorting: each group comes out in the order it arrived. An unrecognised
|
|
84
|
+
* `attention` value falls to `clear` rather than throwing — a client can be
|
|
85
|
+
* older than the server that answered it.
|
|
86
|
+
*/
|
|
87
|
+
export declare function partitionBoard<T extends ReliabilityServiceView>(services: readonly T[]): BoardPartition<T>;
|
|
88
|
+
/**
|
|
89
|
+
* The uptime strip's cells for one service — the server's own array, in the
|
|
90
|
+
* order it arrived (oldest first). A passthrough on purpose: no sort, no
|
|
91
|
+
* reverse, no gap filling. The strip has no date axis, so a reversed array is
|
|
92
|
+
* visually plausible and would silently move an outage to the wrong end.
|
|
93
|
+
*/
|
|
94
|
+
export declare function uptimeDays(service: Pick<ReliabilityServiceView, "uptime">): {
|
|
95
|
+
day: string;
|
|
96
|
+
state: ReliabilityViewState;
|
|
97
|
+
}[];
|
|
98
|
+
/** Compact mode shows at most this many needs-attention cards, `now` filling first. */
|
|
99
|
+
export declare const ATTENTION_DISPLAY_CAP = 3;
|
|
100
|
+
/** Compact mode shows this many table rows unless the caller passes `limit`. */
|
|
101
|
+
export declare const RECENT_DISPLAY_CAP = 5;
|
|
102
|
+
/** What the board shows and what a display cap hid. */
|
|
103
|
+
export interface BoardDisplay<T extends ReliabilityServiceView = ReliabilityServiceView> {
|
|
104
|
+
/** TRUE total of attention rows (the whole input, not the capped slice). */
|
|
105
|
+
attentionCount: number;
|
|
106
|
+
shownNow: T[];
|
|
107
|
+
shownRecent: T[];
|
|
108
|
+
hiddenAttentionCount: number;
|
|
109
|
+
/** Table rows in the server's order, every attention tier included. */
|
|
110
|
+
shownTable: T[];
|
|
111
|
+
hiddenTableCount: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Apply the display caps to the complete board. Compact: ≤ 3 attention cards
|
|
115
|
+
* (`now` first, `recent` tops up) and `limit ?? 5` table rows; otherwise
|
|
116
|
+
* uncapped. Hidden counts are computed from the full input, so they are real.
|
|
117
|
+
*/
|
|
118
|
+
export declare function displayBoard<T extends ReliabilityServiceView>(services: readonly T[], opts?: {
|
|
119
|
+
compact?: boolean;
|
|
120
|
+
limit?: number;
|
|
121
|
+
}): BoardDisplay<T>;
|
package/dist/types.d.ts
CHANGED
|
@@ -328,6 +328,14 @@ export interface ConnectionSummary {
|
|
|
328
328
|
profile?: Record<string, unknown>;
|
|
329
329
|
createdAt?: string;
|
|
330
330
|
updatedAt?: string;
|
|
331
|
+
/**
|
|
332
|
+
* True for the server's synthetic "no credential needed" rows. They have no stored credential,
|
|
333
|
+
* so the server 404s get/test/delete on their ids; the connection UI offers nothing on them.
|
|
334
|
+
* Detect with this flag only, never an id prefix.
|
|
335
|
+
*/
|
|
336
|
+
builtIn?: boolean;
|
|
337
|
+
/** The last test result: `false` = failed, `null`/absent = never tested. */
|
|
338
|
+
lastTestOk?: boolean | null;
|
|
331
339
|
}
|
|
332
340
|
/** A saved set of action-test input values, scoped to a connection + action. */
|
|
333
341
|
export interface SavedTest {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@w6w/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "React components for w6w — central API management. Build plugins, apps and integrations on them.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://w6w.io",
|
|
@@ -98,10 +98,11 @@
|
|
|
98
98
|
"build:css": "node scripts/build-css.mjs",
|
|
99
99
|
"check:css": "node scripts/build-css.mjs --check",
|
|
100
100
|
"typecheck": "tsc -b --noEmit",
|
|
101
|
-
"test": "node --conditions=w6w-source --import ./src/test-jsx-loader.mjs --test src/__tests__/*.test.ts src/components/__tests__/*.test.ts",
|
|
101
|
+
"test": "node --max-old-space-size=2048 --conditions=w6w-source --import ./src/test-jsx-loader.mjs --test --test-concurrency=4 --test-timeout=120000 src/__tests__/*.test.ts src/components/__tests__/*.test.ts",
|
|
102
102
|
"test:picker-layout": "bash test/picker-layout/run.sh",
|
|
103
103
|
"test:expr-template": "bash test/expr-template/run.sh",
|
|
104
104
|
"test:action-test-form": "bash test/action-test-form/run.sh",
|
|
105
|
+
"test:host-isolation": "bash test/host-isolation/run.sh",
|
|
105
106
|
"test:copyable": "bash test/copyable/run.sh",
|
|
106
107
|
"test:pack-smoke": "bash test/pack-smoke/run.sh",
|
|
107
108
|
"storybook": "storybook dev -p 6006 --no-open",
|
package/src/code.css
CHANGED
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
*/
|
|
35
35
|
/* Light — the base defaults. */
|
|
36
36
|
:where(:root) {
|
|
37
|
-
color-scheme: light;
|
|
38
37
|
--w6w-bg: #f7f8fa;
|
|
39
38
|
--w6w-panel: #ffffff;
|
|
40
39
|
--w6w-panel-2: #f0f2f6;
|
|
@@ -57,13 +56,13 @@
|
|
|
57
56
|
--w6w-code-punctuation: #5f6875;
|
|
58
57
|
--w6w-code-variable: #953800;
|
|
59
58
|
--w6w-radius: 10px;
|
|
59
|
+
--w6w-scheme: light;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/* Dark — followed automatically from the OS preference (unless a host has
|
|
63
63
|
forced a mode via data-theme, which is handled by the blocks below). */
|
|
64
64
|
@media (prefers-color-scheme: dark) {
|
|
65
65
|
:where(:root) {
|
|
66
|
-
color-scheme: dark;
|
|
67
66
|
--w6w-bg: #0f1115;
|
|
68
67
|
--w6w-panel: #181b22;
|
|
69
68
|
--w6w-panel-2: #1f232c;
|
|
@@ -78,6 +77,7 @@
|
|
|
78
77
|
--w6w-health-down: var(--w6w-danger);
|
|
79
78
|
--w6w-health-unknown: #9aa3b2;
|
|
80
79
|
--w6w-icon-swatch: #1f232c;
|
|
80
|
+
--w6w-scheme: dark;
|
|
81
81
|
--w6w-code-comment: #7d8797;
|
|
82
82
|
--w6w-code-keyword: #d2a8ff;
|
|
83
83
|
--w6w-code-string: #7ee787;
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
/* Explicit mode. Declared AFTER the media query at equal (zero) specificity, so
|
|
91
91
|
a forced data-theme always beats the OS preference. */
|
|
92
92
|
:where([data-theme=light]) {
|
|
93
|
-
|
|
93
|
+
--w6w-scheme: light;
|
|
94
94
|
--w6w-bg: #f7f8fa;
|
|
95
95
|
--w6w-panel: #ffffff;
|
|
96
96
|
--w6w-panel-2: #f0f2f6;
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
:where([data-theme=dark]) {
|
|
118
|
-
|
|
118
|
+
--w6w-scheme: dark;
|
|
119
119
|
--w6w-bg: #0f1115;
|
|
120
120
|
--w6w-panel: #181b22;
|
|
121
121
|
--w6w-panel-2: #1f232c;
|
|
@@ -147,6 +147,25 @@
|
|
|
147
147
|
font-size: 0.85em;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/* color-scheme — declared on ui COMPONENT ROOTS, never on the host's <html>.
|
|
151
|
+
`color-scheme` inherits and also themes the page canvas, scrollbars and form
|
|
152
|
+
controls, so setting it on :root / [data-theme] let importing this file flip a
|
|
153
|
+
host's whole document. Instead each token block above also sets the
|
|
154
|
+
`--w6w-scheme` custom property (light / dark), which INHERITS, so the nearest
|
|
155
|
+
themed ancestor wins however themes nest (a light panel inside a dark page and
|
|
156
|
+
the reverse). Elements ui renders (any `w6w-` class, which covers the native
|
|
157
|
+
<dialog> modals) and the native controls inside them read it with
|
|
158
|
+
`color-scheme: var(--w6w-scheme)`. Not a hand-picked root list: every ui
|
|
159
|
+
component carries a `w6w-` class. Only an element whose class LIST has a token
|
|
160
|
+
starting `w6w-` matches (`class^=` / `class*=" w6w-"`), so host elements are never
|
|
161
|
+
touched: not a host `data-theme` wrapper, not a host class that merely contains
|
|
162
|
+
`w6w-` (`my-w6w-card`), and not a host element's own color-scheme on inputs nested
|
|
163
|
+
in a ui root (color-scheme inherits, so no descendant rule is needed). Nothing here
|
|
164
|
+
ever matches <html>/:root. All zero specificity. */
|
|
165
|
+
:where([class^=w6w-]:not(:root), [class*=" w6w-"]:not(:root)) {
|
|
166
|
+
color-scheme: var(--w6w-scheme);
|
|
167
|
+
}
|
|
168
|
+
|
|
150
169
|
/*
|
|
151
170
|
* @w6w/ui — the spacing / typography scale.
|
|
152
171
|
*
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
.w6w-callable-list {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--w6w-sp-4);
|
|
5
|
+
}
|
|
6
|
+
.w6w-callable-list-head {
|
|
7
|
+
display: flex;
|
|
8
|
+
justify-content: space-between;
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
gap: var(--w6w-sp-4);
|
|
11
|
+
}
|
|
12
|
+
.w6w-callable-list-heading {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
gap: var(--w6w-sp-1);
|
|
16
|
+
min-width: 0;
|
|
17
|
+
}
|
|
18
|
+
.w6w-callable-list-title {
|
|
19
|
+
margin: 0;
|
|
20
|
+
}
|
|
21
|
+
.w6w-callable-list-description {
|
|
22
|
+
margin: 0;
|
|
23
|
+
}
|
|
24
|
+
.w6w-callable-list-toggle {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: var(--w6w-sp-2);
|
|
28
|
+
cursor: pointer;
|
|
29
|
+
}
|
|
30
|
+
.w6w-callable-list-actions {
|
|
31
|
+
display: flex;
|
|
32
|
+
gap: var(--w6w-sp-2);
|
|
33
|
+
flex-shrink: 0;
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
}
|
|
36
|
+
.w6w-callable-list-body {
|
|
37
|
+
border: 1px solid var(--w6w-border);
|
|
38
|
+
border-radius: 8px;
|
|
39
|
+
padding: var(--w6w-sp-2);
|
|
40
|
+
}
|
|
41
|
+
.w6w-callable-list-rows {
|
|
42
|
+
list-style: none;
|
|
43
|
+
margin: 0;
|
|
44
|
+
padding: 0;
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
gap: var(--w6w-sp-1);
|
|
48
|
+
}
|
|
49
|
+
.w6w-callable-list-trail {
|
|
50
|
+
display: inline-flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
gap: var(--w6w-sp-2);
|
|
53
|
+
}
|
|
54
|
+
.w6w-callable-list-badge {
|
|
55
|
+
padding: var(--w6w-sp-0-5) var(--w6w-sp-2);
|
|
56
|
+
border-radius: 999px;
|
|
57
|
+
border: 1px solid var(--w6w-border);
|
|
58
|
+
color: var(--w6w-muted);
|
|
59
|
+
font-size: var(--w6w-fs-xs);
|
|
60
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* Connections (D-12u): ConnectionList, ConnectionHeader and the state tags they share. */
|
|
2
|
+
.w6w-connection-list {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
gap: var(--w6w-sp-3);
|
|
6
|
+
}
|
|
7
|
+
.w6w-connection-list-head {
|
|
8
|
+
display: flex;
|
|
9
|
+
justify-content: space-between;
|
|
10
|
+
align-items: flex-start;
|
|
11
|
+
gap: var(--w6w-sp-4);
|
|
12
|
+
}
|
|
13
|
+
.w6w-connection-list-heading {
|
|
14
|
+
min-width: 0;
|
|
15
|
+
}
|
|
16
|
+
.w6w-connection-list-actions {
|
|
17
|
+
display: flex;
|
|
18
|
+
gap: var(--w6w-sp-2);
|
|
19
|
+
flex-shrink: 0;
|
|
20
|
+
}
|
|
21
|
+
.w6w-connection-rows {
|
|
22
|
+
list-style: none;
|
|
23
|
+
margin: 0;
|
|
24
|
+
padding: 0;
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
gap: var(--w6w-sp-1);
|
|
28
|
+
}
|
|
29
|
+
.w6w-connection-row {
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
gap: var(--w6w-sp-2);
|
|
33
|
+
}
|
|
34
|
+
.w6w-connection-row-main {
|
|
35
|
+
flex: 1;
|
|
36
|
+
min-width: 0;
|
|
37
|
+
}
|
|
38
|
+
.w6w-connection-row-actions {
|
|
39
|
+
display: flex;
|
|
40
|
+
gap: var(--w6w-sp-1-5);
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
}
|
|
43
|
+
.w6w-connection-name {
|
|
44
|
+
margin-right: var(--w6w-sp-2);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* State tags (connected / needs attention / invalid). */
|
|
48
|
+
.w6w-connection-tag {
|
|
49
|
+
display: inline-block;
|
|
50
|
+
background: var(--w6w-panel-2);
|
|
51
|
+
border: 1px solid var(--w6w-border);
|
|
52
|
+
border-radius: 999px;
|
|
53
|
+
padding: var(--w6w-sp-0-5) var(--w6w-sp-2);
|
|
54
|
+
font-size: var(--w6w-fs-xs);
|
|
55
|
+
margin-right: var(--w6w-sp-1);
|
|
56
|
+
}
|
|
57
|
+
.w6w-connection-tag-warn {
|
|
58
|
+
color: #ffb86b;
|
|
59
|
+
border-color: #ffb86b;
|
|
60
|
+
}
|
|
61
|
+
.w6w-connection-tag-danger {
|
|
62
|
+
color: var(--w6w-danger);
|
|
63
|
+
border-color: var(--w6w-danger);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* ConnectionHeader */
|
|
67
|
+
.w6w-connection-header {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
gap: var(--w6w-sp-3);
|
|
71
|
+
}
|
|
72
|
+
.w6w-connection-header-main {
|
|
73
|
+
flex: 1;
|
|
74
|
+
min-width: 0;
|
|
75
|
+
}
|
|
76
|
+
.w6w-connection-header-title {
|
|
77
|
+
margin: 0;
|
|
78
|
+
}
|
|
79
|
+
.w6w-connection-header-meta {
|
|
80
|
+
margin: 0;
|
|
81
|
+
}
|
|
82
|
+
.w6w-connection-header-actions {
|
|
83
|
+
display: flex;
|
|
84
|
+
gap: var(--w6w-sp-1-5);
|
|
85
|
+
align-items: center;
|
|
86
|
+
}
|
|
87
|
+
/* The id's copy button appears on hover/focus only. */
|
|
88
|
+
.w6w-connection-id-copy.w6w-copyable {
|
|
89
|
+
display: inline-flex;
|
|
90
|
+
width: auto;
|
|
91
|
+
min-width: 0;
|
|
92
|
+
vertical-align: middle;
|
|
93
|
+
}
|
|
94
|
+
.w6w-connection-id-copy .w6w-copyable-btn {
|
|
95
|
+
opacity: 0;
|
|
96
|
+
}
|
|
97
|
+
.w6w-connection-id-copy:hover .w6w-copyable-btn,
|
|
98
|
+
.w6w-connection-id-copy:focus-within .w6w-copyable-btn {
|
|
99
|
+
opacity: 1;
|
|
100
|
+
}
|
package/src/styles/_flow.scss
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
added to that stack later inherits it with no styling of its own.
|
|
10
10
|
|
|
11
11
|
Custom properties, deliberately, rather than a `.react-flow__controls-button`
|
|
12
|
-
override:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
own rule and lose
|
|
12
|
+
override: React Flow's own stylesheet is compiled into the same
|
|
13
|
+
styles.css (`@use` in the build-only styles.build.scss), but cascade
|
|
14
|
+
order is not something to lean on: a bare class override (0,1,0) would tie
|
|
15
|
+
with the library's own rule and lose if the order ever changed. Custom properties inherit and are
|
|
16
16
|
order-independent, and scoping them on `.w6w-flow` keeps them off the rest of
|
|
17
17
|
the page.
|
|
18
18
|
|