api-render-ui 1.1.2 → 1.1.4
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 +30 -0
- package/dist/index.cjs +140 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +140 -30
- package/dist/index.js.map +1 -1
- package/example/animal.html +1082 -1020
- package/package.json +1 -1
- package/src/api-render-ui.css +67 -24
- package/src/api-render-ui.ts +87 -7
- package/src/inlined-styles.ts +67 -24
- package/src/model.ts +45 -0
package/Readme.md
CHANGED
|
@@ -34,6 +34,36 @@ api-render-ui is a UI library that pursues simple and efficient data rendering f
|
|
|
34
34
|
// 执行渲染
|
|
35
35
|
apiRenderer.render(openapiSpec);
|
|
36
36
|
```
|
|
37
|
+
|
|
38
|
+
### Theme support
|
|
39
|
+
|
|
40
|
+
You can control the theme via the `theme` option when creating `ApiRenderer`:
|
|
41
|
+
|
|
42
|
+
- Pass a string: `'light'` or `'dark'` to use built-in theme classes.
|
|
43
|
+
- Pass an object: supply a palette (CSS variables or short keys) to set custom colors.
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// built-in light
|
|
49
|
+
new ApiRenderer({ mountPoint: '#notebook', theme: 'light' }).render(openapiSpec);
|
|
50
|
+
|
|
51
|
+
// built-in dark
|
|
52
|
+
new ApiRenderer({ mountPoint: '#notebook', theme: 'dark' }).render(openapiSpec);
|
|
53
|
+
|
|
54
|
+
// custom palette
|
|
55
|
+
// custom palette (recommended keys)
|
|
56
|
+
new ApiRenderer({ mountPoint: '#notebook', theme: { main: '#ff7f50', aux: '#ffd1b3', embellish: '#ffc39e', surface: '#fff8f0' } }).render(openapiSpec);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Palette keys supported:
|
|
60
|
+
|
|
61
|
+
- `main` — main (primary) color used for labels and primary accents.
|
|
62
|
+
- `aux` — auxiliary color used for hover and subtle accents.
|
|
63
|
+
- `embellish` / `embellishment` — embellishment color used for active states and outlines.
|
|
64
|
+
- `surface` — background surface color.
|
|
65
|
+
- `primary` — alias for `main`.
|
|
66
|
+
- Any CSS variable name (e.g. `--even-bg`) may also be provided directly.
|
|
37
67
|
### Usage in single html
|
|
38
68
|
Please refer to [example](example/animal.html) in the source code.
|
|
39
69
|
|
package/dist/index.cjs
CHANGED
|
@@ -27,13 +27,55 @@ module.exports = __toCommonJS(index_exports);
|
|
|
27
27
|
// src/inlined-styles.ts
|
|
28
28
|
var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
29
29
|
align-items: flex-start;
|
|
30
|
-
background: white;
|
|
30
|
+
background: var(--surface, white);
|
|
31
31
|
display: inline-flex;
|
|
32
32
|
flex-direction: column;
|
|
33
33
|
gap: 5px;
|
|
34
34
|
justify-content: flex-start;
|
|
35
35
|
width: 100%
|
|
36
36
|
}
|
|
37
|
+
/* Theme variables and mappings */
|
|
38
|
+
:root {
|
|
39
|
+
--Labels---Vibrant---Controls-Primary-\u221A: #404040;
|
|
40
|
+
--primary: #404040;
|
|
41
|
+
--main-color: #404040; /* main / primary color */
|
|
42
|
+
--aux-color: #a9c7ef; /* auxiliary color for hover / accents */
|
|
43
|
+
--embellish-color: #ced8e7; /* embellishment color for active states */
|
|
44
|
+
--surface: white;
|
|
45
|
+
--text: black;
|
|
46
|
+
--even-bg: rgb(235, 239, 244);
|
|
47
|
+
--odd-bg: rgb(250, 246, 246);
|
|
48
|
+
--hover-bg: var(--aux-color, rgb(169, 199, 239));
|
|
49
|
+
--active-bg: var(--embellish-color, rgb(206, 216, 231));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.codigma-theme-light {
|
|
53
|
+
--main-color: #404040;
|
|
54
|
+
--aux-color: #a9c7ef;
|
|
55
|
+
--embellish-color: #ced8e7;
|
|
56
|
+
--primary: var(--main-color);
|
|
57
|
+
--Labels---Vibrant---Controls-Primary-\u221A: var(--main-color);
|
|
58
|
+
--surface: white;
|
|
59
|
+
--text: black;
|
|
60
|
+
--even-bg: rgb(235, 239, 244);
|
|
61
|
+
--odd-bg: rgb(250, 246, 246);
|
|
62
|
+
--hover-bg: var(--aux-color);
|
|
63
|
+
--active-bg: var(--embellish-color);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.codigma-theme-dark {
|
|
67
|
+
--main-color: #9fb8ff;
|
|
68
|
+
--aux-color: #334155;
|
|
69
|
+
--embellish-color: #22303a;
|
|
70
|
+
--primary: var(--main-color);
|
|
71
|
+
--Labels---Vibrant---Controls-Primary-\u221A: var(--main-color);
|
|
72
|
+
--surface: #1f1f1f;
|
|
73
|
+
--text: #e6e6e6;
|
|
74
|
+
--even-bg: #2a2a2a;
|
|
75
|
+
--odd-bg: #222222;
|
|
76
|
+
--hover-bg: var(--aux-color);
|
|
77
|
+
--active-bg: var(--embellish-color);
|
|
78
|
+
}
|
|
37
79
|
.codigma-apioperator {
|
|
38
80
|
align-items: center;
|
|
39
81
|
align-self: stretch;
|
|
@@ -44,18 +86,18 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
44
86
|
justify-content: flex-start
|
|
45
87
|
}
|
|
46
88
|
.codigma-apioperator:nth-child(even) {
|
|
47
|
-
|
|
89
|
+
color: var(--main-color, var(--primary, #404040));
|
|
48
90
|
}
|
|
49
91
|
.codigma-apioperator:nth-child(odd) {
|
|
50
|
-
|
|
92
|
+
color: var(--main-color, var(--primary, #404040));
|
|
51
93
|
}
|
|
52
94
|
|
|
53
95
|
.codigma-apioperator:hover {
|
|
54
96
|
cursor: pointer;
|
|
55
|
-
|
|
97
|
+
color: var(--main-color, var(--primary, #404040));
|
|
56
98
|
}
|
|
57
99
|
.codigma-apioperator:active {
|
|
58
|
-
|
|
100
|
+
color: var(--main-color, var(--primary, #404040));
|
|
59
101
|
}
|
|
60
102
|
.codigma-method {
|
|
61
103
|
align-items: center;
|
|
@@ -71,18 +113,18 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
71
113
|
justify-content: center
|
|
72
114
|
}
|
|
73
115
|
.codigma-get {
|
|
74
|
-
color: var(--
|
|
116
|
+
color: var(--main-color, var(--primary, #404040));
|
|
75
117
|
word-wrap: break-word
|
|
76
118
|
}
|
|
77
119
|
.codigma-requrl {
|
|
78
|
-
color: black;
|
|
120
|
+
color: var(--text, black);
|
|
79
121
|
flex: 1 1 0;
|
|
80
122
|
word-wrap: break-word
|
|
81
123
|
}
|
|
82
124
|
/**********************apiunit css style*************************/
|
|
83
125
|
.codigma-apiunit {
|
|
84
126
|
align-items: flex-start;
|
|
85
|
-
background: white;
|
|
127
|
+
background: var(--surface, white);
|
|
86
128
|
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
|
|
87
129
|
display: inline-flex;
|
|
88
130
|
flex-direction: column;
|
|
@@ -93,8 +135,8 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
93
135
|
.codigma-apiunit-apioperator {
|
|
94
136
|
align-items: center;
|
|
95
137
|
align-self: stretch;
|
|
96
|
-
border-bottom: 1px var(--
|
|
97
|
-
border-top: 1px var(--
|
|
138
|
+
border-bottom: 1px var(--main-color, var(--primary, #404040)) solid;
|
|
139
|
+
border-top: 1px var(--main-color, var(--primary, #404040)) solid;
|
|
98
140
|
display: inline-flex;
|
|
99
141
|
gap: 10px;
|
|
100
142
|
height: 48px;
|
|
@@ -115,17 +157,18 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
115
157
|
justify-content: center
|
|
116
158
|
}
|
|
117
159
|
.codigma-apiunit-post {
|
|
118
|
-
color: var(--
|
|
160
|
+
color: var(--main-color, var(--primary, #404040));
|
|
119
161
|
word-wrap: break-word
|
|
120
162
|
}
|
|
121
163
|
.codigma-apiunit-requrl {
|
|
122
|
-
color: black;
|
|
164
|
+
color: var(--text, black);
|
|
123
165
|
flex: 1 1 0;
|
|
124
166
|
word-wrap: break-word;
|
|
125
167
|
border-left: 0;
|
|
126
168
|
border-right: 0;
|
|
127
169
|
border-top: 0;
|
|
128
|
-
border-bottom: 1px solid
|
|
170
|
+
border-bottom: 1px var(--main-color, var(--primary, #404040)) solid;
|
|
171
|
+
height: 70%;
|
|
129
172
|
}
|
|
130
173
|
.codigma-apiunit-send-button {
|
|
131
174
|
align-items: center;
|
|
@@ -136,7 +179,7 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
136
179
|
width: 88px
|
|
137
180
|
}
|
|
138
181
|
.codigma-apiunit-send {
|
|
139
|
-
color: black;
|
|
182
|
+
color: var(--text, black);
|
|
140
183
|
word-wrap: break-word
|
|
141
184
|
}
|
|
142
185
|
.codigma-apiunit-send-button:hover {
|
|
@@ -165,7 +208,7 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
165
208
|
}
|
|
166
209
|
.codigma-apiunit-parameters-cnr {
|
|
167
210
|
align-items: center;
|
|
168
|
-
background: white;
|
|
211
|
+
background: var(--surface, white);
|
|
169
212
|
display: flex;
|
|
170
213
|
height: 42px;
|
|
171
214
|
justify-content: space-between;
|
|
@@ -174,7 +217,7 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
174
217
|
.codigma-apiunit-parakeyvalues {
|
|
175
218
|
align-items: flex-start;
|
|
176
219
|
align-self: stretch;
|
|
177
|
-
background: white;
|
|
220
|
+
background: var(--surface, white);
|
|
178
221
|
display: inline-flex;
|
|
179
222
|
flex-direction: column;
|
|
180
223
|
flex: 1 1 0;
|
|
@@ -192,11 +235,11 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
192
235
|
}
|
|
193
236
|
.codigma-apiunit-valuetext {
|
|
194
237
|
align-self: stretch;
|
|
195
|
-
background: white;
|
|
238
|
+
background: var(--surface, white);
|
|
196
239
|
border-left: 0;
|
|
197
240
|
border-right: 0;
|
|
198
241
|
border-top: 0;
|
|
199
|
-
border-bottom: 1px var(--
|
|
242
|
+
border-bottom: 1px var(--main-color, var(--primary, #404040)) solid;
|
|
200
243
|
padding: 10px;
|
|
201
244
|
width: 161px
|
|
202
245
|
}
|
|
@@ -221,21 +264,21 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
221
264
|
.codigma-apiunit-parakeyvalues {
|
|
222
265
|
align-items: flex-start;
|
|
223
266
|
align-self: stretch;
|
|
224
|
-
background: white;
|
|
267
|
+
background: var(--surface, white);
|
|
225
268
|
display: flex;
|
|
226
269
|
flex: 1 1 0;
|
|
227
270
|
gap: 10px;
|
|
228
271
|
justify-content: flex-start;
|
|
229
272
|
outline-offset: -1px;
|
|
230
|
-
outline: 1px var(--
|
|
273
|
+
outline: 1px var(--main-color, var(--primary, #404040)) solid;
|
|
231
274
|
overflow: hidden;
|
|
232
275
|
padding: 10px
|
|
233
276
|
}
|
|
234
277
|
.codigma-apiunit-reqresponse {
|
|
235
278
|
align-items: flex-start;
|
|
236
279
|
align-self: stretch;
|
|
237
|
-
background: white;
|
|
238
|
-
border-top: 1px var(--
|
|
280
|
+
background: var(--surface, white);
|
|
281
|
+
border-top: 1px var(--main-color, var(--primary, #404040)) solid;
|
|
239
282
|
display: flex;
|
|
240
283
|
flex-direction: column;
|
|
241
284
|
flex: 1 1 0;
|
|
@@ -253,7 +296,7 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
253
296
|
}
|
|
254
297
|
.codigma-apiunit-responsetitle {
|
|
255
298
|
align-items: center;
|
|
256
|
-
border-bottom: 1px var(--
|
|
299
|
+
border-bottom: 1px var(--main-color, var(--primary, #404040)) solid;
|
|
257
300
|
display: flex;
|
|
258
301
|
height: 42px;
|
|
259
302
|
justify-content: space-between;
|
|
@@ -262,7 +305,7 @@ var GLOBAL_STYLES = `.codigma-apioperatorlist {
|
|
|
262
305
|
.codigma-apiunit-response-cnr {
|
|
263
306
|
align-items: center;
|
|
264
307
|
align-self: stretch;
|
|
265
|
-
background: white;
|
|
308
|
+
background: var(--surface, white);
|
|
266
309
|
display: flex;
|
|
267
310
|
justify-content: space-between;
|
|
268
311
|
padding-top: 2px;
|
|
@@ -287,11 +330,13 @@ var ApiRenderer = class _ApiRenderer {
|
|
|
287
330
|
mountPoint: document?.body,
|
|
288
331
|
// 默认挂载到body
|
|
289
332
|
className: "Apioperatorlist codigma-apioperatorlist",
|
|
290
|
-
layerName: "apioperatorlist"
|
|
333
|
+
layerName: "apioperatorlist",
|
|
334
|
+
// theme: can be a string like 'light' or 'dark', or an object palette
|
|
335
|
+
theme: "light"
|
|
291
336
|
}, options);
|
|
292
337
|
this.container = null;
|
|
293
338
|
}
|
|
294
|
-
render(apiSpec, renderUnit = false) {
|
|
339
|
+
render(apiSpec, currentServer, serviceName, renderUnit = false) {
|
|
295
340
|
const appendInlineStyle = (text) => {
|
|
296
341
|
if (!_ApiRenderer.globalStyleInjected) {
|
|
297
342
|
const styleEl = document.createElement("style");
|
|
@@ -306,9 +351,50 @@ var ApiRenderer = class _ApiRenderer {
|
|
|
306
351
|
if (!mountElement) {
|
|
307
352
|
throw new Error("Invalid mount point specified");
|
|
308
353
|
}
|
|
354
|
+
try {
|
|
355
|
+
const themeOpt = this.options.theme;
|
|
356
|
+
if (typeof themeOpt === "string") {
|
|
357
|
+
mountElement.classList.add(`codigma-theme-${themeOpt}`);
|
|
358
|
+
} else if (themeOpt && typeof themeOpt === "object") {
|
|
359
|
+
const palette = themeOpt;
|
|
360
|
+
const setVar = (key, value) => {
|
|
361
|
+
if (value == null) return;
|
|
362
|
+
const varName = key.startsWith("--") ? key : `--${key}`;
|
|
363
|
+
try {
|
|
364
|
+
mountElement.style.setProperty(varName, String(value));
|
|
365
|
+
} catch {
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
if (palette.main) {
|
|
369
|
+
setVar("--main-color", palette.main);
|
|
370
|
+
setVar("--primary", palette.main);
|
|
371
|
+
setVar("--Labels---Vibrant---Controls-Primary-\u221A", palette.main);
|
|
372
|
+
}
|
|
373
|
+
if (palette.aux) {
|
|
374
|
+
setVar("--aux-color", palette.aux);
|
|
375
|
+
setVar("--hover-bg", palette.aux);
|
|
376
|
+
}
|
|
377
|
+
if (palette.embellish || palette.embellishment) {
|
|
378
|
+
setVar("--embellish-color", palette.embellish || palette.embellishment);
|
|
379
|
+
setVar("--active-bg", palette.embellish || palette.embellishment);
|
|
380
|
+
}
|
|
381
|
+
if (palette.primary) {
|
|
382
|
+
setVar("--primary", palette.primary);
|
|
383
|
+
setVar("--Labels---Vibrant---Controls-Primary-\u221A", palette.primary);
|
|
384
|
+
setVar("--main-color", palette.primary);
|
|
385
|
+
}
|
|
386
|
+
if (palette["--even-bg"]) setVar("--even-bg", palette["--even-bg"]);
|
|
387
|
+
if (palette["--odd-bg"]) setVar("--odd-bg", palette["--odd-bg"]);
|
|
388
|
+
if (palette.surface) setVar("--surface", palette.surface);
|
|
389
|
+
Object.entries(palette).forEach(([k, v]) => {
|
|
390
|
+
if (k.startsWith("--")) setVar(k, v);
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
} catch (e) {
|
|
394
|
+
}
|
|
309
395
|
if (apiSpec["openapi"] && apiSpec["openapi"].startsWith("3.") || apiSpec["swagger"] && apiSpec["swagger"].startsWith("2.")) {
|
|
310
396
|
const countApi = countOpenAPI(apiSpec);
|
|
311
|
-
const apiOperatorList =
|
|
397
|
+
const apiOperatorList = parseOpenApiSpec(apiSpec, currentServer, serviceName);
|
|
312
398
|
if (countApi == 1 && renderUnit) {
|
|
313
399
|
this.container = createApiUnit(apiOperatorList[0]);
|
|
314
400
|
} else {
|
|
@@ -1227,7 +1313,7 @@ function createSvg() {
|
|
|
1227
1313
|
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
1228
1314
|
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
1229
1315
|
path.setAttribute("d", "M5.5 8.5L10.5 13.5L15.5 8.5");
|
|
1230
|
-
path.setAttribute("stroke", "var(--
|
|
1316
|
+
path.setAttribute("stroke", "var(--main-color, var(--primary, #404040) )");
|
|
1231
1317
|
path.setAttribute("stroke-width", "2");
|
|
1232
1318
|
path.setAttribute("stroke-linecap", "round");
|
|
1233
1319
|
path.setAttribute("stroke-linejoin", "round");
|
|
@@ -1367,7 +1453,7 @@ var HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch",
|
|
|
1367
1453
|
function isHttpMethod(method) {
|
|
1368
1454
|
return HTTP_METHODS.includes(method);
|
|
1369
1455
|
}
|
|
1370
|
-
function
|
|
1456
|
+
function parseOpenApiSpec(openapiSpec, currentServer, serviceName) {
|
|
1371
1457
|
const apiOperatorList = [];
|
|
1372
1458
|
const pathEntries = [];
|
|
1373
1459
|
for (const path in openapiSpec.paths) {
|
|
@@ -1388,9 +1474,18 @@ function parseOpenAPI(openapiSpec) {
|
|
|
1388
1474
|
}
|
|
1389
1475
|
}
|
|
1390
1476
|
pathItemEntries.forEach(([method, operation]) => {
|
|
1477
|
+
let url = path;
|
|
1478
|
+
if (currentServer) {
|
|
1479
|
+
url = currentServer.value + "/api/" + serviceName + "/v1" + path;
|
|
1480
|
+
} else if (openapiSpec.servers && openapiSpec.servers.length > 0) {
|
|
1481
|
+
url = openapiSpec.servers[0].url + path;
|
|
1482
|
+
}
|
|
1391
1483
|
const apiOperator = {
|
|
1484
|
+
id: uuid(),
|
|
1485
|
+
label: path,
|
|
1486
|
+
children: [],
|
|
1392
1487
|
method: method.toUpperCase(),
|
|
1393
|
-
url
|
|
1488
|
+
url,
|
|
1394
1489
|
rawApiInfo: operation,
|
|
1395
1490
|
requestBody: null,
|
|
1396
1491
|
response: {},
|
|
@@ -1481,6 +1576,21 @@ function parseOpenAPI(openapiSpec) {
|
|
|
1481
1576
|
});
|
|
1482
1577
|
return apiOperatorList;
|
|
1483
1578
|
}
|
|
1579
|
+
function uuid() {
|
|
1580
|
+
let s = [];
|
|
1581
|
+
const hexDigits = "0123456789abcdef";
|
|
1582
|
+
for (let i = 0; i < 28; i++) {
|
|
1583
|
+
const start = Math.floor(Math.random() * 16);
|
|
1584
|
+
s[i] = hexDigits.substring(start, start + 1);
|
|
1585
|
+
}
|
|
1586
|
+
s[14] = "4";
|
|
1587
|
+
const start1 = s[19] & 3 | 8;
|
|
1588
|
+
s[19] = hexDigits.substring(start1, start1 + 1);
|
|
1589
|
+
s[8] = s[13] = s[18] = s[23] = "-";
|
|
1590
|
+
s[0] = "a";
|
|
1591
|
+
var uuid2 = s.join("");
|
|
1592
|
+
return uuid2;
|
|
1593
|
+
}
|
|
1484
1594
|
function countOpenAPI(openapiSpec) {
|
|
1485
1595
|
let apiCount = 0;
|
|
1486
1596
|
const pathEntries = [];
|