api-render-ui 1.1.3 → 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 +130 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +130 -26
- 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 +76 -3
- 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,7 +330,9 @@ 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
|
}
|
|
@@ -306,6 +351,47 @@ 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
397
|
const apiOperatorList = parseOpenApiSpec(apiSpec, currentServer, serviceName);
|
|
@@ -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");
|
|
@@ -1395,6 +1481,9 @@ function parseOpenApiSpec(openapiSpec, currentServer, serviceName) {
|
|
|
1395
1481
|
url = openapiSpec.servers[0].url + path;
|
|
1396
1482
|
}
|
|
1397
1483
|
const apiOperator = {
|
|
1484
|
+
id: uuid(),
|
|
1485
|
+
label: path,
|
|
1486
|
+
children: [],
|
|
1398
1487
|
method: method.toUpperCase(),
|
|
1399
1488
|
url,
|
|
1400
1489
|
rawApiInfo: operation,
|
|
@@ -1487,6 +1576,21 @@ function parseOpenApiSpec(openapiSpec, currentServer, serviceName) {
|
|
|
1487
1576
|
});
|
|
1488
1577
|
return apiOperatorList;
|
|
1489
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
|
+
}
|
|
1490
1594
|
function countOpenAPI(openapiSpec) {
|
|
1491
1595
|
let apiCount = 0;
|
|
1492
1596
|
const pathEntries = [];
|