@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
package/CHANGELOG.md ADDED
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@w6w/ui` are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Releases are
6
+ tagged `vX.Y.Z` and published to npm by `.github/workflows/release.yml`; changes not yet released
7
+ accumulate under `[Unreleased]`. Entries below `[0.1.0]` predate the first npm release — see the
8
+ repo's git history for exact dates and commits.
9
+
10
+ ## [Unreleased]
11
+
12
+ ## [0.1.0]
13
+
14
+ First npm release (`npm install @w6w/ui`).
15
+
16
+ - `@w6w/expr` is now a regular npm dependency (`^0.1.0`) instead of the
17
+ `github:w6w-io/w6w-core#path:packages/expr` git spec, and is external to the build: the dist
18
+ chunks `import`/`require` it rather than bundling it.
19
+ - Fixed the published manifest: the packed tarball's `main`/`module`/`types` and `exports` point at
20
+ `./dist/*` (packed with `pnpm pack`, which applies `publishConfig`), and the tarball ships only
21
+ `dist/`, the stylesheet exports, `LICENSE`, `README.md` and `CHANGELOG.md` — no tests, stories,
22
+ test loader or `.d.ts` for tests. `scripts/assert-packed-manifest.mjs` and
23
+ `test/pack-smoke/run.sh` (a clean-consumer `tsc` + `vite build`) gate it.
24
+ - Inside this repo `@w6w/expr` resolves to the sibling core checkout's source through the
25
+ `w6w-source` export condition (tsconfig `customConditions`, Vite/Storybook `resolve.conditions`,
26
+ `node --conditions`, the `test/` rigs' esbuild), so no expr `dist/` has to be built first.
27
+
28
+ ### Earlier unreleased changes, shipped in 0.1.0
29
+
30
+ - The expression editor's rail toggle for a source's child fields (a step's output fields, a
31
+ document's keys) now reads "N fields ›" instead of a bare 20px chevron, which went unnoticed
32
+ beside the source chip. On a step with fields, the `▸` arrow moved out of the chip into its own
33
+ caret that expands the fields; it used to insert the whole output instead.
34
+ - The expression editor's **Workflow state** rail now offers an upstream app step's output
35
+ fields without a test run: the action's declared `output` (dot keys become nested paths such as
36
+ `steps.<id>.output.start.utc`), else its `sample`, else the step's last test output. A step with
37
+ none of these shows "Run a test of this step to see its fields".
38
+ - Rewrote the user guide in `docs/` for docs.w6w.io (section `ui`): an overview, theming, the
39
+ design system, and a components reference with one page per group. Corrected `README.md`: MIT
40
+ license, provider-based usage, all 42 components, current stylesheet sizes and bundler notes.
41
+ Moved the token-gate rules for contributors into `CONTRIBUTING.md`.
42
+ - Added a branded `.storybook/manager.ts` theme.
43
+ - Added `*.stories.tsx` coverage for every exported component, and a `pnpm coverage:stories` check
44
+ that keeps it that way.
45
+ - Rewrote `README.md` for an outside reader: install/consume without npm, a full component list,
46
+ palette ancestry, and credits.
47
+ - Added `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, issue templates, and a PR template.
48
+ - Completed `package.json` metadata (`homepage`, `author`, `keywords`, `description`).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 w6w-io
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,261 @@
1
- # Temporary Holding Version
1
+ <p align="center">
2
+ <a href="https://w6w.io">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset=".github/assets/w6w-lockup-ondark.svg">
5
+ <source media="(prefers-color-scheme: light)" srcset=".github/assets/w6w-lockup.svg">
6
+ <img src=".github/assets/w6w-lockup.svg" alt="W6W" width="320">
7
+ </picture>
8
+ </a>
9
+ </p>
2
10
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
11
+ # @w6w/ui
12
+
13
+ React components for [W6W](https://w6w.io) — central API management: one front door, composition,
14
+ visibility and plug & play for every API a product runs on. These are the components W6W's own
15
+ studio is built from, packaged for any app that talks to a W6W server: the connect-an-app modal,
16
+ the app picker, the step builder, the visual workflow canvas, execution history, health and status
17
+ indicators, and the smaller pieces around them.
18
+
19
+ ## Documentation
20
+
21
+ The user guide lives in [`docs/`](docs/) and is published at
22
+ [docs.w6w.io](https://docs.w6w.io) under **UI**:
23
+
24
+ - [Overview](docs/overview.md): install, stylesheet, provider, first component, bundler notes.
25
+ - [Theming](docs/theming.md): light/dark mode and every color token.
26
+ - [Design system](docs/design-system.md): the spacing, type and font tokens.
27
+ - [Components](docs/components/index.md): every component, by group, with props and examples.
28
+
29
+ This README covers the repository itself: what's in it and how it's built.
30
+
31
+ ## Install / consume
32
+
33
+ ```sh
34
+ npm install @w6w/ui react react-dom
35
+ ```
36
+
37
+ `@w6w/expr` is a regular npm dependency and installs with it. `react` and `react-dom` (18 or later)
38
+ are peer dependencies. The npm tarball ships compiled `dist/` (ESM + CJS + `.d.ts`), plus the
39
+ stylesheets; the CommonJS build needs Node 20.19+ / 22.12+ to `require()` the ESM-only `@w6w/expr`.
40
+
41
+ Two source routes remain, for working against an unreleased commit or a sibling checkout:
42
+
43
+ - **Git dependency**: `"@w6w/ui": "github:w6w-io/w6w-ui#<commit-sha>"` — the repo is public.
44
+ - **Sibling checkout with `link:`**: `"@w6w/ui": "link:../w6w-ui"` — the pattern this monorepo
45
+ uses (`studio` links `ui` this way).
46
+
47
+ In this repo `main`/`module`/`types` and `exports` point at raw `.tsx` source under `./src`
48
+ (`publishConfig` switches them to `dist/` in the packed npm tarball, which `pnpm pack` applies), so
49
+ on those two routes your bundler compiles the package like your own code. Inside this repo
50
+ `@w6w/expr` resolves to the sibling `packages/core` checkout through the `w6w-source` export
51
+ condition (set in `tsconfig.json`, `vite.config.ts`, `.storybook/vite.config.ts`, the `test` script
52
+ and the `test/` rigs). Vite needs nothing extra; a few setups do — see the
53
+ [bundler notes](docs/overview.md#bundler-notes):
54
+
55
+ - **Vite with a `link:` checkout**: studio sets `optimizeDeps.exclude: ["@w6w/ui"]` so edits are
56
+ picked up live.
57
+ - **SSR builds**: the package must be bundled, not externalized — the frontend site's Astro build
58
+ sets `ssr.noExternal` for `@w6w/ui` and `prism-react-renderer` (a React-rendering dependency of a
59
+ source package needs its own entry). Next.js needs the equivalent, `transpilePackages`.
60
+ - **A linked checkout**: dedupe React (`resolve.dedupe: ["react", "react-dom"]`), or two copies
61
+ break hooks.
62
+
63
+ ## Usage
64
+
65
+ Five components call your W6W server themselves — `AppPicker`, `AddConnectionModal`,
66
+ `ActionTestForm`, `StepBuilderModal` and `WorkflowFlowEditor`. They read one API client from
67
+ `W6WUIProvider`. Every other component is props in, callbacks out.
68
+
69
+ ```tsx
70
+ import { AddConnectionModal, W6WUIProvider, createW6WApi } from "@w6w/ui";
71
+ import "@w6w/ui/styles.css";
72
+
73
+ const api = createW6WApi({ baseUrl: "https://<your-host>", token: () => getToken() });
74
+
75
+ <W6WUIProvider api={api} theme="light">
76
+ {open && (
77
+ <AddConnectionModal
78
+ onClose={() => setOpen(false)}
79
+ onCreated={({ connectionId }) => {
80
+ setOpen(false);
81
+ refetch(connectionId);
82
+ }}
83
+ />
84
+ )}
85
+ </W6WUIProvider>
86
+ ```
87
+
88
+ `createW6WApi` implements every required `W6WApi` member plus `listApps` and `listTestRuns`. It does
89
+ not implement the optional paged-catalog or app-trigger members, and its `invokeAction` does not
90
+ forward `overrides` yet. `@w6w/react`'s `createW6WUiAdapter` is the other way to build the client.
91
+ See [Providers and the API client](docs/components/providers.md).
92
+
93
+ `Copyable` is the one props-only component with a side effect: it writes to `navigator.clipboard`.
94
+
95
+ ```tsx
96
+ import { CodeBlock, Copyable } from "@w6w/ui";
97
+
98
+ <Copyable value={apiKey} readOnly>
99
+ <input readOnly value={apiKey} />
100
+ </Copyable>
101
+
102
+ <CodeBlock code={curlSnippet} language="bash" />
103
+ ```
104
+
105
+ ### Entrypoints
106
+
107
+ Three, so you only resolve what you use. This matters more than bundle size: the root index
108
+ imports `@w6w/expr` and CodeMirror, and a bundler resolves before it tree-shakes, so a consumer
109
+ without those in its tree fails to *build*, not merely to slim down.
110
+
111
+ | Import | Contains | Stylesheet |
112
+ |--------|----------|------------|
113
+ | `@w6w/ui` | everything except the flow editor | `@w6w/ui/styles.css` (~121 KB) |
114
+ | `@w6w/ui/flow` | `WorkflowFlowEditor` and its helpers — pulls in `@xyflow/react` | `@w6w/ui/styles.css` |
115
+ | `@w6w/ui/code` | `CodeBlock` + `Copyable` — needs only React and `prism-react-renderer` | `@w6w/ui/code.css` (~19 KB) |
116
+
117
+ `code.css` is a strict subset of `styles.css`, so importing both is harmless — the rules are
118
+ byte-identical. Reach for `@w6w/ui/code` when you want the highlighter in something that is not a
119
+ full W6W console; the marketing site (`packages/frontend`) renders its homepage snippets that way,
120
+ at build time, shipping no React at all.
121
+
122
+ `WorkflowFlowEditor` imports React Flow's stylesheet (`@xyflow/react/dist/style.css`) itself.
123
+
124
+ ```tsx
125
+ import { CodeBlock } from "@w6w/ui/code";
126
+ import "@w6w/ui/code.css";
127
+ ```
128
+
129
+ ## Theming
130
+
131
+ `styles.css` defines every color as a `--w6w-*` custom property, in a light and a dark variant:
132
+ surfaces and text (`--w6w-bg`, `--w6w-panel`, `--w6w-panel-2`, `--w6w-border`, `--w6w-text`,
133
+ `--w6w-muted`), roles (`--w6w-accent`, `--w6w-danger`, `--w6w-success`), health
134
+ (`--w6w-health-*`), code (`--w6w-code-*`), plus `--w6w-radius` and `--w6w-icon-swatch`. Defaults are
135
+ declared with zero specificity (`:where(...)`), so a plain `:root` rule overrides them.
136
+
137
+ ```css
138
+ :root {
139
+ --w6w-accent: #6b46c1;
140
+ }
141
+ ```
142
+
143
+ The mode resolves in this order: a component's own `theme` prop, then `<W6WUIProvider theme>`,
144
+ then a `data-theme` attribute on `<html>` (or any ancestor, for the CSS), then the OS
145
+ `prefers-color-scheme`. An embedder whose app has its own theme should pass it to the provider, or
146
+ the components may render in a different mode than the page around them. Full tables and the
147
+ troubleshooting list: [`docs/theming.md`](docs/theming.md).
148
+
149
+ The same namespace carries the spacing and type scale (`--w6w-sp-*`, `--w6w-fs-*`, `--w6w-fw-*`,
150
+ `--w6w-lh-*`, `--w6w-font-*`): [`docs/design-system.md`](docs/design-system.md). The `lint:tokens`
151
+ gate that keeps new code on that scale is described in [CONTRIBUTING.md](CONTRIBUTING.md).
152
+
153
+ ### Where the styles come from
154
+
155
+ The stylesheet is authored in **Sass**: `src/styles.scss` is the entry point and `src/styles/*.scss`
156
+ holds one partial per component family. `src/styles.css` is compiled from those (`pnpm build:css`)
157
+ and committed, so `import "@w6w/ui/styles.css"` above needs no Sass toolchain on your side — that
158
+ stays the supported way in.
159
+
160
+ If you *do* build with Sass, you can import the source instead and get the partials as
161
+ `@use`-able modules:
162
+
163
+ ```scss
164
+ @use "@w6w/ui/styles.scss"; // the whole stylesheet
165
+ @use "@w6w/ui/styles/health"; // or one family — see src/styles/ for the list
166
+ ```
167
+
168
+ Editing `src/styles.css` by hand has no effect — it is regenerated, and `pnpm check:css` fails when
169
+ it has drifted from the Sass sources. Two things stay fixed on purpose: `--w6w-*` remain **CSS**
170
+ custom properties (Sass variables would compile away before you could override them at runtime), and
171
+ `.w6w-*` class names are part of the public surface, which is why this ships as one global
172
+ stylesheet rather than CSS Modules.
173
+
174
+ ### Palette ancestry
175
+
176
+ `@w6w/ui` compiles its own `--w6w-*` tokens from `src/styles.scss` above — branding is not a build
177
+ dependency, so nothing here fetches or imports from another repo at build time. The values
178
+ themselves descend from [`w6w-io/w6w-branding`](https://github.com/w6w-io/w6w-branding), the source
179
+ palette (`tokens/tokens.json`, `BRAND.md`); a branding update is ported into `src/styles/` by hand,
180
+ not pulled in automatically.
181
+
182
+ ## Components
183
+
184
+ 42 exported components (the count `pnpm coverage:stories` checks), grouped as in the docs:
185
+
186
+ - **Providers**: `W6WUIProvider`, `ExpressionOptionsProvider` (plus `createW6WApi`, `useW6WApi`,
187
+ `useExpressionOptions`, `startOAuthPopup`, `useEnterSubmit`).
188
+ - **Buttons and icons**: `IconButton`, `Icon`, `EditButton`, `DeleteButton`.
189
+ - **Data display**: `AppIcon`, `ListItem`, `Copyable`, `CopyableText`.
190
+ - **Forms**: `AppPicker`, `ActionTestForm`, `ParamsForm`, `PropertyEntryForm`, `AuthFieldsForm`,
191
+ `ExpressionInput`, `NodeConfigForm`, `RetryPolicyFields`.
192
+ - **Editors**: `CodeBlock`, `CodeEditor`, `JsonEditor`, `YamlEditor`.
193
+ - **Workflow canvas**: `WorkflowFlowEditor` (from `@w6w/ui/flow`).
194
+ - **Modals**: `Modal`, `ConfirmModal`, `AddConnectionModal`, `StepBuilderModal`.
195
+ - **Status and health**: `HealthStatusPill`, `StepStatusPill`, `UptimeStrip`, `HistoryTimeline`,
196
+ `RepoSyncIndicator`.
197
+ - **Executions**: `ExecutionList`, `ExecutionFilters`, `ExecutionStats`, `ExecutionDetail`,
198
+ `ExecutionLogPanel`, `ApiCallsPanel`.
199
+ - **Server resources**: `ServerResourcesCard`, `ServerResourcesCardSmall`, `ServerResourcesRail`,
200
+ `ServerResourcesBadge`.
201
+
202
+ Everything is exported from `@w6w/ui` except `WorkflowFlowEditor`, which is only in `@w6w/ui/flow`
203
+ (alongside a re-export of `ExpressionOptionsProvider`). `@w6w/ui/code` re-exports `CodeBlock` and
204
+ `Copyable`.
205
+
206
+ ## Storybook
207
+
208
+ ```sh
209
+ pnpm storybook # dev server on :6006
210
+ pnpm build-storybook # static build in storybook-static/ (gitignored)
211
+ pnpm coverage:stories # fail if an exported component has no story
212
+ ```
213
+
214
+ Stories live **beside their component** (`src/CodeBlock.stories.tsx`), never in a separate
215
+ `stories/` tree, so one cannot drift from the other; `.storybook/main.ts` globs
216
+ `../src/**/*.stories.tsx` and nothing else. There are deliberately no scaffolded Button/Header/Page
217
+ examples — every entry in the sidebar is a real component of this library.
218
+
219
+ The sidebar is grouped by category: each story's `title` is `<Category>/<Component>`
220
+ (`"Forms/ParamsForm"`), and the category is one of the list in `.storybook/preview.tsx`'s
221
+ `storySort.order` — Buttons, Forms, Editors, Modals, Data Display, Status & Health, Executions,
222
+ Server Resources, Providers. A new category is added to that list too, so the sidebar order stays
223
+ deliberate.
224
+
225
+ Every component exported from the root entrypoint and from both subpaths (`@w6w/ui/flow`,
226
+ `@w6w/ui/code`) has a co-located story. `pnpm coverage:stories` enforces this: it reads every
227
+ component out of `package.json`'s `exports` map and fails, listing each one by name, if any has no
228
+ matching `*.stories.tsx` — so a newly exported component that ships without a story fails the check,
229
+ not just an existing one that loses its story.
230
+
231
+ The toolbar's **Theme** switch sets `data-theme` on the canvas, which is the same signal the
232
+ components and `styles.scss` read, so a story is exercising the real theming contract. The preview
233
+ imports `src/styles.scss` (the authored source) rather than the compiled CSS, so editing a partial
234
+ under `src/styles/` hot-reloads.
235
+
236
+ Stories are excluded from the published tarball (`files`) and from the `.d.ts` emit.
237
+
238
+ ## Develop / contribute
239
+
240
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, the full command list, and the rule that a
241
+ new exported component ships with its story.
242
+
243
+ ## Credits
244
+
245
+ Maintained by **W6W** — `w6w, Inc, a Delaware corporation`.
246
+ [w6w.io](https://w6w.io) · [docs.w6w.io](https://docs.w6w.io)
247
+
248
+ The `Icon` set (`src/components/icons.tsx`) is copied from the studio's inline SVGs, most of them
249
+ in the [Feather](https://feathericons.com) idiom (MIT, © Cole Bemis); each entry names its source.
250
+
251
+ Built with [`@xyflow/react`](https://reactflow.dev), CodeMirror (via
252
+ [`@uiw/react-codemirror`](https://uiw-react-codemirror.vercel.app)), and
253
+ [`prism-react-renderer`](https://github.com/FormidableLabs/prism-react-renderer).
254
+
255
+ ## License
256
+
257
+ **MIT** — see [LICENSE](LICENSE). (Relicensed from FSL-1.1-ALv2 on 2026-09-23; the studio stays
258
+ FSL.)
259
+
260
+ `@w6w/expr`, which this package depends on, is MIT too, as is `@w6w/types`, the shared model these
261
+ components' wire types mirror (`@w6w/ui` keeps its own local copy rather than depending on it).
@@ -0,0 +1,76 @@
1
+ import { ActionDef, SavedTest, ThemeMode } from './types.ts';
2
+ export interface ActionTestFormProps {
3
+ /** App the action belongs to. */
4
+ appId: string;
5
+ /** The app's actions — the caller already has them from the app detail. */
6
+ actions: ActionDef[];
7
+ /** Fixed connection to run against; its credential is resolved server-side. */
8
+ connectionId?: string;
9
+ /**
10
+ * Pre-selected action (controlled). When provided the built-in action
11
+ * `<select>` is hidden — the caller is already driving the selection.
12
+ */
13
+ action?: ActionDef | null;
14
+ /** Theme hint, accepted for parity with other ui-lib components. */
15
+ theme?: ThemeMode;
16
+ /**
17
+ * Studio-integration seam: when provided (and its reference changes) the
18
+ * current action's params are seeded from a shallow copy of this object, so a
19
+ * host page can "open" a saved test pre-filled. The stored object is never
20
+ * mutated; a subsequent user edit is free to diverge. Optional — existing
21
+ * consumers keep compiling.
22
+ */
23
+ seedValues?: Record<string, unknown> | null;
24
+ /**
25
+ * Studio-integration seam: fired after a successful saved-test create/delete
26
+ * so the host page can invalidate its own `["saved-tests", connId]` query.
27
+ * The modal rail still refreshes its own list independently. Optional.
28
+ */
29
+ onSavedTestsChanged?: () => void;
30
+ /**
31
+ * Studio-integration seam (URL-driven host): the id of the saved test being
32
+ * edited, from a studio deep link (`…/test/:testId`). When it changes to a
33
+ * non-null id it is adopted as the current `editingTestId` — so the bottom Save
34
+ * PATCHes that row and the Delete button shows; when null the tester is a
35
+ * fresh/unsaved test. Optional — existing consumers keep compiling.
36
+ */
37
+ seedTestId?: string | null;
38
+ /**
39
+ * Studio-integration seam: fired whenever the current `values` diverge from
40
+ * (or return to) the seeded baseline. This is the unsaved-changes signal the
41
+ * studio host gates modal-close on (its ConfirmModal prompt). Optional.
42
+ */
43
+ onDirtyChange?: (dirty: boolean) => void;
44
+ /**
45
+ * Studio-integration seam: fired after a successful save (POST create or PATCH
46
+ * update) with the resulting `SavedTest`, so the host can sync the URL
47
+ * (`…/test/:id`) and clear its own dirty state. Optional.
48
+ */
49
+ onTestSaved?: (test: SavedTest) => void;
50
+ /**
51
+ * Studio-integration seam: fired after a successful delete of the saved test
52
+ * currently being edited, with the deleted id, so the host can navigate away
53
+ * from a now-dead `…/test/:id` URL. Optional — existing consumers keep compiling.
54
+ */
55
+ onDeleted?: (testId: string) => void;
56
+ /**
57
+ * Host-embedded mode. When `true` the caller already renders this widget inside
58
+ * its own modal (studio's `ConnectionTesterModal`), so the widget suppresses its
59
+ * OWN `<Modal>` + pop-out (⤢) toggle and instead fills the host container as a
60
+ * full-height flex column: the params + saved-tests region scrolls and the
61
+ * action bar is pinned to the bottom. Default `false` — non-embedded (inline /
62
+ * own pop-out) usages are unchanged.
63
+ */
64
+ embedded?: boolean;
65
+ }
66
+ /**
67
+ * Schema-driven form to test/run a single action against a connection. Renders
68
+ * the action's declared params through {@link ParamsForm} (the same primitive
69
+ * the step builder uses) instead of a raw JSON textarea, invokes the action via
70
+ * `useW6WApi().invokeAction`, and shows the returned value or error.
71
+ *
72
+ * The selected action is either controlled by the caller (`action` prop) or
73
+ * chosen from a built-in `<select>` over `actions`. Param values reset whenever
74
+ * the selected action changes.
75
+ */
76
+ export declare function ActionTestForm({ appId, actions, connectionId, action, seedValues, onSavedTestsChanged, seedTestId, onDirtyChange, onTestSaved, onDeleted, embedded, }: ActionTestFormProps): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { ThemeMode } from './types.ts';
2
+ export interface AddConnectionModalProps {
3
+ onClose: () => void;
4
+ /** Fired after a successful create (both API-key and OAuth paths). */
5
+ onCreated: (result: {
6
+ connectionId: string;
7
+ }) => void;
8
+ /** Optional theme hint passed through to `AppIcon` (light/dark variant). */
9
+ theme?: ThemeMode;
10
+ /**
11
+ * Pre-select an app and skip the picker — used when the modal is opened for a
12
+ * specific app (e.g. from the step builder). Omit to let the user pick.
13
+ */
14
+ initialAppId?: string;
15
+ }
16
+ /**
17
+ * Add-connection modal. Same shape as the step builder's "add a step" modal —
18
+ * the shared {@link AppPicker} (searchable icon grid) for step one, then the
19
+ * chosen app's connection fields for step two — minus the tabs. Pick an app →
20
+ * pick an auth method → fill the fields (or run OAuth) → submit. The
21
+ * `AuthDef.fields` array drives the form, so no app-specific knowledge is baked
22
+ * in. Data + IO come from `useW6WApi()`.
23
+ */
24
+ export declare function AddConnectionModal(props: AddConnectionModalProps): import("react").JSX.Element;
@@ -0,0 +1,83 @@
1
+ import { ReactNode } from 'react';
2
+ import { AppSummary, ThemeMode } from './types.ts';
3
+ export interface AppPickerProps {
4
+ /** Fired when the user picks an app card. */
5
+ onSelectApp: (app: AppSummary) => void;
6
+ theme?: ThemeMode;
7
+ /** Optional pre-filter over the app list (e.g. only connectable apps). Applied CLIENT-side, on top of whatever page/list was fetched — never widens a fetch, only narrows what's shown. */
8
+ filter?: (app: AppSummary) => boolean;
9
+ /** Search-box placeholder. Defaults to "Search apps…". */
10
+ searchPlaceholder?: string;
11
+ /** Message shown when the (filtered) app list is empty. */
12
+ emptyMessage?: string;
13
+ /** Render the search input. Defaults to `true`; the connected-apps list opts out. */
14
+ search?: boolean;
15
+ /** Rendered beneath `emptyMessage` in the empty state (e.g. a "Browse all apps" button). */
16
+ emptyAction?: ReactNode;
17
+ /**
18
+ * Supply the catalog instead of letting the picker fetch it. For a caller
19
+ * that already holds the list — and, more to the point, that decides
20
+ * membership from fields this package's {@link AppSummary} does not carry
21
+ * (`supportsOAuth`, `owner`): passing the decided list keeps ONE list and one
22
+ * loading/error state, where `filter` would mean a second `listApps()` whose
23
+ * result can disagree with the caller's. `null` is "still loading" and
24
+ * renders the same placeholder the internal fetch does. Supplying a list
25
+ * (including `null`) always suppresses BOTH the legacy eager fetch and the
26
+ * bounded paged fetch below.
27
+ */
28
+ apps?: AppSummary[] | null;
29
+ /**
30
+ * Render an opt-in category-filter chip row, derived from the VISIBLE
31
+ * catalog's own `categories` values (never the full RFC vocabulary — see
32
+ * `app-categories.ts`). Defaults to `false`. Only {@link AddConnectionModal}
33
+ * turns this on today — both `StepBuilderModal` picker call sites already
34
+ * narrow their catalog through `filter`, so a second filter layer there
35
+ * would be redundant.
36
+ */
37
+ categoryFilter?: boolean;
38
+ /**
39
+ * Server-side `category` param for the bounded paged fetch (e.g. `"ai"` for
40
+ * the AI tab) — sent to `W6WApi.listAppsPage`, never applied client-side.
41
+ * Ignored when `apps` is supplied or the host has no `listAppsPage`.
42
+ */
43
+ category?: string;
44
+ /** Bounded page size for the paged fetch. Defaults to {@link DEFAULT_PAGE_LIMIT} (60). */
45
+ pageLimit?: number;
46
+ /**
47
+ * Optional page loader that takes precedence over `W6WApi.listAppsPage` and
48
+ * turns on the paged mode by itself (ignored when `apps` is supplied). It
49
+ * is called with exactly `{ q, cursor, limit, signal }` — never `category`
50
+ * or `compact` — and reuses the picker's debounce, stale-response guard,
51
+ * abort, Load more and Retry. Held in a ref: its identity may change every
52
+ * render without causing a request.
53
+ */
54
+ loadPage?: (options: {
55
+ q?: string;
56
+ cursor?: string;
57
+ limit: number;
58
+ signal: AbortSignal;
59
+ }) => Promise<{
60
+ apps: AppSummary[];
61
+ nextCursor?: string;
62
+ }>;
63
+ }
64
+ /**
65
+ * Searchable grid of app cards (icon + name + id + version) — the shared app picker used
66
+ * by both the step builder and the add-connection modal.
67
+ *
68
+ * **Three loading modes**, chosen automatically and mutually exclusive:
69
+ *
70
+ * 1. `apps` supplied (including `null`) — the caller owns loading; this
71
+ * component only renders.
72
+ * 2. `apps` omitted and the host implements `W6WApi.listAppsPage` — bounded
73
+ * server-paged loading: one page per search/category, explicit
74
+ * "Load more", debounced search, cancellation on query change/unmount
75
+ * (T2.1.1 A2). This is the path every current call site in this package
76
+ * reaches once its host wires the optional method.
77
+ * 3. `apps` omitted and the host has ONLY the legacy `W6WApi.listApps` —
78
+ * unchanged eager full-catalog fetch, preserved byte-for-byte for
79
+ * backward compatibility with an older/imported provider (C6). A host
80
+ * with neither `listAppsPage` nor `listApps` settles into this same
81
+ * mode's existing empty state — no request, no throw.
82
+ */
83
+ export declare function AppPicker({ onSelectApp, theme, filter, searchPlaceholder, emptyMessage, search, emptyAction, apps: providedApps, categoryFilter, category, pageLimit, loadPage, }: AppPickerProps): import("react").JSX.Element;