@open-feishu-card/renderer 0.4.0 → 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 +22 -0
- package/dist/index.cjs +93 -13
- package/dist/index.js +93 -13
- package/dist/styles.css +22 -0
- package/package.json +2 -2
package/dist/all.css
CHANGED
|
@@ -707,10 +707,32 @@
|
|
|
707
707
|
}
|
|
708
708
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
709
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
|
+
}
|
|
710
722
|
.universal-card-collapsible-panel__title {
|
|
711
723
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
712
724
|
word-break: break-word;
|
|
713
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; }
|
|
714
736
|
/* follow_text:箭头紧贴文字(真机 __header-content--icon-follow),不拉满整行 */
|
|
715
737
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
716
738
|
gap: 4px;
|
package/dist/index.cjs
CHANGED
|
@@ -1684,10 +1684,32 @@ var BASE_STYLES_CSS = `/**
|
|
|
1684
1684
|
}
|
|
1685
1685
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
1686
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
|
+
}
|
|
1687
1699
|
.universal-card-collapsible-panel__title {
|
|
1688
1700
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
1689
1701
|
word-break: break-word;
|
|
1690
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; }
|
|
1691
1713
|
/* follow_text\uFF1A\u7BAD\u5934\u7D27\u8D34\u6587\u5B57\uFF08\u771F\u673A __header-content--icon-follow\uFF09\uFF0C\u4E0D\u62C9\u6EE1\u6574\u884C */
|
|
1692
1714
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
1693
1715
|
gap: 4px;
|
|
@@ -5944,6 +5966,8 @@ function registerBuiltins() {
|
|
|
5944
5966
|
}
|
|
5945
5967
|
return h("div", { className: `${CLS}-div` }, content);
|
|
5946
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" };
|
|
5947
5971
|
registerComponent("column_set", (el, ctx) => {
|
|
5948
5972
|
const p = el.property || {};
|
|
5949
5973
|
const gapRaw = p.horizontalSpacingValue?.value ?? p.horizontal_spacing;
|
|
@@ -5958,7 +5982,7 @@ function registerBuiltins() {
|
|
|
5958
5982
|
columnGap: gap + "px"
|
|
5959
5983
|
};
|
|
5960
5984
|
if (hAlign) {
|
|
5961
|
-
style.justifyContent =
|
|
5985
|
+
style.justifyContent = H_ALIGN_MAP[hAlign] || "flex-start";
|
|
5962
5986
|
}
|
|
5963
5987
|
applyOuterMargin(style, p.margin);
|
|
5964
5988
|
const bg = propertyBackgroundColor(p);
|
|
@@ -5993,6 +6017,7 @@ function registerBuiltins() {
|
|
|
5993
6017
|
flexShrink: 1,
|
|
5994
6018
|
overflow: "hidden",
|
|
5995
6019
|
display: "flex",
|
|
6020
|
+
// 缺省纵向排列;direction=horizontal 时改行,两个 align 落到哪个 flex 属性也随之交换
|
|
5996
6021
|
flexDirection: "column"
|
|
5997
6022
|
};
|
|
5998
6023
|
const wv = p.widthValue;
|
|
@@ -6028,10 +6053,16 @@ function registerBuiltins() {
|
|
|
6028
6053
|
style.flexBasis = "auto";
|
|
6029
6054
|
}
|
|
6030
6055
|
}
|
|
6031
|
-
const
|
|
6032
|
-
if (
|
|
6033
|
-
|
|
6034
|
-
|
|
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";
|
|
6035
6066
|
const vGap = p.verticalSpacingValue?.value ?? p.vertical_spacing;
|
|
6036
6067
|
style.rowGap = (vGap != null ? verticalSpacingToPx(vGap) : 8) + "px";
|
|
6037
6068
|
const bg = propertyBackgroundColor(p);
|
|
@@ -6362,10 +6393,8 @@ function registerBuiltins() {
|
|
|
6362
6393
|
if (horizontalDir) style.flexDirection = "row";
|
|
6363
6394
|
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6364
6395
|
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6365
|
-
const
|
|
6366
|
-
const
|
|
6367
|
-
const justify = horizontalDir ? H_ALIGN[hAlign] : V_ALIGN[vAlign];
|
|
6368
|
-
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];
|
|
6369
6398
|
if (justify) style.justifyContent = justify;
|
|
6370
6399
|
if (align) style.alignItems = align;
|
|
6371
6400
|
const hGap = p.horizontalSpacingValue?.value ?? p.horizontal_spacing ?? p.horizontalSpacing;
|
|
@@ -6392,7 +6421,7 @@ function registerBuiltins() {
|
|
|
6392
6421
|
registerComponent("collapsible_panel", (el, ctx) => {
|
|
6393
6422
|
const p = el.property || {};
|
|
6394
6423
|
const hdr = p.header && typeof p.header === "object" ? p.header : {};
|
|
6395
|
-
const expanded = p.expanded
|
|
6424
|
+
const expanded = p.expanded === true;
|
|
6396
6425
|
const style = { width: "100%" };
|
|
6397
6426
|
const bgRaw = p.background_color ?? p.backgroundColor;
|
|
6398
6427
|
const bgCustom = propertyBackgroundColor(p);
|
|
@@ -6411,12 +6440,36 @@ function registerBuiltins() {
|
|
|
6411
6440
|
} else {
|
|
6412
6441
|
style.borderRadius = "8px";
|
|
6413
6442
|
}
|
|
6443
|
+
const headerBottom = String(hdr.position ?? "top") === "bottom";
|
|
6444
|
+
if (headerBottom) {
|
|
6445
|
+
style.display = "flex";
|
|
6446
|
+
style.flexDirection = "column";
|
|
6447
|
+
}
|
|
6414
6448
|
applyOuterMargin(style, p.margin);
|
|
6415
6449
|
const headerStyle = {};
|
|
6416
6450
|
const hpad = typeof hdr.padding === "string" ? hdr.padding : boxToStyle(hdr.padding);
|
|
6417
6451
|
if (hpad) headerStyle.padding = hpad;
|
|
6418
|
-
const
|
|
6419
|
-
|
|
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));
|
|
6420
6473
|
let iconVNode = null;
|
|
6421
6474
|
const iconRaw = hdr.icon;
|
|
6422
6475
|
const openAngle = Number(hdr.icon_expanded_angle ?? hdr.iconExpandedAngle ?? -180);
|
|
@@ -6432,11 +6485,38 @@ function registerBuiltins() {
|
|
|
6432
6485
|
const iconFollow = iconPos === "follow_text" || iconPos === "followText";
|
|
6433
6486
|
const headerChildren = iconLeft ? [iconVNode, titleVNode] : [titleVNode, iconVNode];
|
|
6434
6487
|
const summaryStyle = { ...headerStyle, "--panel-icon-angle": `${openAngle}deg` };
|
|
6435
|
-
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` : "");
|
|
6436
6491
|
const summary = h("summary", { className: headerCls, style: summaryStyle }, headerChildren);
|
|
6437
6492
|
const contentStyle = {};
|
|
6438
6493
|
const cpad = typeof p.padding === "string" ? p.padding : boxToStyle(p.padding);
|
|
6439
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
|
+
}
|
|
6440
6520
|
const content = h(
|
|
6441
6521
|
"div",
|
|
6442
6522
|
{ className: `${CLS}-collapsible-panel__content`, style: contentStyle },
|
package/dist/index.js
CHANGED
|
@@ -1683,10 +1683,32 @@ var BASE_STYLES_CSS = `/**
|
|
|
1683
1683
|
}
|
|
1684
1684
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
1685
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
|
+
}
|
|
1686
1698
|
.universal-card-collapsible-panel__title {
|
|
1687
1699
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
1688
1700
|
word-break: break-word;
|
|
1689
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; }
|
|
1690
1712
|
/* follow_text\uFF1A\u7BAD\u5934\u7D27\u8D34\u6587\u5B57\uFF08\u771F\u673A __header-content--icon-follow\uFF09\uFF0C\u4E0D\u62C9\u6EE1\u6574\u884C */
|
|
1691
1713
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
1692
1714
|
gap: 4px;
|
|
@@ -5943,6 +5965,8 @@ function registerBuiltins() {
|
|
|
5943
5965
|
}
|
|
5944
5966
|
return h("div", { className: `${CLS}-div` }, content);
|
|
5945
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" };
|
|
5946
5970
|
registerComponent("column_set", (el, ctx) => {
|
|
5947
5971
|
const p = el.property || {};
|
|
5948
5972
|
const gapRaw = p.horizontalSpacingValue?.value ?? p.horizontal_spacing;
|
|
@@ -5957,7 +5981,7 @@ function registerBuiltins() {
|
|
|
5957
5981
|
columnGap: gap + "px"
|
|
5958
5982
|
};
|
|
5959
5983
|
if (hAlign) {
|
|
5960
|
-
style.justifyContent =
|
|
5984
|
+
style.justifyContent = H_ALIGN_MAP[hAlign] || "flex-start";
|
|
5961
5985
|
}
|
|
5962
5986
|
applyOuterMargin(style, p.margin);
|
|
5963
5987
|
const bg = propertyBackgroundColor(p);
|
|
@@ -5992,6 +6016,7 @@ function registerBuiltins() {
|
|
|
5992
6016
|
flexShrink: 1,
|
|
5993
6017
|
overflow: "hidden",
|
|
5994
6018
|
display: "flex",
|
|
6019
|
+
// 缺省纵向排列;direction=horizontal 时改行,两个 align 落到哪个 flex 属性也随之交换
|
|
5995
6020
|
flexDirection: "column"
|
|
5996
6021
|
};
|
|
5997
6022
|
const wv = p.widthValue;
|
|
@@ -6027,10 +6052,16 @@ function registerBuiltins() {
|
|
|
6027
6052
|
style.flexBasis = "auto";
|
|
6028
6053
|
}
|
|
6029
6054
|
}
|
|
6030
|
-
const
|
|
6031
|
-
if (
|
|
6032
|
-
|
|
6033
|
-
|
|
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";
|
|
6034
6065
|
const vGap = p.verticalSpacingValue?.value ?? p.vertical_spacing;
|
|
6035
6066
|
style.rowGap = (vGap != null ? verticalSpacingToPx(vGap) : 8) + "px";
|
|
6036
6067
|
const bg = propertyBackgroundColor(p);
|
|
@@ -6361,10 +6392,8 @@ function registerBuiltins() {
|
|
|
6361
6392
|
if (horizontalDir) style.flexDirection = "row";
|
|
6362
6393
|
const hAlign = p.horizontal_align ?? p.horizontalAlign;
|
|
6363
6394
|
const vAlign = p.vertical_align ?? p.verticalAlign;
|
|
6364
|
-
const
|
|
6365
|
-
const
|
|
6366
|
-
const justify = horizontalDir ? H_ALIGN[hAlign] : V_ALIGN[vAlign];
|
|
6367
|
-
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];
|
|
6368
6397
|
if (justify) style.justifyContent = justify;
|
|
6369
6398
|
if (align) style.alignItems = align;
|
|
6370
6399
|
const hGap = p.horizontalSpacingValue?.value ?? p.horizontal_spacing ?? p.horizontalSpacing;
|
|
@@ -6391,7 +6420,7 @@ function registerBuiltins() {
|
|
|
6391
6420
|
registerComponent("collapsible_panel", (el, ctx) => {
|
|
6392
6421
|
const p = el.property || {};
|
|
6393
6422
|
const hdr = p.header && typeof p.header === "object" ? p.header : {};
|
|
6394
|
-
const expanded = p.expanded
|
|
6423
|
+
const expanded = p.expanded === true;
|
|
6395
6424
|
const style = { width: "100%" };
|
|
6396
6425
|
const bgRaw = p.background_color ?? p.backgroundColor;
|
|
6397
6426
|
const bgCustom = propertyBackgroundColor(p);
|
|
@@ -6410,12 +6439,36 @@ function registerBuiltins() {
|
|
|
6410
6439
|
} else {
|
|
6411
6440
|
style.borderRadius = "8px";
|
|
6412
6441
|
}
|
|
6442
|
+
const headerBottom = String(hdr.position ?? "top") === "bottom";
|
|
6443
|
+
if (headerBottom) {
|
|
6444
|
+
style.display = "flex";
|
|
6445
|
+
style.flexDirection = "column";
|
|
6446
|
+
}
|
|
6413
6447
|
applyOuterMargin(style, p.margin);
|
|
6414
6448
|
const headerStyle = {};
|
|
6415
6449
|
const hpad = typeof hdr.padding === "string" ? hdr.padding : boxToStyle(hdr.padding);
|
|
6416
6450
|
if (hpad) headerStyle.padding = hpad;
|
|
6417
|
-
const
|
|
6418
|
-
|
|
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));
|
|
6419
6472
|
let iconVNode = null;
|
|
6420
6473
|
const iconRaw = hdr.icon;
|
|
6421
6474
|
const openAngle = Number(hdr.icon_expanded_angle ?? hdr.iconExpandedAngle ?? -180);
|
|
@@ -6431,11 +6484,38 @@ function registerBuiltins() {
|
|
|
6431
6484
|
const iconFollow = iconPos === "follow_text" || iconPos === "followText";
|
|
6432
6485
|
const headerChildren = iconLeft ? [iconVNode, titleVNode] : [titleVNode, iconVNode];
|
|
6433
6486
|
const summaryStyle = { ...headerStyle, "--panel-icon-angle": `${openAngle}deg` };
|
|
6434
|
-
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` : "");
|
|
6435
6490
|
const summary = h("summary", { className: headerCls, style: summaryStyle }, headerChildren);
|
|
6436
6491
|
const contentStyle = {};
|
|
6437
6492
|
const cpad = typeof p.padding === "string" ? p.padding : boxToStyle(p.padding);
|
|
6438
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
|
+
}
|
|
6439
6519
|
const content = h(
|
|
6440
6520
|
"div",
|
|
6441
6521
|
{ className: `${CLS}-collapsible-panel__content`, style: contentStyle },
|
package/dist/styles.css
CHANGED
|
@@ -707,10 +707,32 @@
|
|
|
707
707
|
}
|
|
708
708
|
.universal-card-collapsible-panel__header::-webkit-details-marker { display: none; }
|
|
709
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
|
+
}
|
|
710
722
|
.universal-card-collapsible-panel__title {
|
|
711
723
|
flex: 1; min-width: 0; font-size: 14px; line-height: 22px;
|
|
712
724
|
word-break: break-word;
|
|
713
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; }
|
|
714
736
|
/* follow_text:箭头紧贴文字(真机 __header-content--icon-follow),不拉满整行 */
|
|
715
737
|
.universal-card-collapsible-panel__header--icon-follow {
|
|
716
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.4.
|
|
31
|
+
"@open-feishu-card/adapter": "0.4.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"tsup": "^8.3.5",
|