@open-feishu-card/renderer 0.3.6 → 0.5.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/dist/all.css +106 -0
- package/dist/index.cjs +302 -16
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +302 -16
- package/dist/styles.css +106 -0
- package/package.json +2 -2
package/dist/all.css
CHANGED
|
@@ -380,6 +380,90 @@
|
|
|
380
380
|
font-size: 12px;
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
+
/* ---- img_combination 多图混排(比例逆向自网页版 .universal-card-img-combination) ---- */
|
|
384
|
+
.universal-card-img-combination { display: flex; width: 100%; justify-content: space-between; }
|
|
385
|
+
.universal-card-img-combination__item { min-width: 0; overflow: hidden; }
|
|
386
|
+
.universal-card-img-combination__item > .universal-card-image__host { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
387
|
+
.universal-card-img-combination__item > .universal-card-image__placeholder { width: 100%; height: 100%; }
|
|
388
|
+
/* double:左窄(32.4%, 24:33) + 右宽(67.6%, 49.33:33) */
|
|
389
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(odd) {
|
|
390
|
+
width: 32.4%; aspect-ratio: 24 / 33;
|
|
391
|
+
}
|
|
392
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(2n) {
|
|
393
|
+
width: calc(67.6% - 4px); aspect-ratio: 49.33 / 33;
|
|
394
|
+
}
|
|
395
|
+
/* triple:左大图(66.5%, 1:1) + 右列两张小图 */
|
|
396
|
+
.universal-card-img-combination--triple .universal-card-img-combination__left {
|
|
397
|
+
width: 66.5%; aspect-ratio: 1; margin-right: 1%;
|
|
398
|
+
}
|
|
399
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right {
|
|
400
|
+
width: 33%; display: flex; flex-direction: column; justify-content: space-between;
|
|
401
|
+
}
|
|
402
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item {
|
|
403
|
+
width: 100%; aspect-ratio: 1;
|
|
404
|
+
}
|
|
405
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item:first-child {
|
|
406
|
+
margin-bottom: 1.5%;
|
|
407
|
+
}
|
|
408
|
+
/* bisect / trisect:等宽方格换行 */
|
|
409
|
+
.universal-card-img-combination--bisect { flex-wrap: wrap; gap: 4px; }
|
|
410
|
+
.universal-card-img-combination--bisect .universal-card-img-combination__item {
|
|
411
|
+
width: calc(50% - 2px); aspect-ratio: 1;
|
|
412
|
+
}
|
|
413
|
+
.universal-card-img-combination--trisect { flex-wrap: wrap; justify-content: flex-start; gap: 4px; }
|
|
414
|
+
.universal-card-img-combination--trisect .universal-card-img-combination__item {
|
|
415
|
+
width: calc(33.33% - 2.67px); aspect-ratio: 1;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* ---- select_img 多图选择(对齐网页版 .universal-card-select-img) ---- */
|
|
419
|
+
.universal-card-select-img {
|
|
420
|
+
width: 100%; max-width: 100%; display: grid; grid-gap: 4px; box-sizing: border-box;
|
|
421
|
+
}
|
|
422
|
+
.universal-card-select-img--stretch { grid-template-columns: 1fr; }
|
|
423
|
+
.universal-card-select-img--bisect { grid-template-columns: 1fr 1fr; }
|
|
424
|
+
.universal-card-select-img--trisect { grid-template-columns: 1fr 1fr 1fr; }
|
|
425
|
+
.universal-card-select-img__item-wrapper { position: relative; border-radius: 6px; }
|
|
426
|
+
.universal-card-select-img__item-wrapper::after {
|
|
427
|
+
content: " "; position: absolute; inset: 0; box-sizing: border-box;
|
|
428
|
+
border: 1px solid var(--N300); border-radius: 6px; pointer-events: none; z-index: 1;
|
|
429
|
+
}
|
|
430
|
+
.universal-card-select-img__item-wrapper--selected::after { border: 2px solid var(--B500); }
|
|
431
|
+
.universal-card-select-img__item {
|
|
432
|
+
position: relative; overflow: hidden; box-sizing: border-box; border-radius: 6px;
|
|
433
|
+
cursor: pointer; width: 100%;
|
|
434
|
+
}
|
|
435
|
+
.universal-card-select-img__item--disabled { cursor: not-allowed; }
|
|
436
|
+
.universal-card-select-img__item--disabled::after {
|
|
437
|
+
content: " "; position: absolute; inset: 0; z-index: 1;
|
|
438
|
+
background-color: rgba(255, 255, 255, .5);
|
|
439
|
+
}
|
|
440
|
+
.universal-card-select-img__item > .universal-card-image__host {
|
|
441
|
+
display: block; width: 100%; height: 100%; object-fit: cover;
|
|
442
|
+
}
|
|
443
|
+
.universal-card-select-img__item > .universal-card-image__placeholder {
|
|
444
|
+
width: 100%; height: 100%;
|
|
445
|
+
}
|
|
446
|
+
/* 表单内复选/单选标记(真机仅 in-form 显示;表单外用选中描边表达状态) */
|
|
447
|
+
.universal-card-select-img__checkbox {
|
|
448
|
+
position: absolute; top: 0; right: 0; z-index: 2; padding: 5px 8px; cursor: pointer;
|
|
449
|
+
}
|
|
450
|
+
.universal-card-select-img__checkbox--disabled { cursor: not-allowed; }
|
|
451
|
+
.universal-card-select-img__checkbox-box {
|
|
452
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
453
|
+
width: 16px; height: 16px; box-sizing: border-box; border-radius: 50%;
|
|
454
|
+
background-color: rgba(0, 0, 0, .15); border: 1px solid #eff0f1;
|
|
455
|
+
box-shadow: 0 0 2px rgba(0, 0, 0, .1);
|
|
456
|
+
}
|
|
457
|
+
.universal-card-select-img__checkbox-box--square { border-radius: 4px; }
|
|
458
|
+
.universal-card-select-img__checkbox-box--checked {
|
|
459
|
+
background-color: var(--B500); border-color: var(--B500);
|
|
460
|
+
}
|
|
461
|
+
.universal-card-select-img__checkbox-box--checked::after {
|
|
462
|
+
content: ""; width: 3.5px; height: 7px;
|
|
463
|
+
border: solid #fff; border-width: 0 2px 2px 0;
|
|
464
|
+
transform: rotate(45deg) translateY(-1px);
|
|
465
|
+
}
|
|
466
|
+
|
|
383
467
|
/* ---- 按钮 ---- */
|
|
384
468
|
/* 飞书按钮文本是纯文本、单行:min-height 容纳偶发换行,文字超长省略号收尾。
|
|
385
469
|
样式全集逆向自网页版 ud__button:三大族——outlined(描边)/ text(纯文字)/ filled(实心),
|
|
@@ -623,10 +707,32 @@
|
|
|
623
707
|
}
|
|
624
708
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
625
709
|
.universal-card-collapsible-panel__header::marker { content: ''; }
|
|
710
|
+
/* header.vertical_align:center(默认)/ top / bottom */
|
|
711
|
+
.universal-card-collapsible-panel__header--valign-top { align-items: flex-start; }
|
|
712
|
+
.universal-card-collapsible-panel__header--valign-bottom { align-items: flex-end; }
|
|
713
|
+
/* header.width:fill(默认,撑满整行)/ auto(自适应内容宽)/
|
|
714
|
+
auto_when_fold(折叠自适应、展开撑满——真机语义) */
|
|
715
|
+
.universal-card-collapsible-panel__header--w-auto,
|
|
716
|
+
.universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
717
|
+
width: max-content; max-width: 100%;
|
|
718
|
+
}
|
|
719
|
+
.universal-card-collapsible-panel[open] > .universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
720
|
+
width: 100%;
|
|
721
|
+
}
|
|
626
722
|
.universal-card-collapsible-panel__title {
|
|
627
723
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
628
724
|
word-break: break-word;
|
|
629
725
|
}
|
|
726
|
+
/* title ↔ expanded_title:有 expanded_title 时,折叠展示 title、展开展示 expanded_title
|
|
727
|
+
(真机语义)。纯 CSS 由 details[open] 驱动,不学要 JS 同步。 */
|
|
728
|
+
.universal-card-collapsible-panel__title-text { display: block; }
|
|
729
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
730
|
+
.universal-card-collapsible-panel__title-text--expanded { display: none; }
|
|
731
|
+
.universal-card-collapsible-panel[open]
|
|
732
|
+
.universal-card-collapsible-panel__title--has-expanded .universal-card-collapsible-panel__title-text { display: none; }
|
|
733
|
+
.universal-card-collapsible-panel[open]
|
|
734
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
735
|
+
.universal-card-collapsible-panel__title-text--expanded { display: block; }
|
|
630
736
|
/* follow_text:箭头紧贴文字(真机 __header-content--icon-follow),不拉满整行 */
|
|
631
737
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
632
738
|
gap: 4px;
|
package/dist/index.cjs
CHANGED
|
@@ -850,8 +850,13 @@ function resolveCornerRadius(property) {
|
|
|
850
850
|
}
|
|
851
851
|
if (direct != null) return sizeToPx(direct);
|
|
852
852
|
const echo = property.cornerRadiusValue;
|
|
853
|
-
if (
|
|
854
|
-
if (
|
|
853
|
+
if (typeof echo === "number") return echo + "px";
|
|
854
|
+
if (typeof echo === "string" && echo.trim()) return sizeToPx(echo);
|
|
855
|
+
if (echo && typeof echo === "object") {
|
|
856
|
+
const value = echo.value;
|
|
857
|
+
if (typeof value === "number") return value + "px";
|
|
858
|
+
if (typeof value === "string" && value.trim()) return sizeToPx(value);
|
|
859
|
+
}
|
|
855
860
|
return void 0;
|
|
856
861
|
}
|
|
857
862
|
function boxToStyle(box) {
|
|
@@ -1352,6 +1357,90 @@ var BASE_STYLES_CSS = `/**
|
|
|
1352
1357
|
font-size: 12px;
|
|
1353
1358
|
}
|
|
1354
1359
|
|
|
1360
|
+
/* ---- img_combination \u591A\u56FE\u6DF7\u6392\uFF08\u6BD4\u4F8B\u9006\u5411\u81EA\u7F51\u9875\u7248 .universal-card-img-combination\uFF09 ---- */
|
|
1361
|
+
.universal-card-img-combination { display: flex; width: 100%; justify-content: space-between; }
|
|
1362
|
+
.universal-card-img-combination__item { min-width: 0; overflow: hidden; }
|
|
1363
|
+
.universal-card-img-combination__item > .universal-card-image__host { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
1364
|
+
.universal-card-img-combination__item > .universal-card-image__placeholder { width: 100%; height: 100%; }
|
|
1365
|
+
/* double\uFF1A\u5DE6\u7A84(32.4%, 24:33) + \u53F3\u5BBD(67.6%, 49.33:33) */
|
|
1366
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(odd) {
|
|
1367
|
+
width: 32.4%; aspect-ratio: 24 / 33;
|
|
1368
|
+
}
|
|
1369
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(2n) {
|
|
1370
|
+
width: calc(67.6% - 4px); aspect-ratio: 49.33 / 33;
|
|
1371
|
+
}
|
|
1372
|
+
/* triple\uFF1A\u5DE6\u5927\u56FE(66.5%, 1:1) + \u53F3\u5217\u4E24\u5F20\u5C0F\u56FE */
|
|
1373
|
+
.universal-card-img-combination--triple .universal-card-img-combination__left {
|
|
1374
|
+
width: 66.5%; aspect-ratio: 1; margin-right: 1%;
|
|
1375
|
+
}
|
|
1376
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right {
|
|
1377
|
+
width: 33%; display: flex; flex-direction: column; justify-content: space-between;
|
|
1378
|
+
}
|
|
1379
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item {
|
|
1380
|
+
width: 100%; aspect-ratio: 1;
|
|
1381
|
+
}
|
|
1382
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item:first-child {
|
|
1383
|
+
margin-bottom: 1.5%;
|
|
1384
|
+
}
|
|
1385
|
+
/* bisect / trisect\uFF1A\u7B49\u5BBD\u65B9\u683C\u6362\u884C */
|
|
1386
|
+
.universal-card-img-combination--bisect { flex-wrap: wrap; gap: 4px; }
|
|
1387
|
+
.universal-card-img-combination--bisect .universal-card-img-combination__item {
|
|
1388
|
+
width: calc(50% - 2px); aspect-ratio: 1;
|
|
1389
|
+
}
|
|
1390
|
+
.universal-card-img-combination--trisect { flex-wrap: wrap; justify-content: flex-start; gap: 4px; }
|
|
1391
|
+
.universal-card-img-combination--trisect .universal-card-img-combination__item {
|
|
1392
|
+
width: calc(33.33% - 2.67px); aspect-ratio: 1;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
/* ---- select_img \u591A\u56FE\u9009\u62E9\uFF08\u5BF9\u9F50\u7F51\u9875\u7248 .universal-card-select-img\uFF09 ---- */
|
|
1396
|
+
.universal-card-select-img {
|
|
1397
|
+
width: 100%; max-width: 100%; display: grid; grid-gap: 4px; box-sizing: border-box;
|
|
1398
|
+
}
|
|
1399
|
+
.universal-card-select-img--stretch { grid-template-columns: 1fr; }
|
|
1400
|
+
.universal-card-select-img--bisect { grid-template-columns: 1fr 1fr; }
|
|
1401
|
+
.universal-card-select-img--trisect { grid-template-columns: 1fr 1fr 1fr; }
|
|
1402
|
+
.universal-card-select-img__item-wrapper { position: relative; border-radius: 6px; }
|
|
1403
|
+
.universal-card-select-img__item-wrapper::after {
|
|
1404
|
+
content: " "; position: absolute; inset: 0; box-sizing: border-box;
|
|
1405
|
+
border: 1px solid var(--N300); border-radius: 6px; pointer-events: none; z-index: 1;
|
|
1406
|
+
}
|
|
1407
|
+
.universal-card-select-img__item-wrapper--selected::after { border: 2px solid var(--B500); }
|
|
1408
|
+
.universal-card-select-img__item {
|
|
1409
|
+
position: relative; overflow: hidden; box-sizing: border-box; border-radius: 6px;
|
|
1410
|
+
cursor: pointer; width: 100%;
|
|
1411
|
+
}
|
|
1412
|
+
.universal-card-select-img__item--disabled { cursor: not-allowed; }
|
|
1413
|
+
.universal-card-select-img__item--disabled::after {
|
|
1414
|
+
content: " "; position: absolute; inset: 0; z-index: 1;
|
|
1415
|
+
background-color: rgba(255, 255, 255, .5);
|
|
1416
|
+
}
|
|
1417
|
+
.universal-card-select-img__item > .universal-card-image__host {
|
|
1418
|
+
display: block; width: 100%; height: 100%; object-fit: cover;
|
|
1419
|
+
}
|
|
1420
|
+
.universal-card-select-img__item > .universal-card-image__placeholder {
|
|
1421
|
+
width: 100%; height: 100%;
|
|
1422
|
+
}
|
|
1423
|
+
/* \u8868\u5355\u5185\u590D\u9009/\u5355\u9009\u6807\u8BB0\uFF08\u771F\u673A\u4EC5 in-form \u663E\u793A\uFF1B\u8868\u5355\u5916\u7528\u9009\u4E2D\u63CF\u8FB9\u8868\u8FBE\u72B6\u6001\uFF09 */
|
|
1424
|
+
.universal-card-select-img__checkbox {
|
|
1425
|
+
position: absolute; top: 0; right: 0; z-index: 2; padding: 5px 8px; cursor: pointer;
|
|
1426
|
+
}
|
|
1427
|
+
.universal-card-select-img__checkbox--disabled { cursor: not-allowed; }
|
|
1428
|
+
.universal-card-select-img__checkbox-box {
|
|
1429
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
1430
|
+
width: 16px; height: 16px; box-sizing: border-box; border-radius: 50%;
|
|
1431
|
+
background-color: rgba(0, 0, 0, .15); border: 1px solid #eff0f1;
|
|
1432
|
+
box-shadow: 0 0 2px rgba(0, 0, 0, .1);
|
|
1433
|
+
}
|
|
1434
|
+
.universal-card-select-img__checkbox-box--square { border-radius: 4px; }
|
|
1435
|
+
.universal-card-select-img__checkbox-box--checked {
|
|
1436
|
+
background-color: var(--B500); border-color: var(--B500);
|
|
1437
|
+
}
|
|
1438
|
+
.universal-card-select-img__checkbox-box--checked::after {
|
|
1439
|
+
content: ""; width: 3.5px; height: 7px;
|
|
1440
|
+
border: solid #fff; border-width: 0 2px 2px 0;
|
|
1441
|
+
transform: rotate(45deg) translateY(-1px);
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1355
1444
|
/* ---- \u6309\u94AE ---- */
|
|
1356
1445
|
/* \u98DE\u4E66\u6309\u94AE\u6587\u672C\u662F\u7EAF\u6587\u672C\u3001\u5355\u884C\uFF1Amin-height \u5BB9\u7EB3\u5076\u53D1\u6362\u884C\uFF0C\u6587\u5B57\u8D85\u957F\u7701\u7565\u53F7\u6536\u5C3E\u3002
|
|
1357
1446
|
\u6837\u5F0F\u5168\u96C6\u9006\u5411\u81EA\u7F51\u9875\u7248 ud__button\uFF1A\u4E09\u5927\u65CF\u2014\u2014outlined\uFF08\u63CF\u8FB9\uFF09/ text\uFF08\u7EAF\u6587\u5B57\uFF09/ filled\uFF08\u5B9E\u5FC3\uFF09\uFF0C
|
|
@@ -1595,10 +1684,32 @@ var BASE_STYLES_CSS = `/**
|
|
|
1595
1684
|
}
|
|
1596
1685
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
1597
1686
|
.universal-card-collapsible-panel__header::marker { content: ''; }
|
|
1687
|
+
/* header.vertical_align\uFF1Acenter\uFF08\u9ED8\u8BA4\uFF09/ top / bottom */
|
|
1688
|
+
.universal-card-collapsible-panel__header--valign-top { align-items: flex-start; }
|
|
1689
|
+
.universal-card-collapsible-panel__header--valign-bottom { align-items: flex-end; }
|
|
1690
|
+
/* header.width\uFF1Afill\uFF08\u9ED8\u8BA4\uFF0C\u6491\u6EE1\u6574\u884C\uFF09/ auto\uFF08\u81EA\u9002\u5E94\u5185\u5BB9\u5BBD\uFF09/
|
|
1691
|
+
auto_when_fold\uFF08\u6298\u53E0\u81EA\u9002\u5E94\u3001\u5C55\u5F00\u6491\u6EE1\u2014\u2014\u771F\u673A\u8BED\u4E49\uFF09 */
|
|
1692
|
+
.universal-card-collapsible-panel__header--w-auto,
|
|
1693
|
+
.universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
1694
|
+
width: max-content; max-width: 100%;
|
|
1695
|
+
}
|
|
1696
|
+
.universal-card-collapsible-panel[open] > .universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
1697
|
+
width: 100%;
|
|
1698
|
+
}
|
|
1598
1699
|
.universal-card-collapsible-panel__title {
|
|
1599
1700
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
1600
1701
|
word-break: break-word;
|
|
1601
1702
|
}
|
|
1703
|
+
/* title \u2194 expanded_title\uFF1A\u6709 expanded_title \u65F6\uFF0C\u6298\u53E0\u5C55\u793A title\u3001\u5C55\u5F00\u5C55\u793A expanded_title
|
|
1704
|
+
\uFF08\u771F\u673A\u8BED\u4E49\uFF09\u3002\u7EAF CSS \u7531 details[open] \u9A71\u52A8\uFF0C\u4E0D\u5B66\u8981 JS \u540C\u6B65\u3002 */
|
|
1705
|
+
.universal-card-collapsible-panel__title-text { display: block; }
|
|
1706
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
1707
|
+
.universal-card-collapsible-panel__title-text--expanded { display: none; }
|
|
1708
|
+
.universal-card-collapsible-panel[open]
|
|
1709
|
+
.universal-card-collapsible-panel__title--has-expanded .universal-card-collapsible-panel__title-text { display: none; }
|
|
1710
|
+
.universal-card-collapsible-panel[open]
|
|
1711
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
1712
|
+
.universal-card-collapsible-panel__title-text--expanded { display: block; }
|
|
1602
1713
|
/* follow_text\uFF1A\u7BAD\u5934\u7D27\u8D34\u6587\u5B57\uFF08\u771F\u673A __header-content--icon-follow\uFF09\uFF0C\u4E0D\u62C9\u6EE1\u6574\u884C */
|
|
1603
1714
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
1604
1715
|
gap: 4px;
|
|
@@ -5855,6 +5966,8 @@ function registerBuiltins() {
|
|
|
5855
5966
|
}
|
|
5856
5967
|
return h("div", { className: `${CLS}-div` }, content);
|
|
5857
5968
|
});
|
|
5969
|
+
const H_ALIGN_MAP = { left: "flex-start", center: "center", right: "flex-end" };
|
|
5970
|
+
const V_ALIGN_MAP = { top: "flex-start", center: "center", bottom: "flex-end" };
|
|
5858
5971
|
registerComponent("column_set", (el, ctx) => {
|
|
5859
5972
|
const p = el.property || {};
|
|
5860
5973
|
const gapRaw = p.horizontalSpacingValue?.value ?? p.horizontal_spacing;
|
|
@@ -5869,7 +5982,7 @@ function registerBuiltins() {
|
|
|
5869
5982
|
columnGap: gap + "px"
|
|
5870
5983
|
};
|
|
5871
5984
|
if (hAlign) {
|
|
5872
|
-
style.justifyContent =
|
|
5985
|
+
style.justifyContent = H_ALIGN_MAP[hAlign] || "flex-start";
|
|
5873
5986
|
}
|
|
5874
5987
|
applyOuterMargin(style, p.margin);
|
|
5875
5988
|
const bg = propertyBackgroundColor(p);
|
|
@@ -5904,6 +6017,7 @@ function registerBuiltins() {
|
|
|
5904
6017
|
flexShrink: 1,
|
|
5905
6018
|
overflow: "hidden",
|
|
5906
6019
|
display: "flex",
|
|
6020
|
+
// 缺省纵向排列;direction=horizontal 时改行,两个 align 落到哪个 flex 属性也随之交换
|
|
5907
6021
|
flexDirection: "column"
|
|
5908
6022
|
};
|
|
5909
6023
|
const wv = p.widthValue;
|
|
@@ -5939,10 +6053,16 @@ function registerBuiltins() {
|
|
|
5939
6053
|
style.flexBasis = "auto";
|
|
5940
6054
|
}
|
|
5941
6055
|
}
|
|
5942
|
-
const
|
|
5943
|
-
if (
|
|
5944
|
-
|
|
5945
|
-
|
|
6056
|
+
const horizontalDir = p.direction === "horizontal";
|
|
6057
|
+
if (horizontalDir) style.flexDirection = "row";
|
|
6058
|
+
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6059
|
+
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6060
|
+
const justify = horizontalDir ? H_ALIGN_MAP[hAlign] : V_ALIGN_MAP[vAlign];
|
|
6061
|
+
const align = horizontalDir ? V_ALIGN_MAP[vAlign] : H_ALIGN_MAP[hAlign];
|
|
6062
|
+
if (justify) style.justifyContent = justify;
|
|
6063
|
+
if (align) style.alignItems = align;
|
|
6064
|
+
const hGap = p.horizontalSpacingValue?.value ?? p.horizontal_spacing ?? p.horizontalSpacing;
|
|
6065
|
+
if (hGap != null) style.columnGap = horizontalSpacingToPx(hGap) + "px";
|
|
5946
6066
|
const vGap = p.verticalSpacingValue?.value ?? p.vertical_spacing;
|
|
5947
6067
|
style.rowGap = (vGap != null ? verticalSpacingToPx(vGap) : 8) + "px";
|
|
5948
6068
|
const bg = propertyBackgroundColor(p);
|
|
@@ -5988,6 +6108,123 @@ function registerBuiltins() {
|
|
|
5988
6108
|
src ? h("img", { className: `${CLS}-image__host`, src, alt: altText, style: imgStyle }) : h("div", { className: `${CLS}-image__placeholder`, style: imgStyle }, altText || "[\u56FE\u7247]")
|
|
5989
6109
|
);
|
|
5990
6110
|
});
|
|
6111
|
+
const IMG_COMBINATION_LIMIT = {
|
|
6112
|
+
double: 2,
|
|
6113
|
+
triple: 3
|
|
6114
|
+
};
|
|
6115
|
+
function renderCombinationImage(item, cornerRadius, ctx) {
|
|
6116
|
+
const src = resolveImageSrc(item, ctx);
|
|
6117
|
+
const style = {
|
|
6118
|
+
width: "100%",
|
|
6119
|
+
height: "100%",
|
|
6120
|
+
objectFit: "cover",
|
|
6121
|
+
display: "block"
|
|
6122
|
+
};
|
|
6123
|
+
if (cornerRadius) style.borderRadius = cornerRadius;
|
|
6124
|
+
return src ? h("img", { className: `${CLS}-image__host`, src, alt: "", style }) : h("div", { className: `${CLS}-image__placeholder`, style }, "[\u56FE\u7247]");
|
|
6125
|
+
}
|
|
6126
|
+
registerComponent("img_combination", (el, ctx) => {
|
|
6127
|
+
const p = el.property || {};
|
|
6128
|
+
const rawList = Array.isArray(p.imgList) ? p.imgList : Array.isArray(p.img_list) ? p.img_list : [];
|
|
6129
|
+
if (rawList.length === 0) return null;
|
|
6130
|
+
const mode = String(p.combinationMode ?? p.combination_mode ?? "double");
|
|
6131
|
+
const limit = IMG_COMBINATION_LIMIT[mode];
|
|
6132
|
+
const list = (limit ? rawList.slice(0, limit) : rawList).map((item) => typeof item === "string" ? { img_key: item } : item).filter(isRecord);
|
|
6133
|
+
if (list.length === 0) return null;
|
|
6134
|
+
const cornerRadius = resolveCornerRadius(p);
|
|
6135
|
+
const containerStyle = {};
|
|
6136
|
+
applyOuterMargin(containerStyle, p.margin);
|
|
6137
|
+
const cls = `${CLS}-img-combination ${CLS}-img-combination--${mode}`;
|
|
6138
|
+
const itemNode = (item) => h(
|
|
6139
|
+
"div",
|
|
6140
|
+
{ className: `${CLS}-img-combination__item` },
|
|
6141
|
+
renderCombinationImage(item, cornerRadius, ctx)
|
|
6142
|
+
);
|
|
6143
|
+
if (mode === "triple") {
|
|
6144
|
+
const [first, ...rest] = list;
|
|
6145
|
+
return h(
|
|
6146
|
+
"div",
|
|
6147
|
+
{ className: cls, style: containerStyle },
|
|
6148
|
+
h(
|
|
6149
|
+
"div",
|
|
6150
|
+
{ className: `${CLS}-img-combination__item ${CLS}-img-combination__left` },
|
|
6151
|
+
renderCombinationImage(first, cornerRadius, ctx)
|
|
6152
|
+
),
|
|
6153
|
+
h("div", { className: `${CLS}-img-combination__right` }, rest.map(itemNode))
|
|
6154
|
+
);
|
|
6155
|
+
}
|
|
6156
|
+
return h("div", { className: cls, style: containerStyle }, list.map(itemNode));
|
|
6157
|
+
});
|
|
6158
|
+
function readSelectImgValues(p) {
|
|
6159
|
+
const raw = p.selectedValues ?? p.selected_values ?? p.value;
|
|
6160
|
+
let value = raw;
|
|
6161
|
+
if (typeof value === "string") {
|
|
6162
|
+
try {
|
|
6163
|
+
value = JSON.parse(value);
|
|
6164
|
+
} catch {
|
|
6165
|
+
return typeof value === "string" && value ? [value] : [];
|
|
6166
|
+
}
|
|
6167
|
+
}
|
|
6168
|
+
if (isRecord(value) && Array.isArray(value.value)) value = value.value;
|
|
6169
|
+
if (!Array.isArray(value)) return [];
|
|
6170
|
+
return value.filter((item) => typeof item === "string");
|
|
6171
|
+
}
|
|
6172
|
+
function renderSelectImgCheckbox(checked, disabled, multiple) {
|
|
6173
|
+
const boxClass = `${CLS}-select-img__checkbox-box` + (multiple ? ` ${CLS}-select-img__checkbox-box--square` : "") + (checked ? ` ${CLS}-select-img__checkbox-box--checked` : "");
|
|
6174
|
+
return h(
|
|
6175
|
+
"div",
|
|
6176
|
+
{
|
|
6177
|
+
className: `${CLS}-select-img__checkbox` + (disabled ? ` ${CLS}-select-img__checkbox--disabled` : "")
|
|
6178
|
+
},
|
|
6179
|
+
h("span", { className: boxClass })
|
|
6180
|
+
);
|
|
6181
|
+
}
|
|
6182
|
+
registerComponent("select_img", (el, ctx) => {
|
|
6183
|
+
const p = el.property || {};
|
|
6184
|
+
const options = Array.isArray(p.options) ? p.options : [];
|
|
6185
|
+
if (options.length === 0) return null;
|
|
6186
|
+
const layout = String(p.layout ?? "bisect");
|
|
6187
|
+
const aspectRatio = String(p.aspectRatio ?? p.aspect_ratio ?? "16:9").replace(":", "/");
|
|
6188
|
+
const multiple = p.multiSelect === true || p.multi_select === true;
|
|
6189
|
+
const disabledAll = p.disabled === true;
|
|
6190
|
+
const selected = readSelectImgValues(p);
|
|
6191
|
+
const containerStyle = {};
|
|
6192
|
+
applyOuterMargin(containerStyle, p.margin);
|
|
6193
|
+
const items = options.map((rawOption) => {
|
|
6194
|
+
const option = isRecord(rawOption) ? rawOption : { img_key: rawOption };
|
|
6195
|
+
const value = typeof option.value === "string" ? option.value : void 0;
|
|
6196
|
+
const isSelected = value !== void 0 && selected.includes(value);
|
|
6197
|
+
const disabled = disabledAll || option.disabled === true;
|
|
6198
|
+
const tip = disabled ? extractText(option.disabled_tips ?? option.disabledTips) : extractText(option.hover_tips ?? option.hoverTips);
|
|
6199
|
+
const src = resolveImageSrc(option, ctx);
|
|
6200
|
+
const wrapperClass = `${CLS}-select-img__item-wrapper` + (isSelected ? ` ${CLS}-select-img__item-wrapper--selected` : "") + (disabled ? ` ${CLS}-select-img__item-wrapper--disabled` : "");
|
|
6201
|
+
const itemClass = `${CLS}-select-img__item` + (disabled ? ` ${CLS}-select-img__item--disabled` : "");
|
|
6202
|
+
return h(
|
|
6203
|
+
"div",
|
|
6204
|
+
{ className: wrapperClass },
|
|
6205
|
+
h(
|
|
6206
|
+
"div",
|
|
6207
|
+
{ className: itemClass, style: { aspectRatio }, title: tip || void 0 },
|
|
6208
|
+
ctx.inForm ? renderSelectImgCheckbox(isSelected, disabled, multiple) : null,
|
|
6209
|
+
src ? h("img", {
|
|
6210
|
+
className: `${CLS}-image__host`,
|
|
6211
|
+
src,
|
|
6212
|
+
alt: "",
|
|
6213
|
+
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
6214
|
+
}) : h(
|
|
6215
|
+
"div",
|
|
6216
|
+
{ className: `${CLS}-image__placeholder`, style: { width: "100%", height: "100%" } },
|
|
6217
|
+
"[\u56FE\u7247]"
|
|
6218
|
+
)
|
|
6219
|
+
)
|
|
6220
|
+
);
|
|
6221
|
+
});
|
|
6222
|
+
return h(
|
|
6223
|
+
"div",
|
|
6224
|
+
{ className: `${CLS}-select-img ${CLS}-select-img--${layout}`, style: containerStyle },
|
|
6225
|
+
items
|
|
6226
|
+
);
|
|
6227
|
+
});
|
|
5991
6228
|
registerComponent("video", (el, ctx) => {
|
|
5992
6229
|
const p = el.property || {};
|
|
5993
6230
|
const src = resolveMediaSrc(p, "video", ctx);
|
|
@@ -6156,10 +6393,8 @@ function registerBuiltins() {
|
|
|
6156
6393
|
if (horizontalDir) style.flexDirection = "row";
|
|
6157
6394
|
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6158
6395
|
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6159
|
-
const
|
|
6160
|
-
const
|
|
6161
|
-
const justify = horizontalDir ? H_ALIGN[hAlign] : V_ALIGN[vAlign];
|
|
6162
|
-
const align = horizontalDir ? V_ALIGN[vAlign] : H_ALIGN[hAlign];
|
|
6396
|
+
const justify = horizontalDir ? H_ALIGN_MAP[hAlign] : V_ALIGN_MAP[vAlign];
|
|
6397
|
+
const align = horizontalDir ? V_ALIGN_MAP[vAlign] : H_ALIGN_MAP[hAlign];
|
|
6163
6398
|
if (justify) style.justifyContent = justify;
|
|
6164
6399
|
if (align) style.alignItems = align;
|
|
6165
6400
|
const hGap = p.horizontalSpacingValue?.value ?? p.horizontal_spacing ?? p.horizontalSpacing;
|
|
@@ -6186,7 +6421,7 @@ function registerBuiltins() {
|
|
|
6186
6421
|
registerComponent("collapsible_panel", (el, ctx) => {
|
|
6187
6422
|
const p = el.property || {};
|
|
6188
6423
|
const hdr = p.header && typeof p.header === "object" ? p.header : {};
|
|
6189
|
-
const expanded = p.expanded
|
|
6424
|
+
const expanded = p.expanded === true;
|
|
6190
6425
|
const style = { width: "100%" };
|
|
6191
6426
|
const bgRaw = p.background_color ?? p.backgroundColor;
|
|
6192
6427
|
const bgCustom = propertyBackgroundColor(p);
|
|
@@ -6205,12 +6440,36 @@ function registerBuiltins() {
|
|
|
6205
6440
|
} else {
|
|
6206
6441
|
style.borderRadius = "8px";
|
|
6207
6442
|
}
|
|
6443
|
+
const headerBottom = String(hdr.position ?? "top") === "bottom";
|
|
6444
|
+
if (headerBottom) {
|
|
6445
|
+
style.display = "flex";
|
|
6446
|
+
style.flexDirection = "column";
|
|
6447
|
+
}
|
|
6208
6448
|
applyOuterMargin(style, p.margin);
|
|
6209
6449
|
const headerStyle = {};
|
|
6210
6450
|
const hpad = typeof hdr.padding === "string" ? hdr.padding : boxToStyle(hdr.padding);
|
|
6211
6451
|
if (hpad) headerStyle.padding = hpad;
|
|
6212
|
-
const
|
|
6213
|
-
|
|
6452
|
+
const hbg = resolveColor(hdr.background_color ?? hdr.backgroundColor);
|
|
6453
|
+
if (hbg) headerStyle.background = hbg;
|
|
6454
|
+
if (headerBottom) headerStyle.order = "2";
|
|
6455
|
+
const titleLeaf = (raw, className) => {
|
|
6456
|
+
if (!raw || typeof raw !== "object") return null;
|
|
6457
|
+
const t = raw;
|
|
6458
|
+
if (typeof t.tag !== "string") return null;
|
|
6459
|
+
const property = t.property && typeof t.property === "object" ? t.property : t;
|
|
6460
|
+
const node = renderHeaderTextLeaf({ tag: t.tag, property }, ctx, className);
|
|
6461
|
+
if (node) return node;
|
|
6462
|
+
const text = extractPlainText(raw) || extractText(raw);
|
|
6463
|
+
return text ? h("div", { className }, text) : null;
|
|
6464
|
+
};
|
|
6465
|
+
const primaryTitle = titleLeaf(hdr.title, `${CLS}-collapsible-panel__title-text`);
|
|
6466
|
+
const expandedTitleRaw = hdr.expanded_title ?? hdr.expandedTitle;
|
|
6467
|
+
const expandedTitle = titleLeaf(
|
|
6468
|
+
expandedTitleRaw,
|
|
6469
|
+
`${CLS}-collapsible-panel__title-text ${CLS}-collapsible-panel__title-text--expanded`
|
|
6470
|
+
);
|
|
6471
|
+
const titleCls = `${CLS}-collapsible-panel__title` + (expandedTitle ? ` ${CLS}-collapsible-panel__title--has-expanded` : "");
|
|
6472
|
+
const titleVNode = h("div", { className: titleCls }, [primaryTitle, expandedTitle].filter(Boolean));
|
|
6214
6473
|
let iconVNode = null;
|
|
6215
6474
|
const iconRaw = hdr.icon;
|
|
6216
6475
|
const openAngle = Number(hdr.icon_expanded_angle ?? hdr.iconExpandedAngle ?? -180);
|
|
@@ -6226,11 +6485,38 @@ function registerBuiltins() {
|
|
|
6226
6485
|
const iconFollow = iconPos === "follow_text" || iconPos === "followText";
|
|
6227
6486
|
const headerChildren = iconLeft ? [iconVNode, titleVNode] : [titleVNode, iconVNode];
|
|
6228
6487
|
const summaryStyle = { ...headerStyle, "--panel-icon-angle": `${openAngle}deg` };
|
|
6229
|
-
const
|
|
6488
|
+
const headerWidth = String(hdr.width ?? hdr.headerWidth ?? "fill");
|
|
6489
|
+
const headerVAlign = String(hdr.vertical_align ?? hdr.verticalAlign ?? "center");
|
|
6490
|
+
const headerCls = `${CLS}-collapsible-panel__header` + (iconFollow ? ` ${CLS}-collapsible-panel__header--icon-follow` : "") + (headerWidth === "auto" ? ` ${CLS}-collapsible-panel__header--w-auto` : "") + (headerWidth === "auto_when_fold" ? ` ${CLS}-collapsible-panel__header--w-auto-when-fold` : "") + (headerVAlign === "top" ? ` ${CLS}-collapsible-panel__header--valign-top` : "") + (headerVAlign === "bottom" ? ` ${CLS}-collapsible-panel__header--valign-bottom` : "");
|
|
6230
6491
|
const summary = h("summary", { className: headerCls, style: summaryStyle }, headerChildren);
|
|
6231
6492
|
const contentStyle = {};
|
|
6232
6493
|
const cpad = typeof p.padding === "string" ? p.padding : boxToStyle(p.padding);
|
|
6233
6494
|
if (cpad) contentStyle.padding = cpad;
|
|
6495
|
+
if (headerBottom) contentStyle.order = "1";
|
|
6496
|
+
const direction = String(p.direction ?? "vertical");
|
|
6497
|
+
const isRow = direction === "horizontal";
|
|
6498
|
+
const hSpacing = p.horizontal_spacing ?? p.horizontalSpacing;
|
|
6499
|
+
const vSpacing = p.vertical_spacing ?? p.verticalSpacing;
|
|
6500
|
+
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6501
|
+
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6502
|
+
if (isRow || hSpacing != null || vSpacing != null || hAlign != null || vAlign != null) {
|
|
6503
|
+
contentStyle.display = "flex";
|
|
6504
|
+
contentStyle.flexDirection = isRow ? "row" : "column";
|
|
6505
|
+
const gapX = hSpacing != null ? horizontalSpacingToPx(hSpacing) : isRow ? 8 : 0;
|
|
6506
|
+
const gapY = vSpacing != null ? verticalSpacingToPx(vSpacing) : 0;
|
|
6507
|
+
if (gapX) contentStyle.columnGap = gapX + "px";
|
|
6508
|
+
if (gapY) contentStyle.rowGap = gapY + "px";
|
|
6509
|
+
const hVal = hAlign ? H_ALIGN_MAP[hAlign] : void 0;
|
|
6510
|
+
const vVal = vAlign ? V_ALIGN_MAP[vAlign] : void 0;
|
|
6511
|
+
if (hVal) {
|
|
6512
|
+
if (isRow) contentStyle.justifyContent = hVal;
|
|
6513
|
+
else contentStyle.alignItems = hVal;
|
|
6514
|
+
}
|
|
6515
|
+
if (vVal) {
|
|
6516
|
+
if (isRow) contentStyle.alignItems = vVal;
|
|
6517
|
+
else contentStyle.justifyContent = vVal;
|
|
6518
|
+
}
|
|
6519
|
+
}
|
|
6234
6520
|
const content = h(
|
|
6235
6521
|
"div",
|
|
6236
6522
|
{ className: `${CLS}-collapsible-panel__content`, style: contentStyle },
|
|
@@ -6363,7 +6649,7 @@ function registerBuiltins() {
|
|
|
6363
6649
|
);
|
|
6364
6650
|
});
|
|
6365
6651
|
registerComponent("form", (el, ctx) => {
|
|
6366
|
-
const children = renderElements(el.property?.elements, ctx);
|
|
6652
|
+
const children = renderElements(el.property?.elements, { ...ctx, inForm: true });
|
|
6367
6653
|
const className = `${CLS}-form`;
|
|
6368
6654
|
if (!ctx.options.interactive) return h("div", { className }, children);
|
|
6369
6655
|
const name = typeof el.property?.name === "string" ? el.property.name : "";
|
package/dist/index.d.cts
CHANGED
|
@@ -464,6 +464,11 @@ interface RenderContext {
|
|
|
464
464
|
* 客户端把 body paddingTop 从 12 改为 8。由 index.ts 在渲染 body 前注入。
|
|
465
465
|
*/
|
|
466
466
|
bodyPaddingTop?: number;
|
|
467
|
+
/**
|
|
468
|
+
* 是否处于 form 容器内。真机 select_img 仅在表单内显示选中态 checkbox/radio,
|
|
469
|
+
* 表单外只是可点击的图片选项。form 渲染子元素时注入,不改变外部 ctx。
|
|
470
|
+
*/
|
|
471
|
+
inForm?: boolean;
|
|
467
472
|
}
|
|
468
473
|
/** 组件渲染函数 */
|
|
469
474
|
type ComponentFn = (el: CardElement, ctx: RenderContext) => VNode | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -464,6 +464,11 @@ interface RenderContext {
|
|
|
464
464
|
* 客户端把 body paddingTop 从 12 改为 8。由 index.ts 在渲染 body 前注入。
|
|
465
465
|
*/
|
|
466
466
|
bodyPaddingTop?: number;
|
|
467
|
+
/**
|
|
468
|
+
* 是否处于 form 容器内。真机 select_img 仅在表单内显示选中态 checkbox/radio,
|
|
469
|
+
* 表单外只是可点击的图片选项。form 渲染子元素时注入,不改变外部 ctx。
|
|
470
|
+
*/
|
|
471
|
+
inForm?: boolean;
|
|
467
472
|
}
|
|
468
473
|
/** 组件渲染函数 */
|
|
469
474
|
type ComponentFn = (el: CardElement, ctx: RenderContext) => VNode | null;
|
package/dist/index.js
CHANGED
|
@@ -849,8 +849,13 @@ function resolveCornerRadius(property) {
|
|
|
849
849
|
}
|
|
850
850
|
if (direct != null) return sizeToPx(direct);
|
|
851
851
|
const echo = property.cornerRadiusValue;
|
|
852
|
-
if (
|
|
853
|
-
if (
|
|
852
|
+
if (typeof echo === "number") return echo + "px";
|
|
853
|
+
if (typeof echo === "string" && echo.trim()) return sizeToPx(echo);
|
|
854
|
+
if (echo && typeof echo === "object") {
|
|
855
|
+
const value = echo.value;
|
|
856
|
+
if (typeof value === "number") return value + "px";
|
|
857
|
+
if (typeof value === "string" && value.trim()) return sizeToPx(value);
|
|
858
|
+
}
|
|
854
859
|
return void 0;
|
|
855
860
|
}
|
|
856
861
|
function boxToStyle(box) {
|
|
@@ -1351,6 +1356,90 @@ var BASE_STYLES_CSS = `/**
|
|
|
1351
1356
|
font-size: 12px;
|
|
1352
1357
|
}
|
|
1353
1358
|
|
|
1359
|
+
/* ---- img_combination \u591A\u56FE\u6DF7\u6392\uFF08\u6BD4\u4F8B\u9006\u5411\u81EA\u7F51\u9875\u7248 .universal-card-img-combination\uFF09 ---- */
|
|
1360
|
+
.universal-card-img-combination { display: flex; width: 100%; justify-content: space-between; }
|
|
1361
|
+
.universal-card-img-combination__item { min-width: 0; overflow: hidden; }
|
|
1362
|
+
.universal-card-img-combination__item > .universal-card-image__host { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
1363
|
+
.universal-card-img-combination__item > .universal-card-image__placeholder { width: 100%; height: 100%; }
|
|
1364
|
+
/* double\uFF1A\u5DE6\u7A84(32.4%, 24:33) + \u53F3\u5BBD(67.6%, 49.33:33) */
|
|
1365
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(odd) {
|
|
1366
|
+
width: 32.4%; aspect-ratio: 24 / 33;
|
|
1367
|
+
}
|
|
1368
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(2n) {
|
|
1369
|
+
width: calc(67.6% - 4px); aspect-ratio: 49.33 / 33;
|
|
1370
|
+
}
|
|
1371
|
+
/* triple\uFF1A\u5DE6\u5927\u56FE(66.5%, 1:1) + \u53F3\u5217\u4E24\u5F20\u5C0F\u56FE */
|
|
1372
|
+
.universal-card-img-combination--triple .universal-card-img-combination__left {
|
|
1373
|
+
width: 66.5%; aspect-ratio: 1; margin-right: 1%;
|
|
1374
|
+
}
|
|
1375
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right {
|
|
1376
|
+
width: 33%; display: flex; flex-direction: column; justify-content: space-between;
|
|
1377
|
+
}
|
|
1378
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item {
|
|
1379
|
+
width: 100%; aspect-ratio: 1;
|
|
1380
|
+
}
|
|
1381
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item:first-child {
|
|
1382
|
+
margin-bottom: 1.5%;
|
|
1383
|
+
}
|
|
1384
|
+
/* bisect / trisect\uFF1A\u7B49\u5BBD\u65B9\u683C\u6362\u884C */
|
|
1385
|
+
.universal-card-img-combination--bisect { flex-wrap: wrap; gap: 4px; }
|
|
1386
|
+
.universal-card-img-combination--bisect .universal-card-img-combination__item {
|
|
1387
|
+
width: calc(50% - 2px); aspect-ratio: 1;
|
|
1388
|
+
}
|
|
1389
|
+
.universal-card-img-combination--trisect { flex-wrap: wrap; justify-content: flex-start; gap: 4px; }
|
|
1390
|
+
.universal-card-img-combination--trisect .universal-card-img-combination__item {
|
|
1391
|
+
width: calc(33.33% - 2.67px); aspect-ratio: 1;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
/* ---- select_img \u591A\u56FE\u9009\u62E9\uFF08\u5BF9\u9F50\u7F51\u9875\u7248 .universal-card-select-img\uFF09 ---- */
|
|
1395
|
+
.universal-card-select-img {
|
|
1396
|
+
width: 100%; max-width: 100%; display: grid; grid-gap: 4px; box-sizing: border-box;
|
|
1397
|
+
}
|
|
1398
|
+
.universal-card-select-img--stretch { grid-template-columns: 1fr; }
|
|
1399
|
+
.universal-card-select-img--bisect { grid-template-columns: 1fr 1fr; }
|
|
1400
|
+
.universal-card-select-img--trisect { grid-template-columns: 1fr 1fr 1fr; }
|
|
1401
|
+
.universal-card-select-img__item-wrapper { position: relative; border-radius: 6px; }
|
|
1402
|
+
.universal-card-select-img__item-wrapper::after {
|
|
1403
|
+
content: " "; position: absolute; inset: 0; box-sizing: border-box;
|
|
1404
|
+
border: 1px solid var(--N300); border-radius: 6px; pointer-events: none; z-index: 1;
|
|
1405
|
+
}
|
|
1406
|
+
.universal-card-select-img__item-wrapper--selected::after { border: 2px solid var(--B500); }
|
|
1407
|
+
.universal-card-select-img__item {
|
|
1408
|
+
position: relative; overflow: hidden; box-sizing: border-box; border-radius: 6px;
|
|
1409
|
+
cursor: pointer; width: 100%;
|
|
1410
|
+
}
|
|
1411
|
+
.universal-card-select-img__item--disabled { cursor: not-allowed; }
|
|
1412
|
+
.universal-card-select-img__item--disabled::after {
|
|
1413
|
+
content: " "; position: absolute; inset: 0; z-index: 1;
|
|
1414
|
+
background-color: rgba(255, 255, 255, .5);
|
|
1415
|
+
}
|
|
1416
|
+
.universal-card-select-img__item > .universal-card-image__host {
|
|
1417
|
+
display: block; width: 100%; height: 100%; object-fit: cover;
|
|
1418
|
+
}
|
|
1419
|
+
.universal-card-select-img__item > .universal-card-image__placeholder {
|
|
1420
|
+
width: 100%; height: 100%;
|
|
1421
|
+
}
|
|
1422
|
+
/* \u8868\u5355\u5185\u590D\u9009/\u5355\u9009\u6807\u8BB0\uFF08\u771F\u673A\u4EC5 in-form \u663E\u793A\uFF1B\u8868\u5355\u5916\u7528\u9009\u4E2D\u63CF\u8FB9\u8868\u8FBE\u72B6\u6001\uFF09 */
|
|
1423
|
+
.universal-card-select-img__checkbox {
|
|
1424
|
+
position: absolute; top: 0; right: 0; z-index: 2; padding: 5px 8px; cursor: pointer;
|
|
1425
|
+
}
|
|
1426
|
+
.universal-card-select-img__checkbox--disabled { cursor: not-allowed; }
|
|
1427
|
+
.universal-card-select-img__checkbox-box {
|
|
1428
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
1429
|
+
width: 16px; height: 16px; box-sizing: border-box; border-radius: 50%;
|
|
1430
|
+
background-color: rgba(0, 0, 0, .15); border: 1px solid #eff0f1;
|
|
1431
|
+
box-shadow: 0 0 2px rgba(0, 0, 0, .1);
|
|
1432
|
+
}
|
|
1433
|
+
.universal-card-select-img__checkbox-box--square { border-radius: 4px; }
|
|
1434
|
+
.universal-card-select-img__checkbox-box--checked {
|
|
1435
|
+
background-color: var(--B500); border-color: var(--B500);
|
|
1436
|
+
}
|
|
1437
|
+
.universal-card-select-img__checkbox-box--checked::after {
|
|
1438
|
+
content: ""; width: 3.5px; height: 7px;
|
|
1439
|
+
border: solid #fff; border-width: 0 2px 2px 0;
|
|
1440
|
+
transform: rotate(45deg) translateY(-1px);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1354
1443
|
/* ---- \u6309\u94AE ---- */
|
|
1355
1444
|
/* \u98DE\u4E66\u6309\u94AE\u6587\u672C\u662F\u7EAF\u6587\u672C\u3001\u5355\u884C\uFF1Amin-height \u5BB9\u7EB3\u5076\u53D1\u6362\u884C\uFF0C\u6587\u5B57\u8D85\u957F\u7701\u7565\u53F7\u6536\u5C3E\u3002
|
|
1356
1445
|
\u6837\u5F0F\u5168\u96C6\u9006\u5411\u81EA\u7F51\u9875\u7248 ud__button\uFF1A\u4E09\u5927\u65CF\u2014\u2014outlined\uFF08\u63CF\u8FB9\uFF09/ text\uFF08\u7EAF\u6587\u5B57\uFF09/ filled\uFF08\u5B9E\u5FC3\uFF09\uFF0C
|
|
@@ -1594,10 +1683,32 @@ var BASE_STYLES_CSS = `/**
|
|
|
1594
1683
|
}
|
|
1595
1684
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
1596
1685
|
.universal-card-collapsible-panel__header::marker { content: ''; }
|
|
1686
|
+
/* header.vertical_align\uFF1Acenter\uFF08\u9ED8\u8BA4\uFF09/ top / bottom */
|
|
1687
|
+
.universal-card-collapsible-panel__header--valign-top { align-items: flex-start; }
|
|
1688
|
+
.universal-card-collapsible-panel__header--valign-bottom { align-items: flex-end; }
|
|
1689
|
+
/* header.width\uFF1Afill\uFF08\u9ED8\u8BA4\uFF0C\u6491\u6EE1\u6574\u884C\uFF09/ auto\uFF08\u81EA\u9002\u5E94\u5185\u5BB9\u5BBD\uFF09/
|
|
1690
|
+
auto_when_fold\uFF08\u6298\u53E0\u81EA\u9002\u5E94\u3001\u5C55\u5F00\u6491\u6EE1\u2014\u2014\u771F\u673A\u8BED\u4E49\uFF09 */
|
|
1691
|
+
.universal-card-collapsible-panel__header--w-auto,
|
|
1692
|
+
.universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
1693
|
+
width: max-content; max-width: 100%;
|
|
1694
|
+
}
|
|
1695
|
+
.universal-card-collapsible-panel[open] > .universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
1696
|
+
width: 100%;
|
|
1697
|
+
}
|
|
1597
1698
|
.universal-card-collapsible-panel__title {
|
|
1598
1699
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
1599
1700
|
word-break: break-word;
|
|
1600
1701
|
}
|
|
1702
|
+
/* title \u2194 expanded_title\uFF1A\u6709 expanded_title \u65F6\uFF0C\u6298\u53E0\u5C55\u793A title\u3001\u5C55\u5F00\u5C55\u793A expanded_title
|
|
1703
|
+
\uFF08\u771F\u673A\u8BED\u4E49\uFF09\u3002\u7EAF CSS \u7531 details[open] \u9A71\u52A8\uFF0C\u4E0D\u5B66\u8981 JS \u540C\u6B65\u3002 */
|
|
1704
|
+
.universal-card-collapsible-panel__title-text { display: block; }
|
|
1705
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
1706
|
+
.universal-card-collapsible-panel__title-text--expanded { display: none; }
|
|
1707
|
+
.universal-card-collapsible-panel[open]
|
|
1708
|
+
.universal-card-collapsible-panel__title--has-expanded .universal-card-collapsible-panel__title-text { display: none; }
|
|
1709
|
+
.universal-card-collapsible-panel[open]
|
|
1710
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
1711
|
+
.universal-card-collapsible-panel__title-text--expanded { display: block; }
|
|
1601
1712
|
/* follow_text\uFF1A\u7BAD\u5934\u7D27\u8D34\u6587\u5B57\uFF08\u771F\u673A __header-content--icon-follow\uFF09\uFF0C\u4E0D\u62C9\u6EE1\u6574\u884C */
|
|
1602
1713
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
1603
1714
|
gap: 4px;
|
|
@@ -5854,6 +5965,8 @@ function registerBuiltins() {
|
|
|
5854
5965
|
}
|
|
5855
5966
|
return h("div", { className: `${CLS}-div` }, content);
|
|
5856
5967
|
});
|
|
5968
|
+
const H_ALIGN_MAP = { left: "flex-start", center: "center", right: "flex-end" };
|
|
5969
|
+
const V_ALIGN_MAP = { top: "flex-start", center: "center", bottom: "flex-end" };
|
|
5857
5970
|
registerComponent("column_set", (el, ctx) => {
|
|
5858
5971
|
const p = el.property || {};
|
|
5859
5972
|
const gapRaw = p.horizontalSpacingValue?.value ?? p.horizontal_spacing;
|
|
@@ -5868,7 +5981,7 @@ function registerBuiltins() {
|
|
|
5868
5981
|
columnGap: gap + "px"
|
|
5869
5982
|
};
|
|
5870
5983
|
if (hAlign) {
|
|
5871
|
-
style.justifyContent =
|
|
5984
|
+
style.justifyContent = H_ALIGN_MAP[hAlign] || "flex-start";
|
|
5872
5985
|
}
|
|
5873
5986
|
applyOuterMargin(style, p.margin);
|
|
5874
5987
|
const bg = propertyBackgroundColor(p);
|
|
@@ -5903,6 +6016,7 @@ function registerBuiltins() {
|
|
|
5903
6016
|
flexShrink: 1,
|
|
5904
6017
|
overflow: "hidden",
|
|
5905
6018
|
display: "flex",
|
|
6019
|
+
// 缺省纵向排列;direction=horizontal 时改行,两个 align 落到哪个 flex 属性也随之交换
|
|
5906
6020
|
flexDirection: "column"
|
|
5907
6021
|
};
|
|
5908
6022
|
const wv = p.widthValue;
|
|
@@ -5938,10 +6052,16 @@ function registerBuiltins() {
|
|
|
5938
6052
|
style.flexBasis = "auto";
|
|
5939
6053
|
}
|
|
5940
6054
|
}
|
|
5941
|
-
const
|
|
5942
|
-
if (
|
|
5943
|
-
|
|
5944
|
-
|
|
6055
|
+
const horizontalDir = p.direction === "horizontal";
|
|
6056
|
+
if (horizontalDir) style.flexDirection = "row";
|
|
6057
|
+
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6058
|
+
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6059
|
+
const justify = horizontalDir ? H_ALIGN_MAP[hAlign] : V_ALIGN_MAP[vAlign];
|
|
6060
|
+
const align = horizontalDir ? V_ALIGN_MAP[vAlign] : H_ALIGN_MAP[hAlign];
|
|
6061
|
+
if (justify) style.justifyContent = justify;
|
|
6062
|
+
if (align) style.alignItems = align;
|
|
6063
|
+
const hGap = p.horizontalSpacingValue?.value ?? p.horizontal_spacing ?? p.horizontalSpacing;
|
|
6064
|
+
if (hGap != null) style.columnGap = horizontalSpacingToPx(hGap) + "px";
|
|
5945
6065
|
const vGap = p.verticalSpacingValue?.value ?? p.vertical_spacing;
|
|
5946
6066
|
style.rowGap = (vGap != null ? verticalSpacingToPx(vGap) : 8) + "px";
|
|
5947
6067
|
const bg = propertyBackgroundColor(p);
|
|
@@ -5987,6 +6107,123 @@ function registerBuiltins() {
|
|
|
5987
6107
|
src ? h("img", { className: `${CLS}-image__host`, src, alt: altText, style: imgStyle }) : h("div", { className: `${CLS}-image__placeholder`, style: imgStyle }, altText || "[\u56FE\u7247]")
|
|
5988
6108
|
);
|
|
5989
6109
|
});
|
|
6110
|
+
const IMG_COMBINATION_LIMIT = {
|
|
6111
|
+
double: 2,
|
|
6112
|
+
triple: 3
|
|
6113
|
+
};
|
|
6114
|
+
function renderCombinationImage(item, cornerRadius, ctx) {
|
|
6115
|
+
const src = resolveImageSrc(item, ctx);
|
|
6116
|
+
const style = {
|
|
6117
|
+
width: "100%",
|
|
6118
|
+
height: "100%",
|
|
6119
|
+
objectFit: "cover",
|
|
6120
|
+
display: "block"
|
|
6121
|
+
};
|
|
6122
|
+
if (cornerRadius) style.borderRadius = cornerRadius;
|
|
6123
|
+
return src ? h("img", { className: `${CLS}-image__host`, src, alt: "", style }) : h("div", { className: `${CLS}-image__placeholder`, style }, "[\u56FE\u7247]");
|
|
6124
|
+
}
|
|
6125
|
+
registerComponent("img_combination", (el, ctx) => {
|
|
6126
|
+
const p = el.property || {};
|
|
6127
|
+
const rawList = Array.isArray(p.imgList) ? p.imgList : Array.isArray(p.img_list) ? p.img_list : [];
|
|
6128
|
+
if (rawList.length === 0) return null;
|
|
6129
|
+
const mode = String(p.combinationMode ?? p.combination_mode ?? "double");
|
|
6130
|
+
const limit = IMG_COMBINATION_LIMIT[mode];
|
|
6131
|
+
const list = (limit ? rawList.slice(0, limit) : rawList).map((item) => typeof item === "string" ? { img_key: item } : item).filter(isRecord);
|
|
6132
|
+
if (list.length === 0) return null;
|
|
6133
|
+
const cornerRadius = resolveCornerRadius(p);
|
|
6134
|
+
const containerStyle = {};
|
|
6135
|
+
applyOuterMargin(containerStyle, p.margin);
|
|
6136
|
+
const cls = `${CLS}-img-combination ${CLS}-img-combination--${mode}`;
|
|
6137
|
+
const itemNode = (item) => h(
|
|
6138
|
+
"div",
|
|
6139
|
+
{ className: `${CLS}-img-combination__item` },
|
|
6140
|
+
renderCombinationImage(item, cornerRadius, ctx)
|
|
6141
|
+
);
|
|
6142
|
+
if (mode === "triple") {
|
|
6143
|
+
const [first, ...rest] = list;
|
|
6144
|
+
return h(
|
|
6145
|
+
"div",
|
|
6146
|
+
{ className: cls, style: containerStyle },
|
|
6147
|
+
h(
|
|
6148
|
+
"div",
|
|
6149
|
+
{ className: `${CLS}-img-combination__item ${CLS}-img-combination__left` },
|
|
6150
|
+
renderCombinationImage(first, cornerRadius, ctx)
|
|
6151
|
+
),
|
|
6152
|
+
h("div", { className: `${CLS}-img-combination__right` }, rest.map(itemNode))
|
|
6153
|
+
);
|
|
6154
|
+
}
|
|
6155
|
+
return h("div", { className: cls, style: containerStyle }, list.map(itemNode));
|
|
6156
|
+
});
|
|
6157
|
+
function readSelectImgValues(p) {
|
|
6158
|
+
const raw = p.selectedValues ?? p.selected_values ?? p.value;
|
|
6159
|
+
let value = raw;
|
|
6160
|
+
if (typeof value === "string") {
|
|
6161
|
+
try {
|
|
6162
|
+
value = JSON.parse(value);
|
|
6163
|
+
} catch {
|
|
6164
|
+
return typeof value === "string" && value ? [value] : [];
|
|
6165
|
+
}
|
|
6166
|
+
}
|
|
6167
|
+
if (isRecord(value) && Array.isArray(value.value)) value = value.value;
|
|
6168
|
+
if (!Array.isArray(value)) return [];
|
|
6169
|
+
return value.filter((item) => typeof item === "string");
|
|
6170
|
+
}
|
|
6171
|
+
function renderSelectImgCheckbox(checked, disabled, multiple) {
|
|
6172
|
+
const boxClass = `${CLS}-select-img__checkbox-box` + (multiple ? ` ${CLS}-select-img__checkbox-box--square` : "") + (checked ? ` ${CLS}-select-img__checkbox-box--checked` : "");
|
|
6173
|
+
return h(
|
|
6174
|
+
"div",
|
|
6175
|
+
{
|
|
6176
|
+
className: `${CLS}-select-img__checkbox` + (disabled ? ` ${CLS}-select-img__checkbox--disabled` : "")
|
|
6177
|
+
},
|
|
6178
|
+
h("span", { className: boxClass })
|
|
6179
|
+
);
|
|
6180
|
+
}
|
|
6181
|
+
registerComponent("select_img", (el, ctx) => {
|
|
6182
|
+
const p = el.property || {};
|
|
6183
|
+
const options = Array.isArray(p.options) ? p.options : [];
|
|
6184
|
+
if (options.length === 0) return null;
|
|
6185
|
+
const layout = String(p.layout ?? "bisect");
|
|
6186
|
+
const aspectRatio = String(p.aspectRatio ?? p.aspect_ratio ?? "16:9").replace(":", "/");
|
|
6187
|
+
const multiple = p.multiSelect === true || p.multi_select === true;
|
|
6188
|
+
const disabledAll = p.disabled === true;
|
|
6189
|
+
const selected = readSelectImgValues(p);
|
|
6190
|
+
const containerStyle = {};
|
|
6191
|
+
applyOuterMargin(containerStyle, p.margin);
|
|
6192
|
+
const items = options.map((rawOption) => {
|
|
6193
|
+
const option = isRecord(rawOption) ? rawOption : { img_key: rawOption };
|
|
6194
|
+
const value = typeof option.value === "string" ? option.value : void 0;
|
|
6195
|
+
const isSelected = value !== void 0 && selected.includes(value);
|
|
6196
|
+
const disabled = disabledAll || option.disabled === true;
|
|
6197
|
+
const tip = disabled ? extractText(option.disabled_tips ?? option.disabledTips) : extractText(option.hover_tips ?? option.hoverTips);
|
|
6198
|
+
const src = resolveImageSrc(option, ctx);
|
|
6199
|
+
const wrapperClass = `${CLS}-select-img__item-wrapper` + (isSelected ? ` ${CLS}-select-img__item-wrapper--selected` : "") + (disabled ? ` ${CLS}-select-img__item-wrapper--disabled` : "");
|
|
6200
|
+
const itemClass = `${CLS}-select-img__item` + (disabled ? ` ${CLS}-select-img__item--disabled` : "");
|
|
6201
|
+
return h(
|
|
6202
|
+
"div",
|
|
6203
|
+
{ className: wrapperClass },
|
|
6204
|
+
h(
|
|
6205
|
+
"div",
|
|
6206
|
+
{ className: itemClass, style: { aspectRatio }, title: tip || void 0 },
|
|
6207
|
+
ctx.inForm ? renderSelectImgCheckbox(isSelected, disabled, multiple) : null,
|
|
6208
|
+
src ? h("img", {
|
|
6209
|
+
className: `${CLS}-image__host`,
|
|
6210
|
+
src,
|
|
6211
|
+
alt: "",
|
|
6212
|
+
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
6213
|
+
}) : h(
|
|
6214
|
+
"div",
|
|
6215
|
+
{ className: `${CLS}-image__placeholder`, style: { width: "100%", height: "100%" } },
|
|
6216
|
+
"[\u56FE\u7247]"
|
|
6217
|
+
)
|
|
6218
|
+
)
|
|
6219
|
+
);
|
|
6220
|
+
});
|
|
6221
|
+
return h(
|
|
6222
|
+
"div",
|
|
6223
|
+
{ className: `${CLS}-select-img ${CLS}-select-img--${layout}`, style: containerStyle },
|
|
6224
|
+
items
|
|
6225
|
+
);
|
|
6226
|
+
});
|
|
5990
6227
|
registerComponent("video", (el, ctx) => {
|
|
5991
6228
|
const p = el.property || {};
|
|
5992
6229
|
const src = resolveMediaSrc(p, "video", ctx);
|
|
@@ -6155,10 +6392,8 @@ function registerBuiltins() {
|
|
|
6155
6392
|
if (horizontalDir) style.flexDirection = "row";
|
|
6156
6393
|
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6157
6394
|
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6158
|
-
const
|
|
6159
|
-
const
|
|
6160
|
-
const justify = horizontalDir ? H_ALIGN[hAlign] : V_ALIGN[vAlign];
|
|
6161
|
-
const align = horizontalDir ? V_ALIGN[vAlign] : H_ALIGN[hAlign];
|
|
6395
|
+
const justify = horizontalDir ? H_ALIGN_MAP[hAlign] : V_ALIGN_MAP[vAlign];
|
|
6396
|
+
const align = horizontalDir ? V_ALIGN_MAP[vAlign] : H_ALIGN_MAP[hAlign];
|
|
6162
6397
|
if (justify) style.justifyContent = justify;
|
|
6163
6398
|
if (align) style.alignItems = align;
|
|
6164
6399
|
const hGap = p.horizontalSpacingValue?.value ?? p.horizontal_spacing ?? p.horizontalSpacing;
|
|
@@ -6185,7 +6420,7 @@ function registerBuiltins() {
|
|
|
6185
6420
|
registerComponent("collapsible_panel", (el, ctx) => {
|
|
6186
6421
|
const p = el.property || {};
|
|
6187
6422
|
const hdr = p.header && typeof p.header === "object" ? p.header : {};
|
|
6188
|
-
const expanded = p.expanded
|
|
6423
|
+
const expanded = p.expanded === true;
|
|
6189
6424
|
const style = { width: "100%" };
|
|
6190
6425
|
const bgRaw = p.background_color ?? p.backgroundColor;
|
|
6191
6426
|
const bgCustom = propertyBackgroundColor(p);
|
|
@@ -6204,12 +6439,36 @@ function registerBuiltins() {
|
|
|
6204
6439
|
} else {
|
|
6205
6440
|
style.borderRadius = "8px";
|
|
6206
6441
|
}
|
|
6442
|
+
const headerBottom = String(hdr.position ?? "top") === "bottom";
|
|
6443
|
+
if (headerBottom) {
|
|
6444
|
+
style.display = "flex";
|
|
6445
|
+
style.flexDirection = "column";
|
|
6446
|
+
}
|
|
6207
6447
|
applyOuterMargin(style, p.margin);
|
|
6208
6448
|
const headerStyle = {};
|
|
6209
6449
|
const hpad = typeof hdr.padding === "string" ? hdr.padding : boxToStyle(hdr.padding);
|
|
6210
6450
|
if (hpad) headerStyle.padding = hpad;
|
|
6211
|
-
const
|
|
6212
|
-
|
|
6451
|
+
const hbg = resolveColor(hdr.background_color ?? hdr.backgroundColor);
|
|
6452
|
+
if (hbg) headerStyle.background = hbg;
|
|
6453
|
+
if (headerBottom) headerStyle.order = "2";
|
|
6454
|
+
const titleLeaf = (raw, className) => {
|
|
6455
|
+
if (!raw || typeof raw !== "object") return null;
|
|
6456
|
+
const t = raw;
|
|
6457
|
+
if (typeof t.tag !== "string") return null;
|
|
6458
|
+
const property = t.property && typeof t.property === "object" ? t.property : t;
|
|
6459
|
+
const node = renderHeaderTextLeaf({ tag: t.tag, property }, ctx, className);
|
|
6460
|
+
if (node) return node;
|
|
6461
|
+
const text = extractPlainText(raw) || extractText(raw);
|
|
6462
|
+
return text ? h("div", { className }, text) : null;
|
|
6463
|
+
};
|
|
6464
|
+
const primaryTitle = titleLeaf(hdr.title, `${CLS}-collapsible-panel__title-text`);
|
|
6465
|
+
const expandedTitleRaw = hdr.expanded_title ?? hdr.expandedTitle;
|
|
6466
|
+
const expandedTitle = titleLeaf(
|
|
6467
|
+
expandedTitleRaw,
|
|
6468
|
+
`${CLS}-collapsible-panel__title-text ${CLS}-collapsible-panel__title-text--expanded`
|
|
6469
|
+
);
|
|
6470
|
+
const titleCls = `${CLS}-collapsible-panel__title` + (expandedTitle ? ` ${CLS}-collapsible-panel__title--has-expanded` : "");
|
|
6471
|
+
const titleVNode = h("div", { className: titleCls }, [primaryTitle, expandedTitle].filter(Boolean));
|
|
6213
6472
|
let iconVNode = null;
|
|
6214
6473
|
const iconRaw = hdr.icon;
|
|
6215
6474
|
const openAngle = Number(hdr.icon_expanded_angle ?? hdr.iconExpandedAngle ?? -180);
|
|
@@ -6225,11 +6484,38 @@ function registerBuiltins() {
|
|
|
6225
6484
|
const iconFollow = iconPos === "follow_text" || iconPos === "followText";
|
|
6226
6485
|
const headerChildren = iconLeft ? [iconVNode, titleVNode] : [titleVNode, iconVNode];
|
|
6227
6486
|
const summaryStyle = { ...headerStyle, "--panel-icon-angle": `${openAngle}deg` };
|
|
6228
|
-
const
|
|
6487
|
+
const headerWidth = String(hdr.width ?? hdr.headerWidth ?? "fill");
|
|
6488
|
+
const headerVAlign = String(hdr.vertical_align ?? hdr.verticalAlign ?? "center");
|
|
6489
|
+
const headerCls = `${CLS}-collapsible-panel__header` + (iconFollow ? ` ${CLS}-collapsible-panel__header--icon-follow` : "") + (headerWidth === "auto" ? ` ${CLS}-collapsible-panel__header--w-auto` : "") + (headerWidth === "auto_when_fold" ? ` ${CLS}-collapsible-panel__header--w-auto-when-fold` : "") + (headerVAlign === "top" ? ` ${CLS}-collapsible-panel__header--valign-top` : "") + (headerVAlign === "bottom" ? ` ${CLS}-collapsible-panel__header--valign-bottom` : "");
|
|
6229
6490
|
const summary = h("summary", { className: headerCls, style: summaryStyle }, headerChildren);
|
|
6230
6491
|
const contentStyle = {};
|
|
6231
6492
|
const cpad = typeof p.padding === "string" ? p.padding : boxToStyle(p.padding);
|
|
6232
6493
|
if (cpad) contentStyle.padding = cpad;
|
|
6494
|
+
if (headerBottom) contentStyle.order = "1";
|
|
6495
|
+
const direction = String(p.direction ?? "vertical");
|
|
6496
|
+
const isRow = direction === "horizontal";
|
|
6497
|
+
const hSpacing = p.horizontal_spacing ?? p.horizontalSpacing;
|
|
6498
|
+
const vSpacing = p.vertical_spacing ?? p.verticalSpacing;
|
|
6499
|
+
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6500
|
+
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6501
|
+
if (isRow || hSpacing != null || vSpacing != null || hAlign != null || vAlign != null) {
|
|
6502
|
+
contentStyle.display = "flex";
|
|
6503
|
+
contentStyle.flexDirection = isRow ? "row" : "column";
|
|
6504
|
+
const gapX = hSpacing != null ? horizontalSpacingToPx(hSpacing) : isRow ? 8 : 0;
|
|
6505
|
+
const gapY = vSpacing != null ? verticalSpacingToPx(vSpacing) : 0;
|
|
6506
|
+
if (gapX) contentStyle.columnGap = gapX + "px";
|
|
6507
|
+
if (gapY) contentStyle.rowGap = gapY + "px";
|
|
6508
|
+
const hVal = hAlign ? H_ALIGN_MAP[hAlign] : void 0;
|
|
6509
|
+
const vVal = vAlign ? V_ALIGN_MAP[vAlign] : void 0;
|
|
6510
|
+
if (hVal) {
|
|
6511
|
+
if (isRow) contentStyle.justifyContent = hVal;
|
|
6512
|
+
else contentStyle.alignItems = hVal;
|
|
6513
|
+
}
|
|
6514
|
+
if (vVal) {
|
|
6515
|
+
if (isRow) contentStyle.alignItems = vVal;
|
|
6516
|
+
else contentStyle.justifyContent = vVal;
|
|
6517
|
+
}
|
|
6518
|
+
}
|
|
6233
6519
|
const content = h(
|
|
6234
6520
|
"div",
|
|
6235
6521
|
{ className: `${CLS}-collapsible-panel__content`, style: contentStyle },
|
|
@@ -6362,7 +6648,7 @@ function registerBuiltins() {
|
|
|
6362
6648
|
);
|
|
6363
6649
|
});
|
|
6364
6650
|
registerComponent("form", (el, ctx) => {
|
|
6365
|
-
const children = renderElements(el.property?.elements, ctx);
|
|
6651
|
+
const children = renderElements(el.property?.elements, { ...ctx, inForm: true });
|
|
6366
6652
|
const className = `${CLS}-form`;
|
|
6367
6653
|
if (!ctx.options.interactive) return h("div", { className }, children);
|
|
6368
6654
|
const name = typeof el.property?.name === "string" ? el.property.name : "";
|
package/dist/styles.css
CHANGED
|
@@ -380,6 +380,90 @@
|
|
|
380
380
|
font-size: 12px;
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
+
/* ---- img_combination 多图混排(比例逆向自网页版 .universal-card-img-combination) ---- */
|
|
384
|
+
.universal-card-img-combination { display: flex; width: 100%; justify-content: space-between; }
|
|
385
|
+
.universal-card-img-combination__item { min-width: 0; overflow: hidden; }
|
|
386
|
+
.universal-card-img-combination__item > .universal-card-image__host { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
387
|
+
.universal-card-img-combination__item > .universal-card-image__placeholder { width: 100%; height: 100%; }
|
|
388
|
+
/* double:左窄(32.4%, 24:33) + 右宽(67.6%, 49.33:33) */
|
|
389
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(odd) {
|
|
390
|
+
width: 32.4%; aspect-ratio: 24 / 33;
|
|
391
|
+
}
|
|
392
|
+
.universal-card-img-combination--double .universal-card-img-combination__item:nth-child(2n) {
|
|
393
|
+
width: calc(67.6% - 4px); aspect-ratio: 49.33 / 33;
|
|
394
|
+
}
|
|
395
|
+
/* triple:左大图(66.5%, 1:1) + 右列两张小图 */
|
|
396
|
+
.universal-card-img-combination--triple .universal-card-img-combination__left {
|
|
397
|
+
width: 66.5%; aspect-ratio: 1; margin-right: 1%;
|
|
398
|
+
}
|
|
399
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right {
|
|
400
|
+
width: 33%; display: flex; flex-direction: column; justify-content: space-between;
|
|
401
|
+
}
|
|
402
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item {
|
|
403
|
+
width: 100%; aspect-ratio: 1;
|
|
404
|
+
}
|
|
405
|
+
.universal-card-img-combination--triple .universal-card-img-combination__right .universal-card-img-combination__item:first-child {
|
|
406
|
+
margin-bottom: 1.5%;
|
|
407
|
+
}
|
|
408
|
+
/* bisect / trisect:等宽方格换行 */
|
|
409
|
+
.universal-card-img-combination--bisect { flex-wrap: wrap; gap: 4px; }
|
|
410
|
+
.universal-card-img-combination--bisect .universal-card-img-combination__item {
|
|
411
|
+
width: calc(50% - 2px); aspect-ratio: 1;
|
|
412
|
+
}
|
|
413
|
+
.universal-card-img-combination--trisect { flex-wrap: wrap; justify-content: flex-start; gap: 4px; }
|
|
414
|
+
.universal-card-img-combination--trisect .universal-card-img-combination__item {
|
|
415
|
+
width: calc(33.33% - 2.67px); aspect-ratio: 1;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* ---- select_img 多图选择(对齐网页版 .universal-card-select-img) ---- */
|
|
419
|
+
.universal-card-select-img {
|
|
420
|
+
width: 100%; max-width: 100%; display: grid; grid-gap: 4px; box-sizing: border-box;
|
|
421
|
+
}
|
|
422
|
+
.universal-card-select-img--stretch { grid-template-columns: 1fr; }
|
|
423
|
+
.universal-card-select-img--bisect { grid-template-columns: 1fr 1fr; }
|
|
424
|
+
.universal-card-select-img--trisect { grid-template-columns: 1fr 1fr 1fr; }
|
|
425
|
+
.universal-card-select-img__item-wrapper { position: relative; border-radius: 6px; }
|
|
426
|
+
.universal-card-select-img__item-wrapper::after {
|
|
427
|
+
content: " "; position: absolute; inset: 0; box-sizing: border-box;
|
|
428
|
+
border: 1px solid var(--N300); border-radius: 6px; pointer-events: none; z-index: 1;
|
|
429
|
+
}
|
|
430
|
+
.universal-card-select-img__item-wrapper--selected::after { border: 2px solid var(--B500); }
|
|
431
|
+
.universal-card-select-img__item {
|
|
432
|
+
position: relative; overflow: hidden; box-sizing: border-box; border-radius: 6px;
|
|
433
|
+
cursor: pointer; width: 100%;
|
|
434
|
+
}
|
|
435
|
+
.universal-card-select-img__item--disabled { cursor: not-allowed; }
|
|
436
|
+
.universal-card-select-img__item--disabled::after {
|
|
437
|
+
content: " "; position: absolute; inset: 0; z-index: 1;
|
|
438
|
+
background-color: rgba(255, 255, 255, .5);
|
|
439
|
+
}
|
|
440
|
+
.universal-card-select-img__item > .universal-card-image__host {
|
|
441
|
+
display: block; width: 100%; height: 100%; object-fit: cover;
|
|
442
|
+
}
|
|
443
|
+
.universal-card-select-img__item > .universal-card-image__placeholder {
|
|
444
|
+
width: 100%; height: 100%;
|
|
445
|
+
}
|
|
446
|
+
/* 表单内复选/单选标记(真机仅 in-form 显示;表单外用选中描边表达状态) */
|
|
447
|
+
.universal-card-select-img__checkbox {
|
|
448
|
+
position: absolute; top: 0; right: 0; z-index: 2; padding: 5px 8px; cursor: pointer;
|
|
449
|
+
}
|
|
450
|
+
.universal-card-select-img__checkbox--disabled { cursor: not-allowed; }
|
|
451
|
+
.universal-card-select-img__checkbox-box {
|
|
452
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
453
|
+
width: 16px; height: 16px; box-sizing: border-box; border-radius: 50%;
|
|
454
|
+
background-color: rgba(0, 0, 0, .15); border: 1px solid #eff0f1;
|
|
455
|
+
box-shadow: 0 0 2px rgba(0, 0, 0, .1);
|
|
456
|
+
}
|
|
457
|
+
.universal-card-select-img__checkbox-box--square { border-radius: 4px; }
|
|
458
|
+
.universal-card-select-img__checkbox-box--checked {
|
|
459
|
+
background-color: var(--B500); border-color: var(--B500);
|
|
460
|
+
}
|
|
461
|
+
.universal-card-select-img__checkbox-box--checked::after {
|
|
462
|
+
content: ""; width: 3.5px; height: 7px;
|
|
463
|
+
border: solid #fff; border-width: 0 2px 2px 0;
|
|
464
|
+
transform: rotate(45deg) translateY(-1px);
|
|
465
|
+
}
|
|
466
|
+
|
|
383
467
|
/* ---- 按钮 ---- */
|
|
384
468
|
/* 飞书按钮文本是纯文本、单行:min-height 容纳偶发换行,文字超长省略号收尾。
|
|
385
469
|
样式全集逆向自网页版 ud__button:三大族——outlined(描边)/ text(纯文字)/ filled(实心),
|
|
@@ -623,10 +707,32 @@
|
|
|
623
707
|
}
|
|
624
708
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
625
709
|
.universal-card-collapsible-panel__header::marker { content: ''; }
|
|
710
|
+
/* header.vertical_align:center(默认)/ top / bottom */
|
|
711
|
+
.universal-card-collapsible-panel__header--valign-top { align-items: flex-start; }
|
|
712
|
+
.universal-card-collapsible-panel__header--valign-bottom { align-items: flex-end; }
|
|
713
|
+
/* header.width:fill(默认,撑满整行)/ auto(自适应内容宽)/
|
|
714
|
+
auto_when_fold(折叠自适应、展开撑满——真机语义) */
|
|
715
|
+
.universal-card-collapsible-panel__header--w-auto,
|
|
716
|
+
.universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
717
|
+
width: max-content; max-width: 100%;
|
|
718
|
+
}
|
|
719
|
+
.universal-card-collapsible-panel[open] > .universal-card-collapsible-panel__header--w-auto-when-fold {
|
|
720
|
+
width: 100%;
|
|
721
|
+
}
|
|
626
722
|
.universal-card-collapsible-panel__title {
|
|
627
723
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
628
724
|
word-break: break-word;
|
|
629
725
|
}
|
|
726
|
+
/* title ↔ expanded_title:有 expanded_title 时,折叠展示 title、展开展示 expanded_title
|
|
727
|
+
(真机语义)。纯 CSS 由 details[open] 驱动,不学要 JS 同步。 */
|
|
728
|
+
.universal-card-collapsible-panel__title-text { display: block; }
|
|
729
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
730
|
+
.universal-card-collapsible-panel__title-text--expanded { display: none; }
|
|
731
|
+
.universal-card-collapsible-panel[open]
|
|
732
|
+
.universal-card-collapsible-panel__title--has-expanded .universal-card-collapsible-panel__title-text { display: none; }
|
|
733
|
+
.universal-card-collapsible-panel[open]
|
|
734
|
+
.universal-card-collapsible-panel__title--has-expanded
|
|
735
|
+
.universal-card-collapsible-panel__title-text--expanded { display: block; }
|
|
630
736
|
/* follow_text:箭头紧贴文字(真机 __header-content--icon-follow),不拉满整行 */
|
|
631
737
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
632
738
|
gap: 4px;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-feishu-card/renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "零框架依赖的飞书卡片渲染引擎:Web / DOM / SSR,输入 RAW 或公开 DSL,输出真实 DOM 或 HTML 字符串",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"./dist/*.cjs"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@open-feishu-card/adapter": "0.
|
|
31
|
+
"@open-feishu-card/adapter": "0.4.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"tsup": "^8.3.5",
|