api_binding_ui 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -50
- package/SKILL.md +29 -34
- package/dist/app/index-0n23yy5r.js +367 -0
- package/dist/app/index-aaxy714b.css +1 -0
- package/dist/app/index.html +7 -0
- package/dist/cli.js +969 -0
- package/dist/codegen/generate.d.ts +22 -0
- package/dist/codegen/helpers.d.ts +2 -0
- package/dist/framework/contract.d.ts +38 -23
- package/dist/framework/expr.d.ts +26 -27
- package/dist/framework/file.d.ts +28 -0
- package/dist/framework/loadCatalog.d.ts +4 -2
- package/dist/framework/store.d.ts +3 -15
- package/dist/{index-3q1vx729.js → index-jj8twdw9.js} +158 -173
- package/dist/index-jj8twdw9.js.map +16 -0
- package/dist/index.d.ts +6 -8
- package/dist/index.js +461 -298
- package/dist/index.js.map +6 -8
- package/dist/studio/BindingStudio.d.ts +6 -11
- package/dist/studio/SettingsPanel.d.ts +5 -7
- package/dist/studio/index.css +38 -149
- package/dist/studio/index.d.ts +1 -2
- package/dist/studio/index.js +318 -386
- package/dist/studio/index.js.map +8 -10
- package/dist/studio/useBindings.d.ts +7 -5
- package/dist/studio/useCatalog.d.ts +9 -2
- package/package.json +65 -53
- package/spec/FRAMEWORK.md +106 -201
- package/dist/framework/runner.d.ts +0 -36
- package/dist/index-3q1vx729.js.map +0 -16
- package/dist/runtime/BindingProvider.d.ts +0 -42
- package/dist/runtime/BindingScreen.d.ts +0 -23
- package/dist/runtime/hooks.d.ts +0 -22
- package/dist/runtime/screenStore.d.ts +0 -7
- package/dist/studio/BindingWidget.d.ts +0 -9
- package/dist/studio/useSettings.d.ts +0 -8
package/dist/studio/index.js
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
toManifest2,
|
|
5
|
-
markDirty,
|
|
6
|
-
savePending,
|
|
7
|
-
loadAll,
|
|
8
|
-
putBinding,
|
|
9
|
-
dropBinding,
|
|
10
|
-
parseManifests,
|
|
2
|
+
catalogFromText2,
|
|
3
|
+
loadCatalog2,
|
|
11
4
|
humanize,
|
|
5
|
+
fromFile2,
|
|
6
|
+
toFile2,
|
|
12
7
|
createEngine2,
|
|
13
|
-
validateRegistry2
|
|
14
|
-
|
|
15
|
-
} from "../index-3q1vx729.js";
|
|
8
|
+
validateRegistry2
|
|
9
|
+
} from "../index-jj8twdw9.js";
|
|
16
10
|
|
|
17
11
|
// src/studio/BindingStudio.tsx
|
|
18
|
-
import * as
|
|
12
|
+
import * as React14 from "react";
|
|
19
13
|
|
|
20
14
|
// src/studio/ComponentList.tsx
|
|
21
15
|
import * as React2 from "react";
|
|
@@ -2052,58 +2046,151 @@ function Navigator({ engine, current, onPick }) {
|
|
|
2052
2046
|
// src/studio/SettingsPanel.tsx
|
|
2053
2047
|
import * as React12 from "react";
|
|
2054
2048
|
|
|
2055
|
-
// src/studio/
|
|
2049
|
+
// src/studio/useCatalog.ts
|
|
2056
2050
|
import * as React11 from "react";
|
|
2057
2051
|
var DEFAULT_DOCS_URL = "https://apidocs.highradius.com/documentation-ui/index.yaml";
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2052
|
+
function useCatalog(url, provided) {
|
|
2053
|
+
const [state, setState] = React11.useState(() => provided ? { status: "ready", catalog: provided, loadedAt: new Date, source: "provided" } : { status: "loading" });
|
|
2054
|
+
const [nonce, setNonce] = React11.useState(0);
|
|
2055
|
+
const [pasted, setPasted] = React11.useState(null);
|
|
2056
|
+
React11.useEffect(() => {
|
|
2057
|
+
if (pasted) {
|
|
2058
|
+
setState({ status: "ready", catalog: pasted, loadedAt: new Date, source: "pasted" });
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
2061
|
+
if (provided) {
|
|
2062
|
+
setState({ status: "ready", catalog: provided, loadedAt: new Date, source: "provided" });
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
if (!url)
|
|
2066
|
+
return;
|
|
2067
|
+
const ctrl = new AbortController;
|
|
2068
|
+
setState((s) => ({ status: "loading", catalog: s.catalog }));
|
|
2069
|
+
loadCatalog2(url, { signal: ctrl.signal }).then((catalog) => setState({ status: "ready", catalog, loadedAt: new Date, source: "url" }), (e) => {
|
|
2070
|
+
if (!ctrl.signal.aborted)
|
|
2071
|
+
setState((s) => ({ status: "error", catalog: s.catalog, error: e instanceof Error ? e.message : String(e) }));
|
|
2077
2072
|
});
|
|
2073
|
+
return () => ctrl.abort();
|
|
2074
|
+
}, [url, provided, nonce, pasted]);
|
|
2075
|
+
const reload = React11.useCallback(() => {
|
|
2076
|
+
setPasted(null);
|
|
2077
|
+
setNonce((n) => n + 1);
|
|
2078
2078
|
}, []);
|
|
2079
|
-
|
|
2079
|
+
const loadPasted = React11.useCallback((text) => new Promise((resolve) => {
|
|
2080
|
+
setTimeout(() => {
|
|
2081
|
+
try {
|
|
2082
|
+
setPasted(catalogFromText2(text, "pasted"));
|
|
2083
|
+
resolve(undefined);
|
|
2084
|
+
} catch (e) {
|
|
2085
|
+
resolve(e instanceof Error ? e.message : String(e));
|
|
2086
|
+
}
|
|
2087
|
+
}, 0);
|
|
2088
|
+
}), []);
|
|
2089
|
+
return [state, reload, loadPasted];
|
|
2080
2090
|
}
|
|
2081
2091
|
|
|
2082
2092
|
// src/studio/SettingsPanel.tsx
|
|
2083
2093
|
import { jsx as jsx17, jsxs as jsxs15, Fragment as Fragment9 } from "react/jsx-runtime";
|
|
2084
2094
|
var TIME = new Intl.DateTimeFormat(undefined, { hour: "numeric", minute: "2-digit" });
|
|
2085
|
-
|
|
2086
|
-
try {
|
|
2087
|
-
const u = new URL(v, location.href);
|
|
2088
|
-
return u.protocol === "https:" || u.protocol === "http:" || u.protocol === "blob:";
|
|
2089
|
-
} catch {
|
|
2090
|
-
return false;
|
|
2091
|
-
}
|
|
2092
|
-
}
|
|
2095
|
+
var isSource = (v) => v.trim().length > 0 && !/^\s*(javascript|data):/i.test(v);
|
|
2093
2096
|
function docsSummary(c) {
|
|
2094
2097
|
if (c.status === "loading")
|
|
2095
2098
|
return "Loading…";
|
|
2096
2099
|
if (c.status === "error")
|
|
2097
2100
|
return c.error;
|
|
2098
2101
|
const products = new Set(c.catalog.operations.map((o) => o.product).filter(Boolean));
|
|
2099
|
-
|
|
2102
|
+
const where = c.source === "pasted" ? "Pasted file · " : "";
|
|
2103
|
+
return `${where}${products.size || 1} ${products.size === 1 ? "product" : "products"} · ${c.catalog.operations.length} ${c.catalog.operations.length === 1 ? "API" : "APIs"} · loaded ${TIME.format(c.loadedAt)}`;
|
|
2100
2104
|
}
|
|
2101
|
-
|
|
2105
|
+
var SIZE = new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 });
|
|
2106
|
+
var kb = (chars) => chars < 1e6 ? `${SIZE.format(chars / 1000)} KB` : `${SIZE.format(chars / 1e6)} MB`;
|
|
2107
|
+
function PasteDocs({ onPaste, onDone }) {
|
|
2108
|
+
const area = React12.useRef(null);
|
|
2109
|
+
const [size, setSize] = React12.useState(0);
|
|
2110
|
+
const [busy, setBusy] = React12.useState(false);
|
|
2111
|
+
const [error, setError] = React12.useState();
|
|
2112
|
+
const load = async () => {
|
|
2113
|
+
const text = area.current?.value ?? "";
|
|
2114
|
+
setBusy(true);
|
|
2115
|
+
setError(undefined);
|
|
2116
|
+
const problem = await onPaste(text);
|
|
2117
|
+
setBusy(false);
|
|
2118
|
+
if (problem) {
|
|
2119
|
+
setError(problem);
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2122
|
+
if (area.current)
|
|
2123
|
+
area.current.value = "";
|
|
2124
|
+
onDone();
|
|
2125
|
+
};
|
|
2126
|
+
return /* @__PURE__ */ jsxs15("div", {
|
|
2127
|
+
className: "abs-paste",
|
|
2128
|
+
children: [
|
|
2129
|
+
/* @__PURE__ */ jsx17("textarea", {
|
|
2130
|
+
ref: area,
|
|
2131
|
+
id: "abs-docs-paste",
|
|
2132
|
+
className: "abs-input abs-paste-area",
|
|
2133
|
+
rows: 7,
|
|
2134
|
+
wrap: "off",
|
|
2135
|
+
spellCheck: false,
|
|
2136
|
+
autoCorrect: "off",
|
|
2137
|
+
autoCapitalize: "off",
|
|
2138
|
+
autoComplete: "off",
|
|
2139
|
+
autoFocus: true,
|
|
2140
|
+
placeholder: "Paste the contents of index.yaml (or the JSON version)",
|
|
2141
|
+
"aria-label": "OpenAPI document",
|
|
2142
|
+
"aria-describedby": "abs-paste-note",
|
|
2143
|
+
"aria-invalid": !!error,
|
|
2144
|
+
onInput: (e) => setSize(e.currentTarget.value.length)
|
|
2145
|
+
}),
|
|
2146
|
+
/* @__PURE__ */ jsxs15("div", {
|
|
2147
|
+
className: "abs-set-row",
|
|
2148
|
+
children: [
|
|
2149
|
+
/* @__PURE__ */ jsx17("button", {
|
|
2150
|
+
type: "button",
|
|
2151
|
+
className: "abs-btn abs-btn-primary",
|
|
2152
|
+
onClick: () => void load(),
|
|
2153
|
+
disabled: busy || size === 0,
|
|
2154
|
+
children: busy ? /* @__PURE__ */ jsxs15(Fragment9, {
|
|
2155
|
+
children: [
|
|
2156
|
+
/* @__PURE__ */ jsx17(Icon, {
|
|
2157
|
+
name: "refresh",
|
|
2158
|
+
size: 14,
|
|
2159
|
+
className: "abs-spin"
|
|
2160
|
+
}),
|
|
2161
|
+
"Reading…"
|
|
2162
|
+
]
|
|
2163
|
+
}) : "Load"
|
|
2164
|
+
}),
|
|
2165
|
+
/* @__PURE__ */ jsx17("button", {
|
|
2166
|
+
type: "button",
|
|
2167
|
+
className: "abs-btn abs-btn-ghost",
|
|
2168
|
+
onClick: onDone,
|
|
2169
|
+
disabled: busy,
|
|
2170
|
+
children: "Cancel"
|
|
2171
|
+
}),
|
|
2172
|
+
/* @__PURE__ */ jsx17("span", {
|
|
2173
|
+
className: "abs-paste-size",
|
|
2174
|
+
"aria-live": "polite",
|
|
2175
|
+
children: size ? kb(size) : ""
|
|
2176
|
+
})
|
|
2177
|
+
]
|
|
2178
|
+
}),
|
|
2179
|
+
/* @__PURE__ */ jsx17("p", {
|
|
2180
|
+
id: "abs-paste-note",
|
|
2181
|
+
className: "abs-set-status" + (error ? " is-error" : ""),
|
|
2182
|
+
role: error ? "alert" : undefined,
|
|
2183
|
+
children: error ?? "Used for this session only. Nothing is saved; the URL is used again next time."
|
|
2184
|
+
})
|
|
2185
|
+
]
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
function SettingsPanel({ docsUrl, onDocsUrl, catalog, onReload, onPaste, onClose }) {
|
|
2102
2189
|
const [draft, setDraft] = React12.useState(docsUrl);
|
|
2103
|
-
const [
|
|
2190
|
+
const [pasting, setPasting] = React12.useState(false);
|
|
2191
|
+
const usingPaste = catalog.status === "ready" && catalog.source === "pasted";
|
|
2104
2192
|
const panel = React12.useRef(null);
|
|
2105
|
-
const
|
|
2106
|
-
const valid = isUrl(draft);
|
|
2193
|
+
const valid = isSource(draft);
|
|
2107
2194
|
const dirty = draft.trim() !== docsUrl;
|
|
2108
2195
|
React12.useEffect(() => {
|
|
2109
2196
|
const key = (e) => {
|
|
@@ -2132,192 +2219,144 @@ function SettingsPanel({ docsUrl, onDocsUrl, catalog, onReload, manifests, onImp
|
|
|
2132
2219
|
else
|
|
2133
2220
|
onReload();
|
|
2134
2221
|
};
|
|
2135
|
-
|
|
2136
|
-
const blob = new Blob([JSON.stringify(manifests(), null, 2) + `
|
|
2137
|
-
`], { type: "application/json" });
|
|
2138
|
-
const a = document.createElement("a");
|
|
2139
|
-
a.href = URL.createObjectURL(blob);
|
|
2140
|
-
a.download = "bindings.json";
|
|
2141
|
-
a.click();
|
|
2142
|
-
setTimeout(() => URL.revokeObjectURL(a.href), 1000);
|
|
2143
|
-
};
|
|
2144
|
-
const readFile = async (f) => {
|
|
2145
|
-
if (!f)
|
|
2146
|
-
return;
|
|
2147
|
-
try {
|
|
2148
|
-
const list = parseManifests(await f.text());
|
|
2149
|
-
onImport(list);
|
|
2150
|
-
setImportMsg({ ok: true, text: `Imported ${list.length} ${list.length === 1 ? "screen" : "screens"}.` });
|
|
2151
|
-
} catch (err) {
|
|
2152
|
-
setImportMsg({ ok: false, text: err instanceof Error ? err.message : "The file could not be read." });
|
|
2153
|
-
} finally {
|
|
2154
|
-
if (file.current)
|
|
2155
|
-
file.current.value = "";
|
|
2156
|
-
}
|
|
2157
|
-
};
|
|
2158
|
-
return /* @__PURE__ */ jsxs15("div", {
|
|
2222
|
+
return /* @__PURE__ */ jsx17("div", {
|
|
2159
2223
|
className: "abs-settings abs-pop",
|
|
2160
2224
|
ref: panel,
|
|
2161
2225
|
role: "dialog",
|
|
2162
2226
|
"aria-label": "Settings",
|
|
2163
|
-
children:
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
children: dirty ? "Use" : /* @__PURE__ */ jsxs15(Fragment9, {
|
|
2198
|
-
children: [
|
|
2199
|
-
/* @__PURE__ */ jsx17(Icon, {
|
|
2200
|
-
name: "refresh",
|
|
2201
|
-
size: 14,
|
|
2202
|
-
className: catalog.status === "loading" ? "abs-spin" : ""
|
|
2203
|
-
}),
|
|
2204
|
-
"Reload"
|
|
2205
|
-
]
|
|
2206
|
-
})
|
|
2207
|
-
})
|
|
2208
|
-
]
|
|
2209
|
-
}),
|
|
2210
|
-
/* @__PURE__ */ jsx17("p", {
|
|
2211
|
-
id: "abs-docs-status",
|
|
2212
|
-
className: "abs-set-status" + (catalog.status === "error" ? " is-error" : ""),
|
|
2213
|
-
"aria-live": "polite",
|
|
2214
|
-
children: valid ? docsSummary(catalog) : "Enter a full URL, for example " + DEFAULT_DOCS_URL
|
|
2215
|
-
}),
|
|
2216
|
-
docsUrl !== DEFAULT_DOCS_URL ? /* @__PURE__ */ jsx17("button", {
|
|
2217
|
-
type: "button",
|
|
2218
|
-
className: "abs-link abs-more",
|
|
2219
|
-
onClick: () => {
|
|
2220
|
-
setDraft(DEFAULT_DOCS_URL);
|
|
2221
|
-
onDocsUrl(DEFAULT_DOCS_URL);
|
|
2222
|
-
},
|
|
2223
|
-
children: "Use the default URL"
|
|
2224
|
-
}) : null
|
|
2225
|
-
]
|
|
2226
|
-
}),
|
|
2227
|
-
/* @__PURE__ */ jsxs15("div", {
|
|
2228
|
-
className: "abs-set-sec",
|
|
2229
|
-
children: [
|
|
2230
|
-
/* @__PURE__ */ jsx17("span", {
|
|
2231
|
-
className: "abs-set-h",
|
|
2232
|
-
children: "Bindings"
|
|
2233
|
-
}),
|
|
2234
|
-
/* @__PURE__ */ jsx17("p", {
|
|
2235
|
-
className: "abs-set-d",
|
|
2236
|
-
children: "Download to commit them with the app. Import replaces the screens the file contains."
|
|
2237
|
-
}),
|
|
2238
|
-
/* @__PURE__ */ jsxs15("div", {
|
|
2239
|
-
className: "abs-set-row",
|
|
2240
|
-
children: [
|
|
2241
|
-
/* @__PURE__ */ jsxs15("button", {
|
|
2242
|
-
type: "button",
|
|
2243
|
-
className: "abs-btn",
|
|
2244
|
-
onClick: download,
|
|
2245
|
-
children: [
|
|
2246
|
-
/* @__PURE__ */ jsx17(Icon, {
|
|
2247
|
-
name: "download",
|
|
2248
|
-
size: 14
|
|
2249
|
-
}),
|
|
2250
|
-
"Download"
|
|
2251
|
-
]
|
|
2252
|
-
}),
|
|
2253
|
-
/* @__PURE__ */ jsxs15("button", {
|
|
2254
|
-
type: "button",
|
|
2255
|
-
className: "abs-btn",
|
|
2256
|
-
onClick: () => file.current?.click(),
|
|
2227
|
+
children: /* @__PURE__ */ jsxs15("form", {
|
|
2228
|
+
className: "abs-set-sec",
|
|
2229
|
+
onSubmit: apply,
|
|
2230
|
+
children: [
|
|
2231
|
+
/* @__PURE__ */ jsx17("label", {
|
|
2232
|
+
className: "abs-set-h",
|
|
2233
|
+
htmlFor: "abs-docs-url",
|
|
2234
|
+
children: "API docs"
|
|
2235
|
+
}),
|
|
2236
|
+
/* @__PURE__ */ jsx17("p", {
|
|
2237
|
+
className: "abs-set-d",
|
|
2238
|
+
children: "The OpenAPI file every API is read from: a URL, or a path next to the bindings file."
|
|
2239
|
+
}),
|
|
2240
|
+
/* @__PURE__ */ jsxs15("div", {
|
|
2241
|
+
className: "abs-set-row",
|
|
2242
|
+
children: [
|
|
2243
|
+
/* @__PURE__ */ jsx17("input", {
|
|
2244
|
+
id: "abs-docs-url",
|
|
2245
|
+
name: "docsUrl",
|
|
2246
|
+
type: "text",
|
|
2247
|
+
inputMode: "url",
|
|
2248
|
+
autoComplete: "off",
|
|
2249
|
+
spellCheck: false,
|
|
2250
|
+
className: "abs-input" + (valid ? "" : " is-invalid"),
|
|
2251
|
+
value: draft,
|
|
2252
|
+
onChange: (e) => setDraft(e.target.value),
|
|
2253
|
+
"aria-invalid": !valid,
|
|
2254
|
+
"aria-describedby": "abs-docs-status"
|
|
2255
|
+
}),
|
|
2256
|
+
/* @__PURE__ */ jsx17("button", {
|
|
2257
|
+
type: "submit",
|
|
2258
|
+
className: "abs-btn abs-btn-primary",
|
|
2259
|
+
disabled: !valid || catalog.status === "loading",
|
|
2260
|
+
children: dirty ? "Use" : /* @__PURE__ */ jsxs15(Fragment9, {
|
|
2257
2261
|
children: [
|
|
2258
2262
|
/* @__PURE__ */ jsx17(Icon, {
|
|
2259
|
-
name: "
|
|
2260
|
-
size: 14
|
|
2263
|
+
name: "refresh",
|
|
2264
|
+
size: 14,
|
|
2265
|
+
className: catalog.status === "loading" ? "abs-spin" : ""
|
|
2261
2266
|
}),
|
|
2262
|
-
"
|
|
2267
|
+
"Reload"
|
|
2263
2268
|
]
|
|
2264
|
-
}),
|
|
2265
|
-
/* @__PURE__ */ jsx17("input", {
|
|
2266
|
-
ref: file,
|
|
2267
|
-
type: "file",
|
|
2268
|
-
accept: "application/json,.json",
|
|
2269
|
-
hidden: true,
|
|
2270
|
-
onChange: (e) => void readFile(e.target.files?.[0])
|
|
2271
2269
|
})
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2270
|
+
})
|
|
2271
|
+
]
|
|
2272
|
+
}),
|
|
2273
|
+
/* @__PURE__ */ jsx17("p", {
|
|
2274
|
+
id: "abs-docs-status",
|
|
2275
|
+
className: "abs-set-status" + (catalog.status === "error" ? " is-error" : ""),
|
|
2276
|
+
"aria-live": "polite",
|
|
2277
|
+
children: valid ? docsSummary(catalog) : "Enter a URL or a path, for example " + DEFAULT_DOCS_URL
|
|
2278
|
+
}),
|
|
2279
|
+
pasting ? /* @__PURE__ */ jsx17(PasteDocs, {
|
|
2280
|
+
onPaste,
|
|
2281
|
+
onDone: () => setPasting(false)
|
|
2282
|
+
}) : /* @__PURE__ */ jsxs15("div", {
|
|
2283
|
+
className: "abs-set-links",
|
|
2284
|
+
children: [
|
|
2285
|
+
usingPaste ? /* @__PURE__ */ jsxs15("button", {
|
|
2286
|
+
type: "button",
|
|
2287
|
+
className: "abs-link",
|
|
2288
|
+
onClick: onReload,
|
|
2289
|
+
children: [
|
|
2290
|
+
/* @__PURE__ */ jsx17(Icon, {
|
|
2291
|
+
name: "refresh",
|
|
2292
|
+
size: 14
|
|
2293
|
+
}),
|
|
2294
|
+
"Use the URL again"
|
|
2295
|
+
]
|
|
2296
|
+
}) : /* @__PURE__ */ jsxs15("button", {
|
|
2297
|
+
type: "button",
|
|
2298
|
+
className: "abs-link",
|
|
2299
|
+
onClick: () => setPasting(true),
|
|
2300
|
+
children: [
|
|
2301
|
+
/* @__PURE__ */ jsx17(Icon, {
|
|
2302
|
+
name: "upload",
|
|
2303
|
+
size: 14
|
|
2304
|
+
}),
|
|
2305
|
+
"Paste the file instead"
|
|
2306
|
+
]
|
|
2307
|
+
}),
|
|
2308
|
+
docsUrl !== DEFAULT_DOCS_URL ? /* @__PURE__ */ jsx17("button", {
|
|
2309
|
+
type: "button",
|
|
2310
|
+
className: "abs-link",
|
|
2311
|
+
onClick: () => {
|
|
2312
|
+
setDraft(DEFAULT_DOCS_URL);
|
|
2313
|
+
onDocsUrl(DEFAULT_DOCS_URL);
|
|
2314
|
+
},
|
|
2315
|
+
children: "Use the default URL"
|
|
2316
|
+
}) : null
|
|
2317
|
+
]
|
|
2318
|
+
})
|
|
2319
|
+
]
|
|
2320
|
+
})
|
|
2282
2321
|
});
|
|
2283
2322
|
}
|
|
2284
2323
|
|
|
2285
2324
|
// src/studio/useBindings.ts
|
|
2286
2325
|
import * as React13 from "react";
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2326
|
+
|
|
2327
|
+
// src/framework/store.ts
|
|
2328
|
+
function putBinding(idx, screen, b) {
|
|
2329
|
+
const list = (idx[screen] ?? []).filter((x) => !(x.component === b.component && x.slot === b.slot));
|
|
2330
|
+
return { ...idx, [screen]: [...list, b] };
|
|
2331
|
+
}
|
|
2332
|
+
function dropBinding(idx, screen, component, slot) {
|
|
2333
|
+
return { ...idx, [screen]: (idx[screen] ?? []).filter((x) => !(x.component === component && x.slot === slot)) };
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
// src/studio/useBindings.ts
|
|
2337
|
+
function useBindings(initial, save) {
|
|
2338
|
+
const [index, setIndex] = React13.useState(initial);
|
|
2290
2339
|
const [status, setStatus] = React13.useState("idle");
|
|
2291
2340
|
const [removed, setRemoved] = React13.useState(null);
|
|
2292
|
-
const
|
|
2341
|
+
const edits = React13.useRef(0);
|
|
2293
2342
|
const latest = React13.useRef(index);
|
|
2294
2343
|
latest.current = index;
|
|
2295
|
-
const screenIds = fw?.registry.screens.map((s) => s.id).join(`
|
|
2296
|
-
`) ?? "";
|
|
2297
|
-
React13.useEffect(() => {
|
|
2298
|
-
if (!screenIds)
|
|
2299
|
-
return;
|
|
2300
|
-
let live = true;
|
|
2301
|
-
loadAll(adapter, screenIds.split(`
|
|
2302
|
-
`)).then((i) => {
|
|
2303
|
-
if (live) {
|
|
2304
|
-
setIndex(i);
|
|
2305
|
-
setLoaded(true);
|
|
2306
|
-
}
|
|
2307
|
-
});
|
|
2308
|
-
return () => {
|
|
2309
|
-
live = false;
|
|
2310
|
-
};
|
|
2311
|
-
}, [adapter, screenIds]);
|
|
2312
2344
|
const flush = React13.useCallback(async () => {
|
|
2313
|
-
|
|
2345
|
+
const at = edits.current;
|
|
2346
|
+
if (!at)
|
|
2314
2347
|
return;
|
|
2315
2348
|
setStatus("saving");
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2349
|
+
try {
|
|
2350
|
+
await save(latest.current);
|
|
2351
|
+
if (edits.current === at)
|
|
2352
|
+
edits.current = 0;
|
|
2353
|
+
setStatus(edits.current ? "saving" : "saved");
|
|
2354
|
+
} catch {
|
|
2355
|
+
setStatus("failed");
|
|
2356
|
+
}
|
|
2357
|
+
}, [save]);
|
|
2319
2358
|
React13.useEffect(() => {
|
|
2320
|
-
if (!
|
|
2359
|
+
if (!edits.current)
|
|
2321
2360
|
return;
|
|
2322
2361
|
setStatus("saving");
|
|
2323
2362
|
const t = setTimeout(flush, 400);
|
|
@@ -2328,21 +2367,21 @@ function useBindings(fw, adapter) {
|
|
|
2328
2367
|
}, [flush]);
|
|
2329
2368
|
React13.useEffect(() => {
|
|
2330
2369
|
const warn = (e) => {
|
|
2331
|
-
if (
|
|
2370
|
+
if (edits.current)
|
|
2332
2371
|
e.preventDefault();
|
|
2333
2372
|
};
|
|
2334
2373
|
window.addEventListener("beforeunload", warn);
|
|
2335
2374
|
return () => window.removeEventListener("beforeunload", warn);
|
|
2336
2375
|
}, []);
|
|
2337
2376
|
const put = React13.useCallback((screen, b) => {
|
|
2338
|
-
|
|
2377
|
+
edits.current++;
|
|
2339
2378
|
setIndex((i) => putBinding(i, screen, b));
|
|
2340
2379
|
}, []);
|
|
2341
2380
|
const drop = React13.useCallback((screen, component, slot) => {
|
|
2342
2381
|
const binding = latest.current[screen]?.find((x) => x.component === component && x.slot === slot);
|
|
2343
2382
|
if (binding)
|
|
2344
2383
|
setRemoved({ screen, binding });
|
|
2345
|
-
|
|
2384
|
+
edits.current++;
|
|
2346
2385
|
setIndex((i) => dropBinding(i, screen, component, slot));
|
|
2347
2386
|
}, []);
|
|
2348
2387
|
const undo = React13.useCallback(() => {
|
|
@@ -2351,72 +2390,12 @@ function useBindings(fw, adapter) {
|
|
|
2351
2390
|
setRemoved(null);
|
|
2352
2391
|
}, [put, removed]);
|
|
2353
2392
|
const dismiss = React13.useCallback(() => setRemoved(null), []);
|
|
2354
|
-
|
|
2355
|
-
manifests.forEach((m) => markDirty(pending.current, m.screen));
|
|
2356
|
-
setIndex((i) => ({ ...i, ...Object.fromEntries(manifests.map((m) => [m.screen, m.bindings])) }));
|
|
2357
|
-
}, []);
|
|
2358
|
-
return { index, loaded, status, removed, put, drop, undo, dismiss, importManifests, retry: flush };
|
|
2359
|
-
}
|
|
2360
|
-
|
|
2361
|
-
// src/studio/useCatalog.ts
|
|
2362
|
-
import * as React14 from "react";
|
|
2363
|
-
|
|
2364
|
-
// src/framework/loadCatalog.ts
|
|
2365
|
-
import { parse } from "yaml";
|
|
2366
|
-
class CatalogLoadError extends Error {
|
|
2367
|
-
url;
|
|
2368
|
-
constructor(message, url) {
|
|
2369
|
-
super(message);
|
|
2370
|
-
this.url = url;
|
|
2371
|
-
this.name = "CatalogLoadError";
|
|
2372
|
-
}
|
|
2373
|
-
}
|
|
2374
|
-
async function loadCatalog(url, init) {
|
|
2375
|
-
let res;
|
|
2376
|
-
try {
|
|
2377
|
-
res = await fetch(url, { ...init, headers: { Accept: "application/yaml, application/json, text/yaml, */*", ...init?.headers } });
|
|
2378
|
-
} catch {
|
|
2379
|
-
throw new CatalogLoadError("The docs could not be reached. Check the URL, your network, and that the docs server allows this site (CORS).", url);
|
|
2380
|
-
}
|
|
2381
|
-
if (!res.ok)
|
|
2382
|
-
throw new CatalogLoadError(`The docs server answered ${res.status} ${res.statusText}. Check the URL.`, url);
|
|
2383
|
-
const text = await res.text();
|
|
2384
|
-
let doc;
|
|
2385
|
-
try {
|
|
2386
|
-
doc = text.trimStart().startsWith("{") ? JSON.parse(text) : parse(text);
|
|
2387
|
-
} catch {
|
|
2388
|
-
throw new CatalogLoadError("The file is not valid JSON or YAML.", url);
|
|
2389
|
-
}
|
|
2390
|
-
try {
|
|
2391
|
-
return catalogFromOpenApi2(doc, { url });
|
|
2392
|
-
} catch (e) {
|
|
2393
|
-
throw new CatalogLoadError(e instanceof Error ? e.message : "The file is not an OpenAPI document.", url);
|
|
2394
|
-
}
|
|
2395
|
-
}
|
|
2396
|
-
|
|
2397
|
-
// src/studio/useCatalog.ts
|
|
2398
|
-
function useCatalog(url, provided) {
|
|
2399
|
-
const [state, setState] = React14.useState(() => provided ? { status: "ready", catalog: provided, loadedAt: new Date } : { status: "loading" });
|
|
2400
|
-
const [nonce, setNonce] = React14.useState(0);
|
|
2401
|
-
React14.useEffect(() => {
|
|
2402
|
-
if (provided) {
|
|
2403
|
-
setState({ status: "ready", catalog: provided, loadedAt: new Date });
|
|
2404
|
-
return;
|
|
2405
|
-
}
|
|
2406
|
-
const ctrl = new AbortController;
|
|
2407
|
-
setState((s) => ({ status: "loading", catalog: s.catalog }));
|
|
2408
|
-
loadCatalog(url, { signal: ctrl.signal }).then((catalog) => setState({ status: "ready", catalog, loadedAt: new Date }), (e) => {
|
|
2409
|
-
if (!ctrl.signal.aborted)
|
|
2410
|
-
setState((s) => ({ status: "error", catalog: s.catalog, error: e instanceof Error ? e.message : String(e) }));
|
|
2411
|
-
});
|
|
2412
|
-
return () => ctrl.abort();
|
|
2413
|
-
}, [url, provided, nonce]);
|
|
2414
|
-
const reload = React14.useCallback(() => setNonce((n) => n + 1), []);
|
|
2415
|
-
return [state, reload];
|
|
2393
|
+
return { index, loaded: true, status, removed, put, drop, undo, dismiss, retry: flush };
|
|
2416
2394
|
}
|
|
2417
2395
|
|
|
2418
2396
|
// src/studio/BindingStudio.tsx
|
|
2419
2397
|
import { jsx as jsx18, jsxs as jsxs16, Fragment as Fragment10 } from "react/jsx-runtime";
|
|
2398
|
+
var same = (s) => s;
|
|
2420
2399
|
function SaveState({ status, onRetry }) {
|
|
2421
2400
|
return /* @__PURE__ */ jsx18("span", {
|
|
2422
2401
|
className: "abs-saved is-" + status,
|
|
@@ -2452,7 +2431,7 @@ function SaveState({ status, onRetry }) {
|
|
|
2452
2431
|
});
|
|
2453
2432
|
}
|
|
2454
2433
|
function UndoToast({ removed, label, onUndo, onDismiss }) {
|
|
2455
|
-
|
|
2434
|
+
React14.useEffect(() => {
|
|
2456
2435
|
const t = setTimeout(onDismiss, 6000);
|
|
2457
2436
|
return () => clearTimeout(t);
|
|
2458
2437
|
}, [removed, onDismiss]);
|
|
@@ -2492,15 +2471,45 @@ var EMPTY_HINT = /* @__PURE__ */ jsxs16("aside", {
|
|
|
2492
2471
|
})
|
|
2493
2472
|
]
|
|
2494
2473
|
});
|
|
2495
|
-
function BindingStudio({
|
|
2496
|
-
const [
|
|
2497
|
-
const [
|
|
2498
|
-
const
|
|
2499
|
-
|
|
2500
|
-
|
|
2474
|
+
function BindingStudio({ store, docsUrl = same, initialScreen, title = "Bind API", onClose }) {
|
|
2475
|
+
const [file, setFile] = React14.useState(null);
|
|
2476
|
+
const [fileError, setFileError] = React14.useState();
|
|
2477
|
+
const latest = React14.useRef({ file: null, index: {} });
|
|
2478
|
+
React14.useEffect(() => {
|
|
2479
|
+
let live = true;
|
|
2480
|
+
store.load().then((f) => {
|
|
2481
|
+
if (live) {
|
|
2482
|
+
latest.current.file = f;
|
|
2483
|
+
setFile(f);
|
|
2484
|
+
}
|
|
2485
|
+
}, (e) => live && setFileError(e instanceof Error ? e.message : String(e)));
|
|
2486
|
+
return () => {
|
|
2487
|
+
live = false;
|
|
2488
|
+
};
|
|
2489
|
+
}, [store]);
|
|
2490
|
+
const [catalogState, reloadCatalog, loadPasted] = useCatalog(file ? docsUrl(file.openapi) : "");
|
|
2491
|
+
const [settingsOpen, setSettingsOpen] = React14.useState(false);
|
|
2492
|
+
const closeSettings = React14.useCallback(() => setSettingsOpen(false), []);
|
|
2501
2493
|
const catalog = catalogState.catalog;
|
|
2502
|
-
const
|
|
2503
|
-
|
|
2494
|
+
const model = React14.useMemo(() => {
|
|
2495
|
+
if (!file || !catalog)
|
|
2496
|
+
return null;
|
|
2497
|
+
const { fw, index } = fromFile2(file, catalog);
|
|
2498
|
+
return { fw: { ...fw, registry: validateRegistry2(fw).registry }, index };
|
|
2499
|
+
}, [file?.kinds, file?.screens, file?.components, catalog]);
|
|
2500
|
+
const save = React14.useCallback(async (index) => {
|
|
2501
|
+
latest.current.index = index;
|
|
2502
|
+
if (latest.current.file)
|
|
2503
|
+
await store.save(toFile2(latest.current.file, index));
|
|
2504
|
+
}, [store]);
|
|
2505
|
+
const setOpenapi = (openapi) => {
|
|
2506
|
+
const f = latest.current.file;
|
|
2507
|
+
if (!f)
|
|
2508
|
+
return;
|
|
2509
|
+
latest.current.file = { ...f, openapi };
|
|
2510
|
+
setFile(latest.current.file);
|
|
2511
|
+
store.save(toFile2(latest.current.file, Object.keys(latest.current.index).length ? latest.current.index : model?.index ?? {}));
|
|
2512
|
+
};
|
|
2504
2513
|
const settingsButton = /* @__PURE__ */ jsxs16("div", {
|
|
2505
2514
|
className: "abs-settings-wrap",
|
|
2506
2515
|
children: [
|
|
@@ -2529,18 +2538,18 @@ function BindingStudio({ framework, docsUrl = DEFAULT_DOCS_URL, persistence, ini
|
|
|
2529
2538
|
name: "close"
|
|
2530
2539
|
})
|
|
2531
2540
|
}) : null,
|
|
2532
|
-
settingsOpen ? /* @__PURE__ */ jsx18(SettingsPanel, {
|
|
2533
|
-
docsUrl:
|
|
2534
|
-
onDocsUrl:
|
|
2541
|
+
settingsOpen && file ? /* @__PURE__ */ jsx18(SettingsPanel, {
|
|
2542
|
+
docsUrl: file.openapi,
|
|
2543
|
+
onDocsUrl: setOpenapi,
|
|
2535
2544
|
catalog: catalogState,
|
|
2536
2545
|
onReload: reloadCatalog,
|
|
2537
|
-
|
|
2538
|
-
onImport: binds.importManifests,
|
|
2546
|
+
onPaste: loadPasted,
|
|
2539
2547
|
onClose: closeSettings
|
|
2540
2548
|
}) : null
|
|
2541
2549
|
]
|
|
2542
2550
|
});
|
|
2543
|
-
if (!
|
|
2551
|
+
if (!model) {
|
|
2552
|
+
const error = fileError ?? (catalogState.status === "error" ? catalogState.error : undefined);
|
|
2544
2553
|
return /* @__PURE__ */ jsxs16("div", {
|
|
2545
2554
|
className: "abs-root",
|
|
2546
2555
|
children: [
|
|
@@ -2557,7 +2566,7 @@ function BindingStudio({ framework, docsUrl = DEFAULT_DOCS_URL, persistence, ini
|
|
|
2557
2566
|
}),
|
|
2558
2567
|
/* @__PURE__ */ jsx18("div", {
|
|
2559
2568
|
className: "abs-state-page",
|
|
2560
|
-
children:
|
|
2569
|
+
children: error ? /* @__PURE__ */ jsxs16(Fragment10, {
|
|
2561
2570
|
children: [
|
|
2562
2571
|
/* @__PURE__ */ jsx18("span", {
|
|
2563
2572
|
className: "abs-empty-ico is-bad",
|
|
@@ -2567,12 +2576,12 @@ function BindingStudio({ framework, docsUrl = DEFAULT_DOCS_URL, persistence, ini
|
|
|
2567
2576
|
})
|
|
2568
2577
|
}),
|
|
2569
2578
|
/* @__PURE__ */ jsx18("b", {
|
|
2570
|
-
children: "The API docs did not load"
|
|
2579
|
+
children: fileError ? "The bindings file did not load" : "The API docs did not load"
|
|
2571
2580
|
}),
|
|
2572
2581
|
/* @__PURE__ */ jsx18("span", {
|
|
2573
|
-
children:
|
|
2582
|
+
children: error
|
|
2574
2583
|
}),
|
|
2575
|
-
/* @__PURE__ */ jsxs16("div", {
|
|
2584
|
+
fileError ? null : /* @__PURE__ */ jsxs16("div", {
|
|
2576
2585
|
className: "abs-set-row",
|
|
2577
2586
|
children: [
|
|
2578
2587
|
/* @__PURE__ */ jsxs16("button", {
|
|
@@ -2591,7 +2600,7 @@ function BindingStudio({ framework, docsUrl = DEFAULT_DOCS_URL, persistence, ini
|
|
|
2591
2600
|
type: "button",
|
|
2592
2601
|
className: "abs-btn",
|
|
2593
2602
|
onClick: () => setSettingsOpen(true),
|
|
2594
|
-
children: "Change the URL"
|
|
2603
|
+
children: "Change the URL or paste the file"
|
|
2595
2604
|
})
|
|
2596
2605
|
]
|
|
2597
2606
|
})
|
|
@@ -2604,7 +2613,7 @@ function BindingStudio({ framework, docsUrl = DEFAULT_DOCS_URL, persistence, ini
|
|
|
2604
2613
|
}),
|
|
2605
2614
|
/* @__PURE__ */ jsx18("span", {
|
|
2606
2615
|
"aria-live": "polite",
|
|
2607
|
-
children: "Loading API docs…"
|
|
2616
|
+
children: file ? "Loading API docs…" : "Loading bindings…"
|
|
2608
2617
|
})
|
|
2609
2618
|
]
|
|
2610
2619
|
})
|
|
@@ -2613,26 +2622,27 @@ function BindingStudio({ framework, docsUrl = DEFAULT_DOCS_URL, persistence, ini
|
|
|
2613
2622
|
});
|
|
2614
2623
|
}
|
|
2615
2624
|
return /* @__PURE__ */ jsx18(Workbench, {
|
|
2616
|
-
fw,
|
|
2617
|
-
|
|
2625
|
+
fw: model.fw,
|
|
2626
|
+
initial: model.index,
|
|
2627
|
+
save,
|
|
2618
2628
|
title,
|
|
2619
2629
|
initialScreen,
|
|
2620
2630
|
settingsButton
|
|
2621
2631
|
});
|
|
2622
2632
|
}
|
|
2623
|
-
function Workbench({ fw,
|
|
2624
|
-
const { index, loaded, status, removed, put, drop, undo, dismiss, retry } =
|
|
2625
|
-
const [place, go] =
|
|
2626
|
-
const engine =
|
|
2633
|
+
function Workbench({ fw, initial, save, title, initialScreen, settingsButton }) {
|
|
2634
|
+
const { index, loaded, status, removed, put, drop, undo, dismiss, retry } = useBindings(initial, save);
|
|
2635
|
+
const [place, go] = React14.useState({ screen: initialScreen });
|
|
2636
|
+
const engine = React14.useMemo(() => createEngine2(fw, index), [fw, index]);
|
|
2627
2637
|
const screen = place.screen && engine.SCR.get(place.screen) || fw.registry.screens[0];
|
|
2628
2638
|
const comp = screen && place.component ? engine.compOf(screen.id, place.component) : undefined;
|
|
2629
2639
|
const screenId = screen?.id;
|
|
2630
|
-
const select =
|
|
2631
|
-
const putHere =
|
|
2640
|
+
const select = React14.useCallback((component) => go({ screen: screenId, component }), [go, screenId]);
|
|
2641
|
+
const putHere = React14.useCallback((b) => {
|
|
2632
2642
|
if (screenId)
|
|
2633
2643
|
put(screenId, b);
|
|
2634
2644
|
}, [put, screenId]);
|
|
2635
|
-
const dropHere =
|
|
2645
|
+
const dropHere = React14.useCallback((c, s) => {
|
|
2636
2646
|
if (screenId)
|
|
2637
2647
|
drop(screenId, c, s);
|
|
2638
2648
|
}, [drop, screenId]);
|
|
@@ -2720,87 +2730,9 @@ function Workbench({ fw, binds, title, initialScreen, settingsButton }) {
|
|
|
2720
2730
|
]
|
|
2721
2731
|
});
|
|
2722
2732
|
}
|
|
2723
|
-
// src/studio/BindingWidget.tsx
|
|
2724
|
-
import * as React16 from "react";
|
|
2725
|
-
import { jsx as jsx19, jsxs as jsxs17, Fragment as Fragment11 } from "react/jsx-runtime";
|
|
2726
|
-
var fallbackStore = localStorageAdapter2();
|
|
2727
|
-
function BindingWidget({ framework, docsUrl, title }) {
|
|
2728
|
-
const runtime = useBindingRuntime();
|
|
2729
|
-
const dialog = React16.useRef(null);
|
|
2730
|
-
const fab = React16.useRef(null);
|
|
2731
|
-
const [state, setState] = React16.useState("closed");
|
|
2732
|
-
const [screen, setScreen] = React16.useState();
|
|
2733
|
-
const open = () => {
|
|
2734
|
-
setScreen(runtime.activeScreen());
|
|
2735
|
-
setState("open");
|
|
2736
|
-
};
|
|
2737
|
-
const requestClose = React16.useCallback(() => setState((s) => s === "open" ? "closing" : s), []);
|
|
2738
|
-
React16.useLayoutEffect(() => {
|
|
2739
|
-
if (state === "open" && !dialog.current?.open)
|
|
2740
|
-
dialog.current?.showModal();
|
|
2741
|
-
}, [state]);
|
|
2742
|
-
const finishClose = (e) => {
|
|
2743
|
-
if (e.target !== dialog.current || state !== "closing")
|
|
2744
|
-
return;
|
|
2745
|
-
dialog.current?.close();
|
|
2746
|
-
setState("closed");
|
|
2747
|
-
runtime.reloadSaved();
|
|
2748
|
-
fab.current?.focus();
|
|
2749
|
-
};
|
|
2750
|
-
return /* @__PURE__ */ jsxs17(Fragment11, {
|
|
2751
|
-
children: [
|
|
2752
|
-
/* @__PURE__ */ jsxs17("button", {
|
|
2753
|
-
ref: fab,
|
|
2754
|
-
type: "button",
|
|
2755
|
-
className: "abs-fab",
|
|
2756
|
-
onClick: open,
|
|
2757
|
-
"aria-haspopup": "dialog",
|
|
2758
|
-
"aria-expanded": state !== "closed",
|
|
2759
|
-
children: [
|
|
2760
|
-
/* @__PURE__ */ jsx19("span", {
|
|
2761
|
-
className: "abs-fab-ico",
|
|
2762
|
-
children: /* @__PURE__ */ jsx19(Icon, {
|
|
2763
|
-
name: "link",
|
|
2764
|
-
size: 18
|
|
2765
|
-
})
|
|
2766
|
-
}),
|
|
2767
|
-
/* @__PURE__ */ jsx19("span", {
|
|
2768
|
-
className: "abs-fab-label",
|
|
2769
|
-
children: /* @__PURE__ */ jsx19("span", {
|
|
2770
|
-
children: title ?? "Bind API"
|
|
2771
|
-
})
|
|
2772
|
-
})
|
|
2773
|
-
]
|
|
2774
|
-
}),
|
|
2775
|
-
state !== "closed" ? /* @__PURE__ */ jsx19("dialog", {
|
|
2776
|
-
ref: dialog,
|
|
2777
|
-
className: "abs-widget" + (state === "closing" ? " is-closing" : ""),
|
|
2778
|
-
"aria-label": title ?? "Bind API",
|
|
2779
|
-
onCancel: (e) => {
|
|
2780
|
-
e.preventDefault();
|
|
2781
|
-
requestClose();
|
|
2782
|
-
},
|
|
2783
|
-
onClick: (e) => {
|
|
2784
|
-
if (e.target === e.currentTarget)
|
|
2785
|
-
requestClose();
|
|
2786
|
-
},
|
|
2787
|
-
onAnimationEnd: finishClose,
|
|
2788
|
-
children: /* @__PURE__ */ jsx19(BindingStudio, {
|
|
2789
|
-
framework,
|
|
2790
|
-
docsUrl,
|
|
2791
|
-
title,
|
|
2792
|
-
initialScreen: screen,
|
|
2793
|
-
persistence: runtime.persistence ?? fallbackStore,
|
|
2794
|
-
onClose: requestClose
|
|
2795
|
-
})
|
|
2796
|
-
}) : null
|
|
2797
|
-
]
|
|
2798
|
-
});
|
|
2799
|
-
}
|
|
2800
2733
|
export {
|
|
2801
|
-
BindingStudio
|
|
2802
|
-
BindingWidget
|
|
2734
|
+
BindingStudio
|
|
2803
2735
|
};
|
|
2804
2736
|
|
|
2805
|
-
//# debugId=
|
|
2737
|
+
//# debugId=5CC922DF10302EB664756E2164756E21
|
|
2806
2738
|
//# sourceMappingURL=index.js.map
|