@open-feishu-card/renderer 0.2.29 → 0.2.30
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 +49 -0
- package/dist/index.cjs +105 -0
- package/dist/index.d.cts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +104 -1
- package/dist/styles.css +49 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2017,6 +2017,55 @@ var BASE_STYLES_CSS = `/**
|
|
|
2017
2017
|
}
|
|
2018
2018
|
.universal-card-root.theme-dark .universal-card-markdown { color: #d6d6d6; }
|
|
2019
2019
|
.universal-card-root.theme-dark .universal-card-hr { background-color: #2e2e30; }
|
|
2020
|
+
|
|
2021
|
+
/* ---- Toast \u5BBF\u4E3B\uFF08\u5BF9\u9F50\u5BA2\u6237\u7AEF .ud__toast.ud__notice\uFF1A\u9876\u90E8\u4E0B\u62C9\u3001\u6DF1\u8272\u80F6\u56CA\uFF09 ---- */
|
|
2022
|
+
.universal-card-toast-host {
|
|
2023
|
+
position: fixed;
|
|
2024
|
+
top: 32px; /* \u5BA2\u6237\u7AEF\u7EC4\u4EF6\u914D\u7F6E toast:{top:32} */
|
|
2025
|
+
left: 50%;
|
|
2026
|
+
transform: translateX(-50%);
|
|
2027
|
+
display: flex;
|
|
2028
|
+
flex-direction: column;
|
|
2029
|
+
align-items: center;
|
|
2030
|
+
z-index: 300;
|
|
2031
|
+
pointer-events: none;
|
|
2032
|
+
}
|
|
2033
|
+
.universal-card-toast {
|
|
2034
|
+
display: inline-flex;
|
|
2035
|
+
align-items: center;
|
|
2036
|
+
gap: 8px;
|
|
2037
|
+
max-width: 600px; /* \u5BA2\u6237\u7AEF .ud__toast max-width:600px */
|
|
2038
|
+
padding: 10px 16px;
|
|
2039
|
+
border-radius: 8px;
|
|
2040
|
+
background: rgba(31, 35, 41, 0.92); /* N900 \u6DF1\u8272\u534A\u900F\u660E\uFF0C\u767D\u5B57 */
|
|
2041
|
+
color: #fff;
|
|
2042
|
+
font-size: 14px;
|
|
2043
|
+
line-height: 1.5;
|
|
2044
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
|
|
2045
|
+
margin-bottom: 16px; /* \u5BA2\u6237\u7AEF .ud__toast margin-bottom:16px */
|
|
2046
|
+
animation: universal-card-toast-in 0.3s cubic-bezier(0.2, 0, 0, 1);
|
|
2047
|
+
}
|
|
2048
|
+
.universal-card-toast--leave {
|
|
2049
|
+
animation: universal-card-toast-out 0.3s cubic-bezier(0.2, 0, 0, 1) forwards;
|
|
2050
|
+
}
|
|
2051
|
+
.universal-card-toast__icon {
|
|
2052
|
+
flex: none;
|
|
2053
|
+
display: inline-flex;
|
|
2054
|
+
}
|
|
2055
|
+
.universal-card-toast__text {
|
|
2056
|
+
display: -webkit-box;
|
|
2057
|
+
-webkit-box-orient: vertical;
|
|
2058
|
+
overflow: hidden;
|
|
2059
|
+
word-break: break-word;
|
|
2060
|
+
}
|
|
2061
|
+
@keyframes universal-card-toast-in {
|
|
2062
|
+
from { opacity: 0; transform: translateY(-100%); }
|
|
2063
|
+
to { opacity: 1; transform: translateY(0); }
|
|
2064
|
+
}
|
|
2065
|
+
@keyframes universal-card-toast-out {
|
|
2066
|
+
from { opacity: 1; transform: translateY(0); }
|
|
2067
|
+
to { opacity: 0; transform: translateY(-100%); margin-bottom: 0; }
|
|
2068
|
+
}
|
|
2020
2069
|
`;
|
|
2021
2070
|
|
|
2022
2071
|
// src/icon-font.ts
|
|
@@ -6816,6 +6865,60 @@ function feishuCardStyleTag() {
|
|
|
6816
6865
|
return `<style data-feishu-card>${ALL_CSS}</style>`;
|
|
6817
6866
|
}
|
|
6818
6867
|
|
|
6868
|
+
// src/toast.ts
|
|
6869
|
+
var DEFAULT_SHOW_TIME = 2e3;
|
|
6870
|
+
var TYPE_ICON = {
|
|
6871
|
+
success: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#34c724"/><path d="M4.5 8.2l2.2 2.2 4.8-4.8" fill="none" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
6872
|
+
info: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#3370ff"/><circle cx="8" cy="4.6" r="1" fill="#fff"/><rect x="7.2" y="7" width="1.6" height="4.2" rx="0.8" fill="#fff"/></svg>',
|
|
6873
|
+
warning: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#fad355"/><rect x="7.2" y="3.8" width="1.6" height="4.6" rx="0.8" fill="#1f2329"/><circle cx="8" cy="11.8" r="1" fill="#1f2329"/></svg>',
|
|
6874
|
+
error: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#f54a45"/><path d="M5.6 5.6l4.8 4.8M10.4 5.6l-4.8 4.8" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/></svg>'
|
|
6875
|
+
};
|
|
6876
|
+
function escapeHTML(s) {
|
|
6877
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
6878
|
+
}
|
|
6879
|
+
function renderToastHTML(type, opts) {
|
|
6880
|
+
const maxLines = opts.maxLines ?? 1;
|
|
6881
|
+
const styleAttr = maxLines > 1 ? ` style="-webkit-line-clamp:${maxLines};"` : "";
|
|
6882
|
+
return `<div class="universal-card-toast universal-card-toast--${type}" role="status" aria-live="polite"><span class="universal-card-toast__icon">${TYPE_ICON[type]}</span><span class="universal-card-toast__text"${styleAttr}>${escapeHTML(opts.content)}</span></div>`;
|
|
6883
|
+
}
|
|
6884
|
+
function createToastHost(container) {
|
|
6885
|
+
const hostEl = typeof document === "undefined" ? null : container ?? document.body;
|
|
6886
|
+
const ensureHost = () => {
|
|
6887
|
+
if (!hostEl) return null;
|
|
6888
|
+
let el = hostEl.querySelector(".universal-card-toast-host");
|
|
6889
|
+
if (!el) {
|
|
6890
|
+
el = document.createElement("div");
|
|
6891
|
+
el.className = "universal-card-toast-host";
|
|
6892
|
+
hostEl.appendChild(el);
|
|
6893
|
+
}
|
|
6894
|
+
return el;
|
|
6895
|
+
};
|
|
6896
|
+
const push = (type) => (opts) => {
|
|
6897
|
+
const host = ensureHost();
|
|
6898
|
+
if (!host || typeof document === "undefined") return;
|
|
6899
|
+
const wrap = document.createElement("div");
|
|
6900
|
+
wrap.style.cssText = "display:contents";
|
|
6901
|
+
wrap.innerHTML = renderToastHTML(type, opts);
|
|
6902
|
+
const toastEl = wrap.firstElementChild;
|
|
6903
|
+
host.appendChild(toastEl);
|
|
6904
|
+
const showTime = opts.showTime ?? DEFAULT_SHOW_TIME;
|
|
6905
|
+
setTimeout(() => {
|
|
6906
|
+
toastEl.classList.add("universal-card-toast--leave");
|
|
6907
|
+
toastEl.addEventListener("animationend", () => toastEl.remove(), { once: true });
|
|
6908
|
+
setTimeout(() => toastEl.remove(), 400);
|
|
6909
|
+
}, showTime);
|
|
6910
|
+
};
|
|
6911
|
+
return {
|
|
6912
|
+
success: push("success"),
|
|
6913
|
+
info: push("info"),
|
|
6914
|
+
warning: push("warning"),
|
|
6915
|
+
error: push("error"),
|
|
6916
|
+
destroy: () => {
|
|
6917
|
+
hostEl?.querySelectorAll(".universal-card-toast-host .universal-card-toast").forEach((el) => el.remove());
|
|
6918
|
+
}
|
|
6919
|
+
};
|
|
6920
|
+
}
|
|
6921
|
+
|
|
6819
6922
|
// src/remote.ts
|
|
6820
6923
|
var DEFAULT_API_BASE = "https://open.feishu.cn/open-apis/im/v1";
|
|
6821
6924
|
function getFetch(options) {
|
|
@@ -7072,6 +7175,7 @@ exports.HEADER_BG_LIGHT = HEADER_BG_LIGHT;
|
|
|
7072
7175
|
exports.ICON_CODEPOINTS = ICON_CODEPOINTS;
|
|
7073
7176
|
exports.ICON_FONT_CSS = ICON_FONT_CSS;
|
|
7074
7177
|
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
7178
|
+
exports.createToastHost = createToastHost;
|
|
7075
7179
|
exports.feishuAudioHydrateJs = feishuAudioHydrateJs;
|
|
7076
7180
|
exports.feishuAudioHydrateScript = feishuAudioHydrateScript;
|
|
7077
7181
|
exports.feishuCardStyleTag = feishuCardStyleTag;
|
|
@@ -7095,3 +7199,4 @@ exports.renderCardToStringAsync = renderCardToStringAsync;
|
|
|
7095
7199
|
exports.renderDsl = renderDsl;
|
|
7096
7200
|
exports.renderDslToString = renderDslToString;
|
|
7097
7201
|
exports.renderFeishuChart = renderFeishuChart;
|
|
7202
|
+
exports.renderToastHTML = renderToastHTML;
|
package/dist/index.d.cts
CHANGED
|
@@ -606,6 +606,45 @@ declare function feishuAudioHydrateJs(): string;
|
|
|
606
606
|
*/
|
|
607
607
|
declare const CHART_PALETTE: string[];
|
|
608
608
|
|
|
609
|
+
/**
|
|
610
|
+
* Toast 宿主(对齐飞书客户端 kernel.toast)。
|
|
611
|
+
*
|
|
612
|
+
* 事实依据(feishu-card-extract,pcsdk 7.72.0):
|
|
613
|
+
* - 卡片 action 请求响应里带 `toast: { code, content, ... }`(如复制成功、表单校验失败、
|
|
614
|
+
* 错误码提示),Kernel 收到后调 `options.toast.success/info/warning/error` 弹出。
|
|
615
|
+
* - 调用形态:`{ type: "TOAST_SUCCESS", content, showTime: 2e3, maxLines: 1 }`。
|
|
616
|
+
* - DOM 为 `.ud__toast.ud__notice`:顶部下拉动画(translateY(-100%)→0)、
|
|
617
|
+
* max-width:600px、box-shadow、margin-bottom:16px、top:32px。
|
|
618
|
+
*
|
|
619
|
+
* renderer 是 SSR 字符串渲染器,此处提供浏览器侧 toast 宿主:预览交互里模拟
|
|
620
|
+
* action 响应(如按钮点击回调)时调用对应方法,视觉与客户端一致。
|
|
621
|
+
*/
|
|
622
|
+
type ToastType = 'success' | 'info' | 'warning' | 'error';
|
|
623
|
+
interface ToastOptions {
|
|
624
|
+
/** toast 文本内容 */
|
|
625
|
+
content: string;
|
|
626
|
+
/** 显示时长 ms,默认 2000(客户端 showTime 常见值 2e3) */
|
|
627
|
+
showTime?: number;
|
|
628
|
+
/** 最大行数,超出截断省略,默认 1(客户端 maxLines:1) */
|
|
629
|
+
maxLines?: number;
|
|
630
|
+
}
|
|
631
|
+
interface ToastAPI {
|
|
632
|
+
success: (opts: ToastOptions) => void;
|
|
633
|
+
info: (opts: ToastOptions) => void;
|
|
634
|
+
warning: (opts: ToastOptions) => void;
|
|
635
|
+
error: (opts: ToastOptions) => void;
|
|
636
|
+
/** 清空当前所有 toast */
|
|
637
|
+
destroy: () => void;
|
|
638
|
+
}
|
|
639
|
+
/** 生成单个 toast 的 HTML 字符串(纯函数,SSR/测试可用) */
|
|
640
|
+
declare function renderToastHTML(type: ToastType, opts: ToastOptions): string;
|
|
641
|
+
/**
|
|
642
|
+
* 创建 toast 宿主(浏览器侧)。容器挂在 container(默认 document.body),
|
|
643
|
+
* fixed 顶部居中;每次调用追加一条 toast,showTime 后自动移除。
|
|
644
|
+
* Node/SSR 环境无 DOM 时返回 no-op API(不抛错),仅可用 renderToastHTML。
|
|
645
|
+
*/
|
|
646
|
+
declare function createToastHost(container?: HTMLElement | null): ToastAPI;
|
|
647
|
+
|
|
609
648
|
/**
|
|
610
649
|
* 异步渲染:用飞书 access token 自动拉取卡片图片并内联(data URI),
|
|
611
650
|
* 或直接按 message_id 把整条消息拉回来再渲染。
|
|
@@ -681,4 +720,4 @@ declare function renderDslToString(dsl: unknown, options?: RenderOptions): strin
|
|
|
681
720
|
/** 输入公开 DSL,渲染为真实 DOM 节点(浏览器)。= renderCard(dslToRaw(dsl)) */
|
|
682
721
|
declare function renderDsl(dsl: unknown, options?: RenderOptions): Node;
|
|
683
722
|
|
|
684
|
-
export { ALL_CSS, AUDIO_HYDRATED_ATTR, AUDIO_PAUSE_ICON_SVG, AUDIO_PLAY_ICON_SVG, type AsyncRenderOptions, type AtUserInfo, type BoxSpacing, CHART_HYDRATED_ATTR, CHART_PALETTE, CHART_SPEC_ATTR, type CardElement, type CardInput, type CardMessageInput, type ComponentFn, EMOJI_KEY_TO_NAME, EMOJI_SPRITE_CSS, type ElementProperty, type FetchedCardMessage, HEADER_BG_DARK, HEADER_BG_LIGHT, type HeaderTemplate, ICON_CODEPOINTS, ICON_FONT_CSS, type JsonAttachment, type JsonCard, type LinkURL, type ListItem, type MessageMention, type NamedColor, type PersonInfo, type RenderContext, type RenderOptions, type SizeName, type TableColumn, type TableHeaderStyle, type TextAlign, type TextAttribute, type TextStyle, type VNode, type VNodeChild, type VNodeProps, arrayBufferToBase64, feishuAudioHydrateJs, feishuAudioHydrateScript, feishuCardStyleTag, feishuChartHydrateJs, feishuChartHydrateScript, fetchCardMessage, fetchImageDataUri, getComponent, h, hydrateFeishuAudios, hydrateFeishuCharts, mergeMentionsIntoPersons, parseInline, parseMarkdown, prefetchImages, registerComponent, renderCard, renderCardAsync, renderCardToString, renderCardToStringAsync, renderDsl, renderDslToString, renderFeishuChart };
|
|
723
|
+
export { ALL_CSS, AUDIO_HYDRATED_ATTR, AUDIO_PAUSE_ICON_SVG, AUDIO_PLAY_ICON_SVG, type AsyncRenderOptions, type AtUserInfo, type BoxSpacing, CHART_HYDRATED_ATTR, CHART_PALETTE, CHART_SPEC_ATTR, type CardElement, type CardInput, type CardMessageInput, type ComponentFn, EMOJI_KEY_TO_NAME, EMOJI_SPRITE_CSS, type ElementProperty, type FetchedCardMessage, HEADER_BG_DARK, HEADER_BG_LIGHT, type HeaderTemplate, ICON_CODEPOINTS, ICON_FONT_CSS, type JsonAttachment, type JsonCard, type LinkURL, type ListItem, type MessageMention, type NamedColor, type PersonInfo, type RenderContext, type RenderOptions, type SizeName, type TableColumn, type TableHeaderStyle, type TextAlign, type TextAttribute, type TextStyle, type ToastAPI, type ToastOptions, type ToastType, type VNode, type VNodeChild, type VNodeProps, arrayBufferToBase64, createToastHost, feishuAudioHydrateJs, feishuAudioHydrateScript, feishuCardStyleTag, feishuChartHydrateJs, feishuChartHydrateScript, fetchCardMessage, fetchImageDataUri, getComponent, h, hydrateFeishuAudios, hydrateFeishuCharts, mergeMentionsIntoPersons, parseInline, parseMarkdown, prefetchImages, registerComponent, renderCard, renderCardAsync, renderCardToString, renderCardToStringAsync, renderDsl, renderDslToString, renderFeishuChart, renderToastHTML };
|
package/dist/index.d.ts
CHANGED
|
@@ -606,6 +606,45 @@ declare function feishuAudioHydrateJs(): string;
|
|
|
606
606
|
*/
|
|
607
607
|
declare const CHART_PALETTE: string[];
|
|
608
608
|
|
|
609
|
+
/**
|
|
610
|
+
* Toast 宿主(对齐飞书客户端 kernel.toast)。
|
|
611
|
+
*
|
|
612
|
+
* 事实依据(feishu-card-extract,pcsdk 7.72.0):
|
|
613
|
+
* - 卡片 action 请求响应里带 `toast: { code, content, ... }`(如复制成功、表单校验失败、
|
|
614
|
+
* 错误码提示),Kernel 收到后调 `options.toast.success/info/warning/error` 弹出。
|
|
615
|
+
* - 调用形态:`{ type: "TOAST_SUCCESS", content, showTime: 2e3, maxLines: 1 }`。
|
|
616
|
+
* - DOM 为 `.ud__toast.ud__notice`:顶部下拉动画(translateY(-100%)→0)、
|
|
617
|
+
* max-width:600px、box-shadow、margin-bottom:16px、top:32px。
|
|
618
|
+
*
|
|
619
|
+
* renderer 是 SSR 字符串渲染器,此处提供浏览器侧 toast 宿主:预览交互里模拟
|
|
620
|
+
* action 响应(如按钮点击回调)时调用对应方法,视觉与客户端一致。
|
|
621
|
+
*/
|
|
622
|
+
type ToastType = 'success' | 'info' | 'warning' | 'error';
|
|
623
|
+
interface ToastOptions {
|
|
624
|
+
/** toast 文本内容 */
|
|
625
|
+
content: string;
|
|
626
|
+
/** 显示时长 ms,默认 2000(客户端 showTime 常见值 2e3) */
|
|
627
|
+
showTime?: number;
|
|
628
|
+
/** 最大行数,超出截断省略,默认 1(客户端 maxLines:1) */
|
|
629
|
+
maxLines?: number;
|
|
630
|
+
}
|
|
631
|
+
interface ToastAPI {
|
|
632
|
+
success: (opts: ToastOptions) => void;
|
|
633
|
+
info: (opts: ToastOptions) => void;
|
|
634
|
+
warning: (opts: ToastOptions) => void;
|
|
635
|
+
error: (opts: ToastOptions) => void;
|
|
636
|
+
/** 清空当前所有 toast */
|
|
637
|
+
destroy: () => void;
|
|
638
|
+
}
|
|
639
|
+
/** 生成单个 toast 的 HTML 字符串(纯函数,SSR/测试可用) */
|
|
640
|
+
declare function renderToastHTML(type: ToastType, opts: ToastOptions): string;
|
|
641
|
+
/**
|
|
642
|
+
* 创建 toast 宿主(浏览器侧)。容器挂在 container(默认 document.body),
|
|
643
|
+
* fixed 顶部居中;每次调用追加一条 toast,showTime 后自动移除。
|
|
644
|
+
* Node/SSR 环境无 DOM 时返回 no-op API(不抛错),仅可用 renderToastHTML。
|
|
645
|
+
*/
|
|
646
|
+
declare function createToastHost(container?: HTMLElement | null): ToastAPI;
|
|
647
|
+
|
|
609
648
|
/**
|
|
610
649
|
* 异步渲染:用飞书 access token 自动拉取卡片图片并内联(data URI),
|
|
611
650
|
* 或直接按 message_id 把整条消息拉回来再渲染。
|
|
@@ -681,4 +720,4 @@ declare function renderDslToString(dsl: unknown, options?: RenderOptions): strin
|
|
|
681
720
|
/** 输入公开 DSL,渲染为真实 DOM 节点(浏览器)。= renderCard(dslToRaw(dsl)) */
|
|
682
721
|
declare function renderDsl(dsl: unknown, options?: RenderOptions): Node;
|
|
683
722
|
|
|
684
|
-
export { ALL_CSS, AUDIO_HYDRATED_ATTR, AUDIO_PAUSE_ICON_SVG, AUDIO_PLAY_ICON_SVG, type AsyncRenderOptions, type AtUserInfo, type BoxSpacing, CHART_HYDRATED_ATTR, CHART_PALETTE, CHART_SPEC_ATTR, type CardElement, type CardInput, type CardMessageInput, type ComponentFn, EMOJI_KEY_TO_NAME, EMOJI_SPRITE_CSS, type ElementProperty, type FetchedCardMessage, HEADER_BG_DARK, HEADER_BG_LIGHT, type HeaderTemplate, ICON_CODEPOINTS, ICON_FONT_CSS, type JsonAttachment, type JsonCard, type LinkURL, type ListItem, type MessageMention, type NamedColor, type PersonInfo, type RenderContext, type RenderOptions, type SizeName, type TableColumn, type TableHeaderStyle, type TextAlign, type TextAttribute, type TextStyle, type VNode, type VNodeChild, type VNodeProps, arrayBufferToBase64, feishuAudioHydrateJs, feishuAudioHydrateScript, feishuCardStyleTag, feishuChartHydrateJs, feishuChartHydrateScript, fetchCardMessage, fetchImageDataUri, getComponent, h, hydrateFeishuAudios, hydrateFeishuCharts, mergeMentionsIntoPersons, parseInline, parseMarkdown, prefetchImages, registerComponent, renderCard, renderCardAsync, renderCardToString, renderCardToStringAsync, renderDsl, renderDslToString, renderFeishuChart };
|
|
723
|
+
export { ALL_CSS, AUDIO_HYDRATED_ATTR, AUDIO_PAUSE_ICON_SVG, AUDIO_PLAY_ICON_SVG, type AsyncRenderOptions, type AtUserInfo, type BoxSpacing, CHART_HYDRATED_ATTR, CHART_PALETTE, CHART_SPEC_ATTR, type CardElement, type CardInput, type CardMessageInput, type ComponentFn, EMOJI_KEY_TO_NAME, EMOJI_SPRITE_CSS, type ElementProperty, type FetchedCardMessage, HEADER_BG_DARK, HEADER_BG_LIGHT, type HeaderTemplate, ICON_CODEPOINTS, ICON_FONT_CSS, type JsonAttachment, type JsonCard, type LinkURL, type ListItem, type MessageMention, type NamedColor, type PersonInfo, type RenderContext, type RenderOptions, type SizeName, type TableColumn, type TableHeaderStyle, type TextAlign, type TextAttribute, type TextStyle, type ToastAPI, type ToastOptions, type ToastType, type VNode, type VNodeChild, type VNodeProps, arrayBufferToBase64, createToastHost, feishuAudioHydrateJs, feishuAudioHydrateScript, feishuCardStyleTag, feishuChartHydrateJs, feishuChartHydrateScript, fetchCardMessage, fetchImageDataUri, getComponent, h, hydrateFeishuAudios, hydrateFeishuCharts, mergeMentionsIntoPersons, parseInline, parseMarkdown, prefetchImages, registerComponent, renderCard, renderCardAsync, renderCardToString, renderCardToStringAsync, renderDsl, renderDslToString, renderFeishuChart, renderToastHTML };
|
package/dist/index.js
CHANGED
|
@@ -2016,6 +2016,55 @@ var BASE_STYLES_CSS = `/**
|
|
|
2016
2016
|
}
|
|
2017
2017
|
.universal-card-root.theme-dark .universal-card-markdown { color: #d6d6d6; }
|
|
2018
2018
|
.universal-card-root.theme-dark .universal-card-hr { background-color: #2e2e30; }
|
|
2019
|
+
|
|
2020
|
+
/* ---- Toast \u5BBF\u4E3B\uFF08\u5BF9\u9F50\u5BA2\u6237\u7AEF .ud__toast.ud__notice\uFF1A\u9876\u90E8\u4E0B\u62C9\u3001\u6DF1\u8272\u80F6\u56CA\uFF09 ---- */
|
|
2021
|
+
.universal-card-toast-host {
|
|
2022
|
+
position: fixed;
|
|
2023
|
+
top: 32px; /* \u5BA2\u6237\u7AEF\u7EC4\u4EF6\u914D\u7F6E toast:{top:32} */
|
|
2024
|
+
left: 50%;
|
|
2025
|
+
transform: translateX(-50%);
|
|
2026
|
+
display: flex;
|
|
2027
|
+
flex-direction: column;
|
|
2028
|
+
align-items: center;
|
|
2029
|
+
z-index: 300;
|
|
2030
|
+
pointer-events: none;
|
|
2031
|
+
}
|
|
2032
|
+
.universal-card-toast {
|
|
2033
|
+
display: inline-flex;
|
|
2034
|
+
align-items: center;
|
|
2035
|
+
gap: 8px;
|
|
2036
|
+
max-width: 600px; /* \u5BA2\u6237\u7AEF .ud__toast max-width:600px */
|
|
2037
|
+
padding: 10px 16px;
|
|
2038
|
+
border-radius: 8px;
|
|
2039
|
+
background: rgba(31, 35, 41, 0.92); /* N900 \u6DF1\u8272\u534A\u900F\u660E\uFF0C\u767D\u5B57 */
|
|
2040
|
+
color: #fff;
|
|
2041
|
+
font-size: 14px;
|
|
2042
|
+
line-height: 1.5;
|
|
2043
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
|
|
2044
|
+
margin-bottom: 16px; /* \u5BA2\u6237\u7AEF .ud__toast margin-bottom:16px */
|
|
2045
|
+
animation: universal-card-toast-in 0.3s cubic-bezier(0.2, 0, 0, 1);
|
|
2046
|
+
}
|
|
2047
|
+
.universal-card-toast--leave {
|
|
2048
|
+
animation: universal-card-toast-out 0.3s cubic-bezier(0.2, 0, 0, 1) forwards;
|
|
2049
|
+
}
|
|
2050
|
+
.universal-card-toast__icon {
|
|
2051
|
+
flex: none;
|
|
2052
|
+
display: inline-flex;
|
|
2053
|
+
}
|
|
2054
|
+
.universal-card-toast__text {
|
|
2055
|
+
display: -webkit-box;
|
|
2056
|
+
-webkit-box-orient: vertical;
|
|
2057
|
+
overflow: hidden;
|
|
2058
|
+
word-break: break-word;
|
|
2059
|
+
}
|
|
2060
|
+
@keyframes universal-card-toast-in {
|
|
2061
|
+
from { opacity: 0; transform: translateY(-100%); }
|
|
2062
|
+
to { opacity: 1; transform: translateY(0); }
|
|
2063
|
+
}
|
|
2064
|
+
@keyframes universal-card-toast-out {
|
|
2065
|
+
from { opacity: 1; transform: translateY(0); }
|
|
2066
|
+
to { opacity: 0; transform: translateY(-100%); margin-bottom: 0; }
|
|
2067
|
+
}
|
|
2019
2068
|
`;
|
|
2020
2069
|
|
|
2021
2070
|
// src/icon-font.ts
|
|
@@ -6815,6 +6864,60 @@ function feishuCardStyleTag() {
|
|
|
6815
6864
|
return `<style data-feishu-card>${ALL_CSS}</style>`;
|
|
6816
6865
|
}
|
|
6817
6866
|
|
|
6867
|
+
// src/toast.ts
|
|
6868
|
+
var DEFAULT_SHOW_TIME = 2e3;
|
|
6869
|
+
var TYPE_ICON = {
|
|
6870
|
+
success: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#34c724"/><path d="M4.5 8.2l2.2 2.2 4.8-4.8" fill="none" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
6871
|
+
info: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#3370ff"/><circle cx="8" cy="4.6" r="1" fill="#fff"/><rect x="7.2" y="7" width="1.6" height="4.2" rx="0.8" fill="#fff"/></svg>',
|
|
6872
|
+
warning: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#fad355"/><rect x="7.2" y="3.8" width="1.6" height="4.6" rx="0.8" fill="#1f2329"/><circle cx="8" cy="11.8" r="1" fill="#1f2329"/></svg>',
|
|
6873
|
+
error: '<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="7" fill="#f54a45"/><path d="M5.6 5.6l4.8 4.8M10.4 5.6l-4.8 4.8" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/></svg>'
|
|
6874
|
+
};
|
|
6875
|
+
function escapeHTML(s) {
|
|
6876
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
6877
|
+
}
|
|
6878
|
+
function renderToastHTML(type, opts) {
|
|
6879
|
+
const maxLines = opts.maxLines ?? 1;
|
|
6880
|
+
const styleAttr = maxLines > 1 ? ` style="-webkit-line-clamp:${maxLines};"` : "";
|
|
6881
|
+
return `<div class="universal-card-toast universal-card-toast--${type}" role="status" aria-live="polite"><span class="universal-card-toast__icon">${TYPE_ICON[type]}</span><span class="universal-card-toast__text"${styleAttr}>${escapeHTML(opts.content)}</span></div>`;
|
|
6882
|
+
}
|
|
6883
|
+
function createToastHost(container) {
|
|
6884
|
+
const hostEl = typeof document === "undefined" ? null : container ?? document.body;
|
|
6885
|
+
const ensureHost = () => {
|
|
6886
|
+
if (!hostEl) return null;
|
|
6887
|
+
let el = hostEl.querySelector(".universal-card-toast-host");
|
|
6888
|
+
if (!el) {
|
|
6889
|
+
el = document.createElement("div");
|
|
6890
|
+
el.className = "universal-card-toast-host";
|
|
6891
|
+
hostEl.appendChild(el);
|
|
6892
|
+
}
|
|
6893
|
+
return el;
|
|
6894
|
+
};
|
|
6895
|
+
const push = (type) => (opts) => {
|
|
6896
|
+
const host = ensureHost();
|
|
6897
|
+
if (!host || typeof document === "undefined") return;
|
|
6898
|
+
const wrap = document.createElement("div");
|
|
6899
|
+
wrap.style.cssText = "display:contents";
|
|
6900
|
+
wrap.innerHTML = renderToastHTML(type, opts);
|
|
6901
|
+
const toastEl = wrap.firstElementChild;
|
|
6902
|
+
host.appendChild(toastEl);
|
|
6903
|
+
const showTime = opts.showTime ?? DEFAULT_SHOW_TIME;
|
|
6904
|
+
setTimeout(() => {
|
|
6905
|
+
toastEl.classList.add("universal-card-toast--leave");
|
|
6906
|
+
toastEl.addEventListener("animationend", () => toastEl.remove(), { once: true });
|
|
6907
|
+
setTimeout(() => toastEl.remove(), 400);
|
|
6908
|
+
}, showTime);
|
|
6909
|
+
};
|
|
6910
|
+
return {
|
|
6911
|
+
success: push("success"),
|
|
6912
|
+
info: push("info"),
|
|
6913
|
+
warning: push("warning"),
|
|
6914
|
+
error: push("error"),
|
|
6915
|
+
destroy: () => {
|
|
6916
|
+
hostEl?.querySelectorAll(".universal-card-toast-host .universal-card-toast").forEach((el) => el.remove());
|
|
6917
|
+
}
|
|
6918
|
+
};
|
|
6919
|
+
}
|
|
6920
|
+
|
|
6818
6921
|
// src/remote.ts
|
|
6819
6922
|
var DEFAULT_API_BASE = "https://open.feishu.cn/open-apis/im/v1";
|
|
6820
6923
|
function getFetch(options) {
|
|
@@ -7053,4 +7156,4 @@ function renderDsl(dsl, options = {}) {
|
|
|
7053
7156
|
return renderCard(dslToRaw(dsl), options);
|
|
7054
7157
|
}
|
|
7055
7158
|
|
|
7056
|
-
export { ALL_CSS, AUDIO_HYDRATED_ATTR, AUDIO_PAUSE_ICON_SVG, AUDIO_PLAY_ICON_SVG, CHART_HYDRATED_ATTR, CHART_PALETTE, CHART_SPEC_ATTR, EMOJI_KEY_TO_NAME, EMOJI_SPRITE_CSS, HEADER_BG_DARK, HEADER_BG_LIGHT, ICON_CODEPOINTS, ICON_FONT_CSS, arrayBufferToBase64, feishuAudioHydrateJs, feishuAudioHydrateScript, feishuCardStyleTag, feishuChartHydrateJs, feishuChartHydrateScript, fetchCardMessage, fetchImageDataUri, getComponent, h, hydrateFeishuAudios, hydrateFeishuCharts, mergeMentionsIntoPersons, parseInline, parseMarkdown, prefetchImages, registerComponent, renderCard, renderCardAsync, renderCardToString, renderCardToStringAsync, renderDsl, renderDslToString, renderFeishuChart };
|
|
7159
|
+
export { ALL_CSS, AUDIO_HYDRATED_ATTR, AUDIO_PAUSE_ICON_SVG, AUDIO_PLAY_ICON_SVG, CHART_HYDRATED_ATTR, CHART_PALETTE, CHART_SPEC_ATTR, EMOJI_KEY_TO_NAME, EMOJI_SPRITE_CSS, HEADER_BG_DARK, HEADER_BG_LIGHT, ICON_CODEPOINTS, ICON_FONT_CSS, arrayBufferToBase64, createToastHost, feishuAudioHydrateJs, feishuAudioHydrateScript, feishuCardStyleTag, feishuChartHydrateJs, feishuChartHydrateScript, fetchCardMessage, fetchImageDataUri, getComponent, h, hydrateFeishuAudios, hydrateFeishuCharts, mergeMentionsIntoPersons, parseInline, parseMarkdown, prefetchImages, registerComponent, renderCard, renderCardAsync, renderCardToString, renderCardToStringAsync, renderDsl, renderDslToString, renderFeishuChart, renderToastHTML };
|
package/dist/styles.css
CHANGED
|
@@ -1049,3 +1049,52 @@
|
|
|
1049
1049
|
}
|
|
1050
1050
|
.universal-card-root.theme-dark .universal-card-markdown { color: #d6d6d6; }
|
|
1051
1051
|
.universal-card-root.theme-dark .universal-card-hr { background-color: #2e2e30; }
|
|
1052
|
+
|
|
1053
|
+
/* ---- Toast 宿主(对齐客户端 .ud__toast.ud__notice:顶部下拉、深色胶囊) ---- */
|
|
1054
|
+
.universal-card-toast-host {
|
|
1055
|
+
position: fixed;
|
|
1056
|
+
top: 32px; /* 客户端组件配置 toast:{top:32} */
|
|
1057
|
+
left: 50%;
|
|
1058
|
+
transform: translateX(-50%);
|
|
1059
|
+
display: flex;
|
|
1060
|
+
flex-direction: column;
|
|
1061
|
+
align-items: center;
|
|
1062
|
+
z-index: 300;
|
|
1063
|
+
pointer-events: none;
|
|
1064
|
+
}
|
|
1065
|
+
.universal-card-toast {
|
|
1066
|
+
display: inline-flex;
|
|
1067
|
+
align-items: center;
|
|
1068
|
+
gap: 8px;
|
|
1069
|
+
max-width: 600px; /* 客户端 .ud__toast max-width:600px */
|
|
1070
|
+
padding: 10px 16px;
|
|
1071
|
+
border-radius: 8px;
|
|
1072
|
+
background: rgba(31, 35, 41, 0.92); /* N900 深色半透明,白字 */
|
|
1073
|
+
color: #fff;
|
|
1074
|
+
font-size: 14px;
|
|
1075
|
+
line-height: 1.5;
|
|
1076
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
|
|
1077
|
+
margin-bottom: 16px; /* 客户端 .ud__toast margin-bottom:16px */
|
|
1078
|
+
animation: universal-card-toast-in 0.3s cubic-bezier(0.2, 0, 0, 1);
|
|
1079
|
+
}
|
|
1080
|
+
.universal-card-toast--leave {
|
|
1081
|
+
animation: universal-card-toast-out 0.3s cubic-bezier(0.2, 0, 0, 1) forwards;
|
|
1082
|
+
}
|
|
1083
|
+
.universal-card-toast__icon {
|
|
1084
|
+
flex: none;
|
|
1085
|
+
display: inline-flex;
|
|
1086
|
+
}
|
|
1087
|
+
.universal-card-toast__text {
|
|
1088
|
+
display: -webkit-box;
|
|
1089
|
+
-webkit-box-orient: vertical;
|
|
1090
|
+
overflow: hidden;
|
|
1091
|
+
word-break: break-word;
|
|
1092
|
+
}
|
|
1093
|
+
@keyframes universal-card-toast-in {
|
|
1094
|
+
from { opacity: 0; transform: translateY(-100%); }
|
|
1095
|
+
to { opacity: 1; transform: translateY(0); }
|
|
1096
|
+
}
|
|
1097
|
+
@keyframes universal-card-toast-out {
|
|
1098
|
+
from { opacity: 1; transform: translateY(0); }
|
|
1099
|
+
to { opacity: 0; transform: translateY(-100%); margin-bottom: 0; }
|
|
1100
|
+
}
|