@w6w/ui 0.0.0-stage → 0.1.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/LICENSE +21 -0
  3. package/README.md +260 -2
  4. package/dist/ActionTestForm.d.ts +76 -0
  5. package/dist/AddConnectionModal.d.ts +24 -0
  6. package/dist/AppPicker.d.ts +83 -0
  7. package/dist/CodeBlock-CZu4TFSi.cjs +15 -0
  8. package/dist/CodeBlock-CZu4TFSi.cjs.map +1 -0
  9. package/dist/CodeBlock-Dot3Pd7P.js +2889 -0
  10. package/dist/CodeBlock-Dot3Pd7P.js.map +1 -0
  11. package/dist/CodeBlock.d.ts +65 -0
  12. package/dist/CodeEditor.d.ts +42 -0
  13. package/dist/ConfirmModal-DJPYXE9t.cjs +11 -0
  14. package/dist/ConfirmModal-DJPYXE9t.cjs.map +1 -0
  15. package/dist/ConfirmModal-sY1tzkBO.js +6335 -0
  16. package/dist/ConfirmModal-sY1tzkBO.js.map +1 -0
  17. package/dist/Copyable-1niV9gUa.js +771 -0
  18. package/dist/Copyable-1niV9gUa.js.map +1 -0
  19. package/dist/Copyable-CYZU1o4X.cjs +2 -0
  20. package/dist/Copyable-CYZU1o4X.cjs.map +1 -0
  21. package/dist/JsonEditor.d.ts +60 -0
  22. package/dist/NodeConfigForm.d.ts +70 -0
  23. package/dist/ParamsForm.d.ts +56 -0
  24. package/dist/PropertyEntryForm.d.ts +56 -0
  25. package/dist/RetryPolicyFields.d.ts +18 -0
  26. package/dist/StepBuilderModal.d.ts +375 -0
  27. package/dist/TriggerFillForm.d.ts +52 -0
  28. package/dist/WaitEditor.d.ts +6 -0
  29. package/dist/WorkflowFlowEditor.d.ts +119 -0
  30. package/dist/YamlEditor.d.ts +46 -0
  31. package/dist/app-categories.d.ts +38 -0
  32. package/dist/app-pages.d.ts +111 -0
  33. package/dist/code.cjs +2 -0
  34. package/dist/code.cjs.map +1 -0
  35. package/dist/code.d.ts +29 -0
  36. package/dist/code.mjs +7 -0
  37. package/dist/code.mjs.map +1 -0
  38. package/dist/components/ApiCallsPanel.d.ts +41 -0
  39. package/dist/components/AppIcon.d.ts +25 -0
  40. package/dist/components/AuthFieldsForm.d.ts +22 -0
  41. package/dist/components/Combobox.d.ts +24 -0
  42. package/dist/components/ConfirmModal.d.ts +33 -0
  43. package/dist/components/Copyable.d.ts +51 -0
  44. package/dist/components/CopyableText.d.ts +40 -0
  45. package/dist/components/DeleteButton.d.ts +16 -0
  46. package/dist/components/EditButton.d.ts +10 -0
  47. package/dist/components/ExecutionDetail.d.ts +70 -0
  48. package/dist/components/ExecutionFilters.d.ts +59 -0
  49. package/dist/components/ExecutionList.d.ts +60 -0
  50. package/dist/components/ExecutionLogPanel.d.ts +98 -0
  51. package/dist/components/ExecutionStats.d.ts +47 -0
  52. package/dist/components/ExpressionEditorModal.d.ts +42 -0
  53. package/dist/components/ExpressionInput.d.ts +36 -0
  54. package/dist/components/ExpressionOptions.d.ts +185 -0
  55. package/dist/components/HealthStatusPill.d.ts +25 -0
  56. package/dist/components/HistoryTimeline.d.ts +56 -0
  57. package/dist/components/Icon.d.ts +34 -0
  58. package/dist/components/IconButton.d.ts +60 -0
  59. package/dist/components/InfoTip.d.ts +15 -0
  60. package/dist/components/InternalIcon.d.ts +19 -0
  61. package/dist/components/ListItem.d.ts +25 -0
  62. package/dist/components/Modal.d.ts +29 -0
  63. package/dist/components/RepoSyncIndicator.d.ts +29 -0
  64. package/dist/components/ResolvedParams.d.ts +31 -0
  65. package/dist/components/ServerResources.d.ts +47 -0
  66. package/dist/components/StepStatusPill.d.ts +51 -0
  67. package/dist/components/UptimeStrip.d.ts +56 -0
  68. package/dist/components/execution-format.d.ts +24 -0
  69. package/dist/components/expression-dom.d.ts +154 -0
  70. package/dist/components/expression-template.d.ts +86 -0
  71. package/dist/components/history-scale.d.ts +33 -0
  72. package/dist/components/icons.d.ts +41 -0
  73. package/dist/components/resolved-clip.d.ts +42 -0
  74. package/dist/components/server-resources-format.d.ts +68 -0
  75. package/dist/components/server-resources.fixture.d.ts +9 -0
  76. package/dist/components/use-copy.d.ts +14 -0
  77. package/dist/createW6WApi.d.ts +31 -0
  78. package/dist/flow-connect.d.ts +138 -0
  79. package/dist/flow-fanout.d.ts +15 -0
  80. package/dist/flow-types.d.ts +356 -0
  81. package/dist/flow-utils.d.ts +284 -0
  82. package/dist/flow.cjs +3 -0
  83. package/dist/flow.cjs.map +1 -0
  84. package/dist/flow.d.ts +22 -0
  85. package/dist/flow.mjs +1977 -0
  86. package/dist/flow.mjs.map +1 -0
  87. package/dist/index.cjs +2 -0
  88. package/dist/index.cjs.map +1 -0
  89. package/dist/index.d.ts +94 -0
  90. package/dist/index.mjs +1811 -0
  91. package/dist/index.mjs.map +1 -0
  92. package/dist/oauth-popup.d.ts +17 -0
  93. package/dist/output-shape.d.ts +58 -0
  94. package/dist/provider.d.ts +420 -0
  95. package/dist/resolve-params.d.ts +112 -0
  96. package/dist/resolved-json.d.ts +21 -0
  97. package/dist/run-visuals.d.ts +90 -0
  98. package/dist/step-preview-state.d.ts +143 -0
  99. package/dist/theme.d.ts +32 -0
  100. package/dist/trigger-fields.d.ts +56 -0
  101. package/dist/types.d.ts +413 -0
  102. package/dist/ui.css +1 -0
  103. package/dist/use-app-action-defs.d.ts +7 -0
  104. package/dist/use-enter-submit.d.ts +23 -0
  105. package/dist/use-seed-sources.d.ts +16 -0
  106. package/package.json +111 -3
  107. package/src/code.css +542 -0
  108. package/src/styles/_buttons.scss +38 -0
  109. package/src/styles/_chips.scss +210 -0
  110. package/src/styles/_code.scss +139 -0
  111. package/src/styles/_copyable.scss +147 -0
  112. package/src/styles/_data-vars.scss +38 -0
  113. package/src/styles/_execution-history.scss +282 -0
  114. package/src/styles/_execution-log.scss +178 -0
  115. package/src/styles/_expression-field.scss +65 -0
  116. package/src/styles/_expression-inline.scss +63 -0
  117. package/src/styles/_expression-modal.scss +292 -0
  118. package/src/styles/_fields.scss +161 -0
  119. package/src/styles/_flow.scss +217 -0
  120. package/src/styles/_fx.scss +158 -0
  121. package/src/styles/_health.scss +46 -0
  122. package/src/styles/_history-timeline.scss +156 -0
  123. package/src/styles/_icon-button.scss +22 -0
  124. package/src/styles/_icon.scss +15 -0
  125. package/src/styles/_icons.scss +31 -0
  126. package/src/styles/_incoming-state.scss +46 -0
  127. package/src/styles/_info-tip.scss +9 -0
  128. package/src/styles/_layout.scss +6 -0
  129. package/src/styles/_lists.scss +64 -0
  130. package/src/styles/_modal.scss +125 -0
  131. package/src/styles/_multiselect.scss +69 -0
  132. package/src/styles/_repo-sync-indicator.scss +99 -0
  133. package/src/styles/_scale.scss +70 -0
  134. package/src/styles/_sections.scss +36 -0
  135. package/src/styles/_server-resources.scss +163 -0
  136. package/src/styles/_step-builder.scss +376 -0
  137. package/src/styles/_step-config.scss +195 -0
  138. package/src/styles/_tabs.scss +54 -0
  139. package/src/styles/_tester.scss +111 -0
  140. package/src/styles/_tokens.scss +141 -0
  141. package/src/styles/_uptime.scss +61 -0
  142. package/src/styles.css +4208 -0
  143. package/src/styles.scss +61 -0
@@ -0,0 +1,376 @@
1
+ .w6w-step-meta {
2
+ display: flex;
3
+ flex-wrap: wrap;
4
+ align-items: center;
5
+ gap: var(--w6w-sp-1-5);
6
+ /* lint-tokens-allow: relative em, not absolute rem like the scale's --w6w-fs- type tokens — mirrors the accepted _modal.scss:88 .w6w-modal-subtitle precedent; .w6w-step-meta currently has zero .tsx call sites (possible dead CSS, not this task's to delete) */
7
+ font-size: 0.8em;
8
+ color: var(--w6w-muted);
9
+ }
10
+ .w6w-step-meta code {
11
+ color: var(--w6w-text);
12
+ }
13
+
14
+ /* Step builder (sidebar + content) */
15
+ .w6w-stepbuilder {
16
+ display: flex;
17
+ gap: var(--w6w-sp-4);
18
+ min-height: 340px;
19
+ }
20
+ .w6w-stepbuilder-sidebar {
21
+ display: flex;
22
+ flex-direction: column;
23
+ gap: var(--w6w-sp-1);
24
+ width: 140px;
25
+ flex-shrink: 0;
26
+ border-right: 1px solid var(--w6w-border);
27
+ padding-right: var(--w6w-sp-3);
28
+ }
29
+ .w6w-stepbuilder-tab {
30
+ text-align: left;
31
+ background: transparent;
32
+ border: 1px solid transparent;
33
+ border-radius: 8px;
34
+ padding: var(--w6w-sp-2) var(--w6w-sp-2-5);
35
+ color: var(--w6w-muted);
36
+ font-size: var(--w6w-fs-sm);
37
+ cursor: pointer;
38
+ }
39
+ .w6w-stepbuilder-tab:hover {
40
+ background: var(--w6w-panel-2);
41
+ color: var(--w6w-text);
42
+ }
43
+ .w6w-stepbuilder-tab.active {
44
+ background: var(--w6w-panel-2);
45
+ color: var(--w6w-text);
46
+ font-weight: var(--w6w-fw-medium);
47
+ }
48
+ .w6w-stepbuilder-content {
49
+ flex: 1;
50
+ min-width: 0;
51
+ /* Fixed height (not content-driven) so the modal never resizes when toggling
52
+ tabs, and the sidebar divider — which stretches to this row — stays a
53
+ constant length regardless of the right pane's content. */
54
+ height: min(70vh, 520px);
55
+ overflow: auto;
56
+ }
57
+ /* Apps flow: a fixed search header + a separately scrolling list, so the
58
+ scrollbar is contained to the list and never runs alongside the search. */
59
+ .w6w-stepbuilder-apps {
60
+ display: flex;
61
+ flex-direction: column;
62
+ gap: var(--w6w-sp-2-5);
63
+ height: 100%;
64
+ min-height: 0;
65
+ }
66
+ .w6w-stepbuilder-scroll {
67
+ overflow-y: auto;
68
+ /* Fill the remaining height below the search header; the list — not the
69
+ outer modal content — owns the scrollbar. */
70
+ flex: 1;
71
+ min-height: 0;
72
+ padding-right: var(--w6w-sp-1);
73
+ }
74
+ .w6w-stepbuilder-search {
75
+ background: var(--w6w-panel-2);
76
+ border: 1px solid var(--w6w-border);
77
+ border-radius: 8px;
78
+ padding: var(--w6w-sp-2) var(--w6w-sp-2-5);
79
+ color: var(--w6w-text);
80
+ font-size: var(--w6w-fs-sm);
81
+ font-family: inherit;
82
+ width: 100%;
83
+ }
84
+ .w6w-stepbuilder-search:focus {
85
+ outline: none;
86
+ border-color: var(--w6w-accent);
87
+ }
88
+ .w6w-stepbuilder-list {
89
+ display: flex;
90
+ flex-direction: column;
91
+ gap: var(--w6w-sp-1-5);
92
+ }
93
+ .w6w-stepbuilder-item {
94
+ display: flex;
95
+ align-items: center;
96
+ gap: var(--w6w-sp-2-5);
97
+ text-align: left;
98
+ background: var(--w6w-panel-2);
99
+ border: 1px solid var(--w6w-border);
100
+ border-radius: 8px;
101
+ padding: var(--w6w-sp-2-5) var(--w6w-sp-3);
102
+ color: var(--w6w-text);
103
+ cursor: pointer;
104
+ font-size: var(--w6w-fs-sm);
105
+ }
106
+ .w6w-stepbuilder-item:hover {
107
+ border-color: var(--w6w-accent);
108
+ }
109
+ .w6w-stepbuilder-item-main {
110
+ display: flex;
111
+ flex-direction: column;
112
+ gap: var(--w6w-sp-0-5);
113
+ min-width: 0;
114
+ }
115
+
116
+ /* AppPicker's own multi-column card grid (T1.1.1). ADDITIVE on top of the
117
+ shared `.w6w-stepbuilder-list`/`-item` above, which stay byte-identical to
118
+ `main` (NodeList/CallableRow/ReadyToUseFlow still consume them unmodified)
119
+ — this rule wins the cascade purely by being declared later at equal
120
+ (single-class) specificity. `minmax(190px, 1fr)` is re-derived for this
121
+ card's much shorter content (icon + name + id + version, not a full
122
+ description card) from the scale `packages/frontend`'s generic `.grid`
123
+ utility uses (`minmax(260px, 1fr)`) — `grid-template-columns` is box
124
+ geometry, outside `lint:tokens`' scanned property set, so the literal is
125
+ deliberate, not an oversight.
126
+
127
+ `auto-fill`, NOT `auto-fit`: the two differ in exactly one case, and it is
128
+ the case a search box guarantees will happen. `auto-fit` COLLAPSES the
129
+ tracks no card landed in, and the `1fr` then hands their width to the
130
+ survivors — so typing a query that matches one app blew that single card up
131
+ to the full width of the panel, a tile that changes size as you type. With
132
+ `auto-fill` the empty tracks are kept at their `minmax()` width, so a card
133
+ is the same size whether the grid holds 60 of them or 1.
134
+
135
+ `align-content: start` is the vertical half of the same invariant: an auto
136
+ row track under the default `stretch` absorbs the free space of a grid with
137
+ a definite height (this one's, from `.w6w-stepbuilder-scroll`'s `flex: 1`),
138
+ so a single result would also have grown DOWN to fill the panel. */
139
+ .w6w-apppicker-grid {
140
+ display: grid;
141
+ grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
142
+ gap: var(--w6w-sp-2);
143
+ align-content: start;
144
+ }
145
+ /* The quieter resting card (D-3): `--w6w-panel` at rest instead of
146
+ `--w6w-panel-2`, shifting TO `--w6w-panel-2` on hover/focus — the inverse
147
+ of the shared item's flat `--w6w-panel-2` always-on tint. No new token;
148
+ `.w6w-stepbuilder-item:hover`'s `border-color: var(--w6w-accent)` above
149
+ still applies unchanged, so hover keeps both effects together. Slightly
150
+ tighter padding than the shared item, sized for a narrower multi-column
151
+ card rather than a single full-width row.
152
+
153
+ `min-height` pins every tile to one height regardless of what it holds:
154
+ `version` is optional on `AppSummary`, so a catalog that mixes versioned and
155
+ unversioned apps would otherwise render two card heights down the same grid
156
+ (grid items stretch to their ROW, not to the whole grid). The floor is the
157
+ three-line card's own content height rounded up, so it never clips.
158
+
159
+ `align-items: flex-start` overrides the shared item's `center`: against a
160
+ three-line block a centred 24px icon floats beside the id rather than
161
+ reading as the name's own mark. */
162
+ .w6w-apppicker-card {
163
+ background: var(--w6w-panel);
164
+ padding: var(--w6w-sp-2) var(--w6w-sp-2-5);
165
+ align-items: flex-start;
166
+ min-height: 84px;
167
+ }
168
+ .w6w-apppicker-card:hover,
169
+ .w6w-apppicker-card:focus-visible {
170
+ background: var(--w6w-panel-2);
171
+ }
172
+ /* The card's two metadata lines. One `font-size` declaration for both, because
173
+ there is only one deliberate literal here to justify: the type ramp's
174
+ smallest role is `--w6w-fs-xs` (0.75rem), the id and version want to sit a
175
+ step UNDER it, and the ramp has no `2xs` — its 30-name key set is pinned
176
+ name-for-name by `scale-tokens.test.ts` and mirrored by `packages/frontend`'s
177
+ `check:scale-parity`, so adding one is a cross-repo contract change, not a
178
+ card tweak. `code`'s own UA `font-size` also has to be overridden here
179
+ whatever value is chosen. */
180
+ .w6w-apppicker-card-id,
181
+ .w6w-apppicker-card-version {
182
+ /* lint-tokens-allow: one step under --w6w-fs-xs; the ramp has no 2xs role and its keys are pinned */
183
+ font-size: 0.6875rem;
184
+ color: var(--w6w-muted);
185
+ font-family: var(--w6w-font-mono);
186
+ }
187
+ /* Truncation, not wrapping: `min-width: 0` on the parent
188
+ `.w6w-stepbuilder-item-main` is what lets this shrink below its own
189
+ min-content width in the first place — without it the ellipsis never
190
+ engages and a long id widens the flex line instead. */
191
+ .w6w-apppicker-card-id {
192
+ display: block;
193
+ max-width: 100%;
194
+ overflow: hidden;
195
+ text-overflow: ellipsis;
196
+ white-space: nowrap;
197
+ opacity: 0.6;
198
+ }
199
+ /* Quieter than the name, but a step louder than the id it sits under — it is
200
+ the shorter, more scannable of the two. */
201
+ .w6w-apppicker-card-version {
202
+ opacity: 0.75;
203
+ }
204
+
205
+ /* The opt-in category-filter chip row (D-1a; AddConnectionModal only —
206
+ `AppPickerProps.categoryFilter`). Extends `.w6w-chip`'s look
207
+ (`_multiselect.scss:40-53`) for the general shape rather than importing
208
+ it — that partial belongs to `ParamsForm`'s array-editor chips, a
209
+ different feature with the opposite interaction (only SELECTED values are
210
+ chips there; every available category is always a chip here). */
211
+ .w6w-apppicker-cats {
212
+ display: flex;
213
+ flex-wrap: wrap;
214
+ align-items: center;
215
+ gap: var(--w6w-sp-1-5);
216
+ }
217
+ .w6w-apppicker-chip {
218
+ display: inline-flex;
219
+ align-items: center;
220
+ gap: var(--w6w-sp-0-5);
221
+ background: var(--w6w-panel);
222
+ border: 1px solid var(--w6w-border);
223
+ border-radius: 999px;
224
+ padding: var(--w6w-sp-0-5) var(--w6w-sp-2);
225
+ color: var(--w6w-muted);
226
+ font-size: var(--w6w-fs-xs);
227
+ cursor: pointer;
228
+ }
229
+ .w6w-apppicker-chip:hover {
230
+ border-color: var(--w6w-accent);
231
+ color: var(--w6w-text);
232
+ }
233
+ /* The pressed/selected state is driven by the same `aria-pressed` the
234
+ button already carries for assistive tech (P10) — no separate class to
235
+ keep in sync with it. */
236
+ .w6w-apppicker-chip[aria-pressed="true"] {
237
+ background: var(--w6w-accent);
238
+ border-color: var(--w6w-accent);
239
+ color: #fff;
240
+
241
+ /* The count's `.w6w-muted` sets its OWN color, so it doesn't inherit this
242
+ `color: #fff` — left alone it stays `var(--w6w-muted)`, a gray tuned for
243
+ the unpressed `--w6w-panel` background, which is nearly invisible against
244
+ the accent fill. Not full white: the count is still secondary to the
245
+ label. */
246
+ .w6w-muted {
247
+ color: rgba(255, 255, 255, 0.75);
248
+ }
249
+ }
250
+
251
+ /* AppPicker's own layout owner, nested inside `.w6w-stepbuilder-content` (never
252
+ applied in its place — see the call sites). A flex item's automatic minimum
253
+ size is its min-content size unless `overflow` is non-`visible` or
254
+ `min-height:0` is set; `.w6w-stepbuilder-content` has neither, so its
255
+ min-content (every app row, unclipped) pushes `dialog.w6w-modal` up against
256
+ `max-height:90vh`. This host's explicit `height` + `overflow:hidden` zeroes
257
+ that contribution, so the dialog falls back to `.w6w-modal-xl`'s
258
+ `min-height: min(70vh, 620px)` — the step builder's own height. */
259
+ .w6w-apppicker-host {
260
+ flex: 0 0 auto;
261
+ min-width: 0;
262
+ height: min(70vh, 520px);
263
+ display: flex;
264
+ flex-direction: column;
265
+ overflow: hidden;
266
+ }
267
+ .w6w-apppicker-host > .w6w-stepbuilder-apps {
268
+ height: auto;
269
+ flex: 1 1 auto;
270
+ min-height: 0;
271
+ }
272
+
273
+ /* The picker's home tab — the intake's two-column layout:
274
+
275
+ Connnected apps | functions
276
+ | workflows
277
+
278
+ Connected apps down the left; Functions above Workflows down the right.
279
+ Nested inside `.w6w-apppicker-host`, which owns the height, so each column's
280
+ own list is what scrolls — never the modal. `min-height: 0` on the grid and
281
+ on every column is load-bearing: a grid/flex item's automatic minimum size
282
+ is its min-content size, so without it a long list pushes the dialog past
283
+ `.w6w-apppicker-host`'s fixed height instead of scrolling inside it. */
284
+ .w6w-readytouse {
285
+ display: grid;
286
+ grid-template-columns: 1fr 1fr;
287
+ gap: var(--w6w-sp-4);
288
+ flex: 1 1 auto;
289
+ min-height: 0;
290
+ }
291
+
292
+ /* A half with nothing in it is not rendered at all (an empty "Workflows"
293
+ heading would claim you have workflows ready to use), so the grid collapses
294
+ to the one column that survived — and the divider below, which only makes
295
+ sense between two halves, goes with it. */
296
+ .w6w-readytouse[data-cols="1"] {
297
+ grid-template-columns: 1fr;
298
+ }
299
+
300
+ /* The `|` in the intake's sketch. On the right half's leading edge rather than
301
+ as a third grid track, so it spans the full column height however tall the
302
+ two halves end up, and disappears with the half itself. */
303
+ .w6w-readytouse[data-cols="2"] > .w6w-readytouse-stack {
304
+ border-left: 1px solid var(--w6w-border);
305
+ padding-left: var(--w6w-sp-4);
306
+ }
307
+
308
+ /* The right half stacks its two sections; they share the height evenly. */
309
+ .w6w-readytouse-stack {
310
+ display: grid;
311
+ grid-template-rows: 1fr 1fr;
312
+ gap: var(--w6w-sp-3);
313
+ min-height: 0;
314
+ }
315
+
316
+ /* A single column: heading pinned, list scrolling under it. */
317
+ .w6w-readytouse-col {
318
+ display: flex;
319
+ flex-direction: column;
320
+ gap: var(--w6w-sp-2);
321
+ min-height: 0;
322
+ }
323
+
324
+ /* One section only in the stack — a picker offering a single callable family,
325
+ or a workspace with Functions but no Workflows. It takes the whole right
326
+ half rather than leaving a gap under it. */
327
+ .w6w-readytouse-stack > .w6w-readytouse-col:only-child {
328
+ grid-row: 1 / -1;
329
+ }
330
+
331
+ .w6w-readytouse-heading {
332
+ margin: 0;
333
+ font-size: var(--w6w-fs-sm);
334
+ font-weight: var(--w6w-fw-semibold);
335
+ color: var(--w6w-muted-text, var(--w6w-text));
336
+ }
337
+
338
+ /* A Function/Workflow row, distinct from an app row at a glance: an app is
339
+ somebody else's service, a Function/Workflow is something YOU built here.
340
+ Applied by `CallableRow`, which both the home tab and the Workflows/
341
+ Functions tabs render — so the tint and the glyph travel together and a
342
+ Function looks the same wherever it is offered. */
343
+ .w6w-stepbuilder-item--callable {
344
+ background: var(--w6w-panel);
345
+ border-style: dashed;
346
+ }
347
+
348
+ /* Step config (app action / control node): a fixed header (connection + action)
349
+ that never scrolls, a scrolling parameters body, and a pinned footer — mirrors
350
+ the fixed-header/scroll-body split used by `.w6w-stepbuilder-apps`. */
351
+ .w6w-stepconfig {
352
+ display: flex;
353
+ flex-direction: column;
354
+ flex: 1;
355
+ height: 100%;
356
+ min-height: 0;
357
+ gap: var(--w6w-sp-3);
358
+ /* Horizontal breathing room so header/footer align with the padded body. */
359
+ padding-inline: var(--w6w-sp-1);
360
+ }
361
+ /* Inline step rename (pencil) shown next to the modal title. */
362
+ .w6w-step-rename {
363
+ display: inline-flex;
364
+ align-items: center;
365
+ gap: var(--w6w-sp-1);
366
+ }
367
+ .w6w-step-rename input {
368
+ background: var(--w6w-panel-2);
369
+ border: 1px solid var(--w6w-accent);
370
+ border-radius: 6px;
371
+ padding: var(--w6w-sp-0-5) var(--w6w-sp-1-5);
372
+ color: var(--w6w-text);
373
+ /* lint-tokens-allow: relative em, not absolute rem like the scale's --w6w-fs- type tokens — mirrors the accepted _modal.scss:88 .w6w-modal-subtitle precedent */
374
+ font-size: 0.9em;
375
+ font-family: inherit;
376
+ }
@@ -0,0 +1,195 @@
1
+ .w6w-stepconfig-header {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--w6w-sp-2-5);
5
+ flex-shrink: 0;
6
+ }
7
+ /* Connection + action share a row and wrap on narrow widths. */
8
+ .w6w-stepconfig-row {
9
+ display: flex;
10
+ flex-wrap: wrap;
11
+ gap: var(--w6w-sp-3);
12
+ align-items: flex-start;
13
+ }
14
+ .w6w-stepconfig-conn,
15
+ .w6w-stepconfig-action {
16
+ flex: 1 1 240px;
17
+ min-width: 0;
18
+ }
19
+ .w6w-stepconfig-conn-empty {
20
+ flex: 1 1 100%;
21
+ }
22
+ /* Selected connection rendered as a static label (not a dropdown). */
23
+ .w6w-conn-label {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: var(--w6w-sp-2);
27
+ background: var(--w6w-panel-2);
28
+ border: 1px solid var(--w6w-border);
29
+ border-radius: 8px;
30
+ padding: var(--w6w-sp-1-5) var(--w6w-sp-2) var(--w6w-sp-1-5) var(--w6w-sp-2-5);
31
+ min-height: 36px;
32
+ }
33
+ .w6w-conn-label-name {
34
+ flex: 1;
35
+ min-width: 0;
36
+ color: var(--w6w-text);
37
+ font-size: var(--w6w-fs-sm);
38
+ overflow: hidden;
39
+ text-overflow: ellipsis;
40
+ white-space: nowrap;
41
+ }
42
+ /* A pseudo-field wrapper (border/background, like every other field in this
43
+ form) CONTAINING two real buttons, spaced apart — `[App] <--> [Connection]`
44
+ (2026-08-30, fifth pass: "still missing border around SendGrid + prod...
45
+ look like before, where both were inside a pseudo field, only change was
46
+ to make the buttons look like buttons"). The outer border is back; each
47
+ button ALSO keeps its own border/background (one shade lighter,
48
+ `--w6w-panel` against the field's `--w6w-panel-2`) so it still reads as a
49
+ clickable button, not merely text, without the two touching directly —
50
+ the field's own padding is the gap between its edge and each button. */
51
+ .w6w-app-conn-row {
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: space-between;
55
+ gap: var(--w6w-sp-2);
56
+ background: var(--w6w-panel-2);
57
+ border: 1px solid var(--w6w-border);
58
+ border-radius: 8px;
59
+ min-height: 36px;
60
+ padding: var(--w6w-sp-1);
61
+ }
62
+ .w6w-app-conn-btn {
63
+ flex: 0 1 auto;
64
+ min-width: 0;
65
+ display: flex;
66
+ align-items: center;
67
+ gap: var(--w6w-sp-2);
68
+ background: var(--w6w-panel);
69
+ border: 1px solid var(--w6w-border);
70
+ border-radius: 6px;
71
+ padding: var(--w6w-sp-1) var(--w6w-sp-2-5);
72
+ cursor: pointer;
73
+ text-align: left;
74
+ font: inherit;
75
+ color: var(--w6w-text);
76
+ }
77
+ .w6w-app-conn-btn:disabled {
78
+ cursor: default;
79
+ opacity: 0.6;
80
+ }
81
+ .w6w-app-conn-btn:hover:not(:disabled),
82
+ .w6w-app-conn-btn[aria-expanded="true"] {
83
+ border-color: var(--w6w-accent);
84
+ }
85
+
86
+ /* A flyout popover (App/Connection pickers) — portaled to the enclosing
87
+ `<dialog>` so it floats OVER the modal's own scrollable body instead of
88
+ being clipped/squeezed inside it (`Flyout` component doc has the why).
89
+ Plain positioned div, not a nested native dialog. No max-height/overflow
90
+ of its own: `AppPicker` already caps and scrolls itself
91
+ (`.w6w-apppicker-host`, `min(70vh, 520px)`), and the plain connection
92
+ list is short enough in practice to size to content — a SECOND scroll
93
+ container nested inside this one would double-scroll `AppPicker`. */
94
+ .w6w-flyout {
95
+ position: fixed;
96
+ z-index: 40;
97
+ /* No `box-sizing: border-box` reset elsewhere in this package (checked) —
98
+ the inline `width` set by `Flyout` is meant to match the anchor row
99
+ EXACTLY (2026-08-30: "should extend to the end of the prod button and
100
+ div"), so padding/border must come out of that width, not add to it. */
101
+ box-sizing: border-box;
102
+ background: var(--w6w-panel);
103
+ border: 1px solid var(--w6w-border);
104
+ border-radius: 8px;
105
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
106
+ padding: var(--w6w-sp-2);
107
+ }
108
+ .w6w-btn-sm {
109
+ padding: var(--w6w-sp-1) var(--w6w-sp-2);
110
+ font-size: var(--w6w-fs-xs);
111
+ flex-shrink: 0;
112
+ }
113
+ /* Only the parameters form scrolls; x-padding keeps fields off the edge + scrollbar. */
114
+ .w6w-stepconfig-body {
115
+ flex: 1;
116
+ min-height: 0;
117
+ overflow-y: auto;
118
+ padding-inline: var(--w6w-sp-1);
119
+ padding-right: var(--w6w-sp-2);
120
+ }
121
+ /* Footer pinned to the modal bottom, outside the scroll area. */
122
+ .w6w-stepconfig-footer {
123
+ flex-shrink: 0;
124
+ border-top: 1px solid var(--w6w-border);
125
+ padding-top: var(--w6w-sp-3);
126
+ margin-top: 0;
127
+ }
128
+ /* Test-required note — always rendered (empty when there is nothing to say),
129
+ so its reserved height keeps the footer's buttons at the same x/y whether
130
+ the note has text or not; one line, ellipsized rather than wrapped. */
131
+ .w6w-stepconfig-testnote {
132
+ flex-shrink: 0;
133
+ min-height: 1.4em;
134
+ white-space: nowrap;
135
+ overflow: hidden;
136
+ text-overflow: ellipsis;
137
+ }
138
+
139
+ /* The whole-config "code"/JSON view is a DIRECT child of the body — stretch it
140
+ to fill the modal height instead of leaving the dialog half-empty (it passes
141
+ height="100%"). Inline json/code PARAM fields live inside a `.w6w-field` and
142
+ size to their content, capped by the editor's own maxHeight (grow, then
143
+ scroll inside), so they are intentionally NOT stretched here — that was the
144
+ cause of the empty space + overlap under short group/json fields. */
145
+ .w6w-stepconfig-body:has(> .w6w-code-editor, > .w6w-json-editor) {
146
+ display: flex;
147
+ flex-direction: column;
148
+ gap: var(--w6w-sp-2-5);
149
+ }
150
+ .w6w-stepconfig-body > .w6w-code-editor,
151
+ .w6w-stepconfig-body > .w6w-json-editor {
152
+ flex: 1 1 auto;
153
+ min-height: 0;
154
+ }
155
+ /* The `copyable` prop's button overlays `.w6w-json-editor`'s own top-right
156
+ corner — mirrors `_copyable.scss:86-100`'s CodeBlock geometry, but there is
157
+ no `<pre>` here for a `:has()` selector to reach, so it is scoped directly
158
+ to the class instead. Anchored to `.w6w-json-editor` itself (not the
159
+ CodeMirror scroller), so it stays pinned to the visible corner rather than
160
+ scrolling with the content. */
161
+ .w6w-json-editor {
162
+ position: relative;
163
+ }
164
+ .w6w-json-editor > .w6w-copyable-btn {
165
+ position: absolute;
166
+ top: var(--w6w-sp-1);
167
+ right: var(--w6w-sp-1);
168
+ /* Opaque backdrop: this button sits ON the JSON's first line, and
169
+ `.w6w-icon-btn`'s transparent idle state would let the text read through
170
+ it (mirrors `_copyable.scss:93-99`'s rationale exactly). */
171
+ background: var(--w6w-panel);
172
+ border-color: var(--w6w-border);
173
+ }
174
+ .w6w-stepconfig-body .w6w-field > textarea {
175
+ resize: vertical;
176
+ }
177
+ /* Field label row with a trailing action (e.g. the JSON "open full view" btn). */
178
+ .w6w-field-labelrow {
179
+ display: flex;
180
+ align-items: center;
181
+ justify-content: space-between;
182
+ gap: var(--w6w-sp-2);
183
+ }
184
+ /* Full-view JSON modal body — fill the dialog so the editor is roomy. */
185
+ .w6w-json-fullview {
186
+ display: flex;
187
+ flex-direction: column;
188
+ min-height: 0;
189
+ flex: 1 1 auto;
190
+ height: 60vh;
191
+ }
192
+ .w6w-json-fullview > .w6w-json-editor {
193
+ flex: 1 1 auto;
194
+ min-height: 0;
195
+ }
@@ -0,0 +1,54 @@
1
+ .w6w-subtab {
2
+ background: transparent;
3
+ border: none;
4
+ border-radius: 6px;
5
+ padding: 5px var(--w6w-sp-3);
6
+ color: var(--w6w-muted);
7
+ font-size: 13px;
8
+ cursor: pointer;
9
+ }
10
+ .w6w-subtab:hover {
11
+ color: var(--w6w-text);
12
+ }
13
+ .w6w-subtab.active {
14
+ background: var(--w6w-panel);
15
+ color: var(--w6w-text);
16
+ font-weight: var(--w6w-fw-medium);
17
+ }
18
+ .w6w-subtab:disabled {
19
+ opacity: 0.4;
20
+ cursor: default;
21
+ }
22
+ .w6w-subtab:disabled:hover {
23
+ color: var(--w6w-muted);
24
+ }
25
+
26
+ /* Full-width tabs bar: segmented tabs on the left, view icons on the right. */
27
+ .w6w-tabsbar {
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: space-between;
31
+ gap: var(--w6w-sp-3);
32
+ border-bottom: 1px solid var(--w6w-border);
33
+ padding-bottom: var(--w6w-sp-2);
34
+ flex-shrink: 0;
35
+ }
36
+ .w6w-icon-btn:disabled {
37
+ opacity: 0.35;
38
+ cursor: default;
39
+ }
40
+ .w6w-icon-btn:disabled:hover {
41
+ background: transparent;
42
+ color: var(--w6w-muted);
43
+ }
44
+
45
+ /* Config modal body (a picked app/node) fills the dialog so the footer pins to
46
+ the modal's bottom rather than a fixed-height content area. */
47
+ .w6w-stepbuilder-config {
48
+ flex: 1;
49
+ min-height: 0;
50
+ display: flex;
51
+ flex-direction: column;
52
+ }
53
+
54
+ /* Compact one-line step identity (id · app · action) in the edit modal. */