@agentscope-ai/design 1.0.26-beta.1768893648373 → 1.0.26-beta.1769162388973

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.
@@ -1,7 +1,7 @@
1
1
  var _templateObject;
2
2
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
3
  import createGlobalStyle from "../../../libs/createStyle";
4
- export var useStyle = createGlobalStyle(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n.", "-media-player-controller {\n display: flex;\n padding: 8px;\n gap: 8px;\n align-items: center;\n width: 100%;\n height: 40px;\n overflow: hidden;\n}\n\n// \u65F6\u95F4\u6587\u672C\u6837\u5F0F\n.", "-media-time-text {\n flex-grow: 0;\n font-size: 12px;\n line-height: 20px;\n}\n\n// \u8FDB\u5EA6\u6761\u5BB9\u5668\u6837\u5F0F\n.", "-media-progress-container {\n flex-grow: 1;\n cursor: pointer;\n}\n\n// \u8FDB\u5EA6\u6761\u6837\u5F0F\n.", "-media-progress-bar {\n width: 100%;\n\n .", "-progress-bg {\n transition-duration: 0s;\n }\n}\n"])), function (p) {
4
+ export var useStyle = createGlobalStyle(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n.", "-media-player-controller {\n display: flex;\n padding: 8px;\n gap: 8px;\n align-items: center;\n width: 100%;\n height: 40px;\n overflow: hidden;\n}\n\n// \u65F6\u95F4\u6587\u672C\u6837\u5F0F\n.", "-media-time-text {\n flex-grow: 0;\n font-size: 12px;\n line-height: 20px;\n}\n\n// \u8FDB\u5EA6\u6761\u5BB9\u5668\u6837\u5F0F\n.", "-media-progress-container {\n flex-grow: 1;\n cursor: pointer;\n\n}\n\n// \u8FDB\u5EA6\u6761\u6837\u5F0F\n.", "-media-progress-bar {\n display: flex;\n align-items: center;\n width: 100%;\n\n .", "-progress-bg {\n transition-duration: 0s;\n }\n}\n"])), function (p) {
5
5
  return p.sparkPrefix;
6
6
  }, function (p) {
7
7
  return p.sparkPrefix;
@@ -1,3 +1,7 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
1
5
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
6
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
7
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -7,7 +11,48 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
11
  import useToken from 'antd/es/theme/useToken';
8
12
  import { useEffect, useState } from 'react';
9
13
  import { jsx as _jsx } from "react/jsx-runtime";
10
- var svgContainer = document.querySelector('#empty-svg-container');
14
+ var SVG_NS = 'http://www.w3.org/2000/svg';
15
+ var XLINK_NS = 'http://www.w3.org/1999/xlink';
16
+
17
+ // 避免多实例并发注入时互相覆盖:用任务 Map 去重同一个 svgId 的加载
18
+ var svgSymbolTasks = new Map();
19
+ var svgContainer = null;
20
+ if (typeof document !== 'undefined') {
21
+ svgContainer = document.querySelector('#empty-svg-container');
22
+ }
23
+ function escapeRegExp(str) {
24
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
25
+ }
26
+ function toBase64Url(input) {
27
+ // btoa 仅支持 latin1,这里 input 是 URL(ascii),可直接使用
28
+ // 转成 base64url,避免 id 中出现 + / =
29
+ return btoa(input).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
30
+ }
31
+ function ensureSvgContainer() {
32
+ if (svgContainer || typeof document === 'undefined') return svgContainer;
33
+ var container = document.createElement('div');
34
+ container.innerHTML = '<svg></svg>';
35
+ svgContainer = container.querySelector('svg');
36
+ svgContainer.id = 'empty-svg-container';
37
+ svgContainer.setAttribute('aria-hidden', 'true');
38
+ svgContainer.style.position = 'absolute';
39
+ svgContainer.style.width = '0';
40
+ svgContainer.style.height = '0';
41
+ svgContainer.style.overflow = 'hidden';
42
+ document.body.insertBefore(svgContainer, document.body.firstChild);
43
+ return svgContainer;
44
+ }
45
+ function ensureSymbol(svgId) {
46
+ if (!svgContainer) return null;
47
+ var existed = document.getElementById(svgId);
48
+ var symbol = existed || null;
49
+ if (symbol) return symbol;
50
+ symbol = document.createElementNS(SVG_NS, 'symbol');
51
+ symbol.id = svgId;
52
+ symbol.setAttribute('data-loaded', 'false');
53
+ svgContainer.appendChild(symbol);
54
+ return symbol;
55
+ }
11
56
  export default function Illustrate(props) {
12
57
  var _useToken = useToken(),
13
58
  _useToken2 = _slicedToArray(_useToken, 5),
@@ -23,18 +68,7 @@ export default function Illustrate(props) {
23
68
  svgString = _useState2[0],
24
69
  setSvgString = _useState2[1];
25
70
  useEffect(function () {
26
- if (!svgContainer) {
27
- var container = document.createElement('div');
28
- container.innerHTML = '<svg></svg>';
29
- svgContainer = container.querySelector('svg');
30
- svgContainer.id = 'empty-svg-container';
31
- svgContainer.setAttribute('aria-hidden', 'true');
32
- svgContainer.style.position = 'absolute';
33
- svgContainer.style.width = '0';
34
- svgContainer.style.height = '0';
35
- svgContainer.style.overflow = 'hidden';
36
- document.body.insertBefore(svgContainer, document.body.firstChild);
37
- }
71
+ ensureSvgContainer();
38
72
  }, []);
39
73
  useEffect(function () {
40
74
  if (svgContainer && cssVar !== null && cssVar !== void 0 && cssVar.key) {
@@ -48,33 +82,77 @@ export default function Illustrate(props) {
48
82
  if (!isSvg) {
49
83
  return;
50
84
  }
51
- var svgId = btoa(svgUrl);
52
- var svgString = "<svg><use xlink:href=\"#".concat(svgId, "\"></use></svg>");
53
- setSvgString(svgString);
54
- if (document.getElementById(svgId)) {
55
- return;
56
- }
57
- var symbolStr = "<symbol id=\"".concat(svgId, "\"></symbol>");
58
- svgContainer.innerHTML = svgContainer.innerHTML + symbolStr;
59
- fetch(svgUrl).then(function (res) {
60
- return res.text();
61
- }).then(function (res) {
62
- var str = res;
63
- Object.keys(tokenMap).forEach(function (key) {
64
- str = str.replace(new RegExp(key, 'g'), tokenMap[key]);
65
- });
85
+ ensureSvgContainer();
86
+ if (!svgContainer) return;
87
+ var svgId = toBase64Url(svgUrl);
88
+ setSvgString("<svg width=\"100%\" height=\"100%\"><use href=\"#".concat(svgId, "\" xlink:href=\"#").concat(svgId, "\"></use></svg>"));
89
+ var symbol = ensureSymbol(svgId);
90
+ if (!symbol) return;
66
91
 
67
- // 提取viewBox属性
68
- var viewBoxMatch = str.match(/viewBox="([^"]*)"/);
69
- var viewBox = viewBoxMatch ? viewBoxMatch[1] : '';
70
- var symbolElement = document.getElementById(svgId);
71
- var symbolContentStr = str.replace(/<svg[^>]*>/, '');
72
- symbolContentStr = symbolContentStr.replace(/<\/svg>/, '');
73
- if (viewBox) {
74
- symbolElement.setAttribute('viewBox', viewBox);
75
- }
76
- symbolElement.innerHTML = symbolContentStr;
77
- });
92
+ // 已经加载过,直接复用
93
+ if (symbol.getAttribute('data-loaded') === 'true') return;
94
+
95
+ // 同一个 svgId 的并发请求去重
96
+ if (!svgSymbolTasks.has(svgId)) {
97
+ var task = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
98
+ var res, raw, str, viewBoxMatch, viewBox, symbolContentStr;
99
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
100
+ while (1) switch (_context.prev = _context.next) {
101
+ case 0:
102
+ _context.prev = 0;
103
+ _context.next = 3;
104
+ return fetch(svgUrl);
105
+ case 3:
106
+ res = _context.sent;
107
+ if (res.ok) {
108
+ _context.next = 6;
109
+ break;
110
+ }
111
+ throw new Error("HTTP ".concat(res.status));
112
+ case 6:
113
+ _context.next = 8;
114
+ return res.text();
115
+ case 8:
116
+ raw = _context.sent;
117
+ str = raw;
118
+ Object.keys(tokenMap).forEach(function (key) {
119
+ str = str.replace(new RegExp(escapeRegExp(key), 'g'), tokenMap[key]);
120
+ });
121
+
122
+ // 提取 viewBox
123
+ viewBoxMatch = str.match(/viewBox="([^"]*)"/);
124
+ viewBox = viewBoxMatch ? viewBoxMatch[1] : ''; // 只保留 <svg> 内部内容
125
+ symbolContentStr = str.replace(/<svg[^>]*>/, '');
126
+ symbolContentStr = symbolContentStr.replace(/<\/svg>/, '');
127
+ if (viewBox) {
128
+ symbol.setAttribute('viewBox', viewBox);
129
+ }
130
+
131
+ // 使用 DOM API 写入,避免 innerHTML 触发 svgContainer 重建
132
+ symbol.innerHTML = symbolContentStr;
133
+ symbol.setAttribute('data-loaded', 'true');
134
+ symbol.removeAttribute('data-error');
135
+ _context.next = 27;
136
+ break;
137
+ case 21:
138
+ _context.prev = 21;
139
+ _context.t0 = _context["catch"](0);
140
+ // 失败时保证不会进入“空壳已存在但永远不再加载”的状态
141
+ symbol.setAttribute('data-loaded', 'false');
142
+ symbol.setAttribute('data-error', 'true');
143
+ symbol.innerHTML = '';
144
+ // eslint-disable-next-line no-console
145
+ console.warn('[SparkDesign][Empty][Illustrate] load svg failed:', svgUrl, _context.t0);
146
+ case 27:
147
+ case "end":
148
+ return _context.stop();
149
+ }
150
+ }, _callee, null, [[0, 21]]);
151
+ }))().finally(function () {
152
+ svgSymbolTasks.delete(svgId);
153
+ });
154
+ svgSymbolTasks.set(svgId, task);
155
+ }
78
156
  }, [svgUrl]);
79
157
  if (isSvg) {
80
158
  return /*#__PURE__*/_jsx("div", {
@@ -0,0 +1 @@
1
+ export default function (): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,44 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { Button, MediaPreview } from "../../../..";
8
+ import { useState } from 'react';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { Fragment as _Fragment } from "react/jsx-runtime";
11
+ import { jsxs as _jsxs } from "react/jsx-runtime";
12
+ var mediaList = [{
13
+ type: 'image',
14
+ src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
15
+ alt: 'Image 1'
16
+ }, {
17
+ type: 'video',
18
+ src: 'https://cloud.video.taobao.com/vod/MgaPySDXyyWMT4QM-CWYjX6BlVMGNei259qPTCCQ7ew.mp4',
19
+ alt: 'Video 1'
20
+ }, {
21
+ type: 'image',
22
+ src: 'https://img.alicdn.com/imgextra/i4/O1CN01LwpgZg1DJokMyCkBJ_!!6000000000196-2-tps-312-312.png',
23
+ alt: 'Image 2'
24
+ }];
25
+ export default function () {
26
+ var _useState = useState(false),
27
+ _useState2 = _slicedToArray(_useState, 2),
28
+ visible = _useState2[0],
29
+ setVisible = _useState2[1];
30
+ return /*#__PURE__*/_jsxs(_Fragment, {
31
+ children: [/*#__PURE__*/_jsx(Button, {
32
+ onClick: function onClick() {
33
+ return setVisible(true);
34
+ },
35
+ children: "Open Media Preview"
36
+ }), /*#__PURE__*/_jsx(MediaPreview, {
37
+ visible: visible,
38
+ mediaList: mediaList,
39
+ onClose: function onClose() {
40
+ return setVisible(false);
41
+ }
42
+ })]
43
+ });
44
+ }
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ export interface MediaItem {
3
+ /** 媒体类型 */
4
+ type: 'image' | 'video';
5
+ /** 媒体资源地址 */
6
+ src: string;
7
+ /** 媒体替代文本 */
8
+ alt?: string;
9
+ }
10
+ export interface MediaPreviewProps {
11
+ /** 自定义样式类名 */
12
+ className?: string;
13
+ /** 是否显示预览 */
14
+ visible: boolean;
15
+ /** 媒体列表 */
16
+ mediaList: MediaItem[];
17
+ /** 当前选中的索引 */
18
+ currentIndex?: number;
19
+ /** 关闭回调 */
20
+ onClose: () => void;
21
+ }
22
+ declare const MediaPreview: React.FC<MediaPreviewProps>;
23
+ export default MediaPreview;
@@ -0,0 +1,352 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
11
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
12
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
13
+ import { getCommonConfig, useCommonConfig } from "../../../config";
14
+ import { SparkAmplifyLine, SparkExitFullscreenLine, SparkFalseLine, SparkLeftLine, SparkReduceLine, SparkRightLine } from '@agentscope-ai/icons';
15
+ import { ConfigProvider } from 'antd';
16
+ import classNames from 'classnames';
17
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
18
+ import IconButton from "../IconButton";
19
+ import Video from "../Video";
20
+ import { useStyle } from "./index.style";
21
+ import { jsx as _jsx } from "react/jsx-runtime";
22
+ import { jsxs as _jsxs } from "react/jsx-runtime";
23
+ // 边界校验辅助函数
24
+ var clampIndex = function clampIndex(index, length) {
25
+ return Math.max(0, Math.min(index, length - 1));
26
+ };
27
+ var MediaPreview = function MediaPreview(_ref) {
28
+ var className = _ref.className,
29
+ visible = _ref.visible,
30
+ mediaList = _ref.mediaList,
31
+ _ref$currentIndex = _ref.currentIndex,
32
+ currentIndex = _ref$currentIndex === void 0 ? 0 : _ref$currentIndex,
33
+ onClose = _ref.onClose;
34
+ var _getCommonConfig = getCommonConfig(),
35
+ sparkPrefix = _getCommonConfig.sparkPrefix;
36
+ var _useCommonConfig = useCommonConfig(),
37
+ configProviderProps = _useCommonConfig.configProviderProps;
38
+ var Style = useStyle();
39
+ // 问题2: 添加边界校验
40
+ var _useState = useState(function () {
41
+ return clampIndex(currentIndex, mediaList.length);
42
+ }),
43
+ _useState2 = _slicedToArray(_useState, 2),
44
+ activeIndex = _useState2[0],
45
+ setActiveIndex = _useState2[1];
46
+ var _useState3 = useState(1),
47
+ _useState4 = _slicedToArray(_useState3, 2),
48
+ scale = _useState4[0],
49
+ setScale = _useState4[1];
50
+ var _useState5 = useState({
51
+ width: 960,
52
+ height: 600
53
+ }),
54
+ _useState6 = _slicedToArray(_useState5, 2),
55
+ baseSize = _useState6[0],
56
+ setBaseSize = _useState6[1];
57
+ var _useState7 = useState(false),
58
+ _useState8 = _slicedToArray(_useState7, 2),
59
+ isTransitioning = _useState8[0],
60
+ setIsTransitioning = _useState8[1];
61
+ var containerRef = useRef(null);
62
+
63
+ // 计算基于屏幕大小的基础尺寸
64
+ useEffect(function () {
65
+ var updateBaseSize = function updateBaseSize() {
66
+ // 这里的 0.8 是预留边距比例,可根据需要调整
67
+ var screenWidth = 960;
68
+ var screenHeight = 600;
69
+
70
+ // 最小 960 * 600
71
+ var width = Math.max(screenWidth, 960);
72
+ var height = Math.max(screenHeight, 600);
73
+ setBaseSize({
74
+ width: width,
75
+ height: height
76
+ });
77
+ };
78
+ updateBaseSize();
79
+ window.addEventListener('resize', updateBaseSize);
80
+ return function () {
81
+ return window.removeEventListener('resize', updateBaseSize);
82
+ };
83
+ }, []);
84
+
85
+ // 问题8: 当 currentIndex 变化时更新 activeIndex,添加边界检查和重置 scale
86
+ useEffect(function () {
87
+ var validIndex = clampIndex(currentIndex, mediaList.length);
88
+ setActiveIndex(validIndex);
89
+ setScale(1);
90
+ }, [currentIndex, mediaList.length]);
91
+
92
+ // 当 visible 变化时重置缩放
93
+ useEffect(function () {
94
+ if (visible) {
95
+ setScale(1);
96
+ }
97
+ }, [visible]);
98
+
99
+ // 问题6: 提取公共过渡动画逻辑
100
+ var transitionTo = useCallback(function (getNextIndex) {
101
+ if (isTransitioning) return;
102
+ setIsTransitioning(true);
103
+ setTimeout(function () {
104
+ setActiveIndex(getNextIndex);
105
+ setScale(1);
106
+ setTimeout(function () {
107
+ return setIsTransitioning(false);
108
+ }, 50);
109
+ }, 150);
110
+ }, [isTransitioning]);
111
+
112
+ // 切换到上一张
113
+ var handlePrev = useCallback(function () {
114
+ transitionTo(function (prev) {
115
+ return prev > 0 ? prev - 1 : mediaList.length - 1;
116
+ });
117
+ }, [mediaList.length, transitionTo]);
118
+
119
+ // 切换到下一张
120
+ var handleNext = useCallback(function () {
121
+ transitionTo(function (prev) {
122
+ return prev < mediaList.length - 1 ? prev + 1 : 0;
123
+ });
124
+ }, [mediaList.length, transitionTo]);
125
+
126
+ // 放大
127
+ var handleZoomIn = useCallback(function () {
128
+ setScale(function (prev) {
129
+ return Math.min(prev + 0.25, 3);
130
+ });
131
+ }, []);
132
+
133
+ // 缩小
134
+ var handleZoomOut = useCallback(function () {
135
+ setScale(function (prev) {
136
+ return Math.max(prev - 0.25, 0.5);
137
+ });
138
+ }, []);
139
+
140
+ // 问题7: 分离全屏和重置缩放的职责
141
+ // 进入全屏
142
+ var handleEnterFullscreen = useCallback(function () {
143
+ if (!containerRef.current || document.fullscreenElement) return;
144
+ containerRef.current.requestFullscreen().catch(function (err) {
145
+ console.error("Error attempting to enable full-screen mode: ".concat(err.message, " (").concat(err.name, ")"));
146
+ });
147
+ }, []);
148
+
149
+ // 退出全屏
150
+ var handleExitFullscreen = useCallback(function () {
151
+ if (document.fullscreenElement) {
152
+ document.exitFullscreen();
153
+ }
154
+ }, []);
155
+
156
+ // 切换全屏
157
+ var handleToggleFullscreen = useCallback(function () {
158
+ if (document.fullscreenElement) {
159
+ handleExitFullscreen();
160
+ } else {
161
+ handleEnterFullscreen();
162
+ }
163
+ }, [handleEnterFullscreen, handleExitFullscreen]);
164
+
165
+ // 重置所有状态(缩放 + 退出全屏)
166
+ var handleResetAll = useCallback(function () {
167
+ setScale(1);
168
+ handleExitFullscreen();
169
+ }, [handleExitFullscreen]);
170
+
171
+ // 点击缩略图(复用 transitionTo)
172
+ var handleThumbnailClick = useCallback(function (index) {
173
+ if (index === activeIndex) return;
174
+ transitionTo(function () {
175
+ return index;
176
+ });
177
+ }, [activeIndex, transitionTo]);
178
+
179
+ // 键盘事件
180
+ useEffect(function () {
181
+ if (!visible) return;
182
+ var handleKeyDown = function handleKeyDown(e) {
183
+ switch (e.key) {
184
+ case 'ArrowLeft':
185
+ handlePrev();
186
+ break;
187
+ case 'ArrowRight':
188
+ handleNext();
189
+ break;
190
+ case 'Escape':
191
+ onClose();
192
+ break;
193
+ case '+':
194
+ case '=':
195
+ handleZoomIn();
196
+ break;
197
+ case '-':
198
+ handleZoomOut();
199
+ break;
200
+ case 'f':
201
+ case 'F':
202
+ handleToggleFullscreen();
203
+ break;
204
+ case 'r':
205
+ case 'R':
206
+ handleResetAll();
207
+ break;
208
+ default:
209
+ break;
210
+ }
211
+ };
212
+ window.addEventListener('keydown', handleKeyDown);
213
+ return function () {
214
+ return window.removeEventListener('keydown', handleKeyDown);
215
+ };
216
+ }, [visible, handlePrev, handleNext, onClose, handleZoomIn, handleZoomOut, handleToggleFullscreen, handleResetAll]);
217
+ if (!visible || mediaList.length === 0) {
218
+ return null;
219
+ }
220
+ var currentMedia = mediaList[activeIndex];
221
+ return /*#__PURE__*/_jsxs(ConfigProvider, _objectSpread(_objectSpread({}, configProviderProps), {}, {
222
+ children: [/*#__PURE__*/_jsx(Style, {}), /*#__PURE__*/_jsxs("div", {
223
+ ref: containerRef,
224
+ role: "dialog",
225
+ "aria-modal": "true",
226
+ "aria-label": "\u5A92\u4F53\u9884\u89C8",
227
+ className: classNames("".concat(sparkPrefix, "-media-preview-container"), className),
228
+ children: [/*#__PURE__*/_jsx("div", {
229
+ className: classNames("".concat(sparkPrefix, "-media-preview-main-content"), {
230
+ transitioning: isTransitioning
231
+ }),
232
+ style: {
233
+ width: baseSize.width,
234
+ height: baseSize.height,
235
+ transform: "scale(".concat(scale, ")")
236
+ },
237
+ children: currentMedia.type === 'image' ? /*#__PURE__*/_jsx("img", {
238
+ className: "".concat(sparkPrefix, "-media-preview-main-media"),
239
+ src: currentMedia.src,
240
+ alt: currentMedia.alt || ''
241
+ }) : /*#__PURE__*/_jsx(Video, {
242
+ src: currentMedia.src,
243
+ controls: true
244
+ })
245
+ }), /*#__PURE__*/_jsx(IconButton, {
246
+ className: "".concat(sparkPrefix, "-media-preview-nav-left"),
247
+ onClick: handlePrev,
248
+ "aria-label": "\u4E0A\u4E00\u5F20",
249
+ bordered: false,
250
+ icon: /*#__PURE__*/_jsx(SparkLeftLine, {
251
+ className: "".concat(sparkPrefix, "-media-preview-nav-icon")
252
+ })
253
+ }), /*#__PURE__*/_jsx(IconButton, {
254
+ className: "".concat(sparkPrefix, "-media-preview-nav-right"),
255
+ onClick: handleNext,
256
+ "aria-label": "\u4E0B\u4E00\u5F20",
257
+ bordered: false,
258
+ icon: /*#__PURE__*/_jsx(SparkRightLine, {
259
+ className: "".concat(sparkPrefix, "-media-preview-nav-icon")
260
+ })
261
+ }), /*#__PURE__*/_jsxs("div", {
262
+ className: "".concat(sparkPrefix, "-media-preview-toolbar"),
263
+ role: "toolbar",
264
+ children: [/*#__PURE__*/_jsxs("div", {
265
+ className: "".concat(sparkPrefix, "-media-preview-zoom-controls"),
266
+ children: [/*#__PURE__*/_jsx(IconButton, {
267
+ size: "large",
268
+ "aria-label": "\u653E\u5927",
269
+ className: "".concat(sparkPrefix, "-media-preview-tool-button"),
270
+ onClick: handleZoomIn,
271
+ bordered: false,
272
+ icon: /*#__PURE__*/_jsx(SparkAmplifyLine, {
273
+ className: "".concat(sparkPrefix, "-media-preview-tool-icon")
274
+ })
275
+ }), /*#__PURE__*/_jsx(IconButton, {
276
+ size: "large",
277
+ "aria-label": "\u7F29\u5C0F",
278
+ className: "".concat(sparkPrefix, "-media-preview-tool-button"),
279
+ onClick: handleZoomOut,
280
+ bordered: false,
281
+ icon: /*#__PURE__*/_jsx(SparkReduceLine, {
282
+ className: "".concat(sparkPrefix, "-media-preview-tool-icon")
283
+ })
284
+ }), /*#__PURE__*/_jsx(IconButton, {
285
+ size: "large",
286
+ "aria-label": "\u91CD\u7F6E",
287
+ className: "".concat(sparkPrefix, "-media-preview-tool-button"),
288
+ onClick: handleResetAll,
289
+ bordered: false,
290
+ icon: /*#__PURE__*/_jsx(SparkExitFullscreenLine, {
291
+ className: "".concat(sparkPrefix, "-media-preview-tool-icon")
292
+ })
293
+ })]
294
+ }), /*#__PURE__*/_jsx("div", {
295
+ className: "".concat(sparkPrefix, "-media-preview-zoom-controls"),
296
+ children: /*#__PURE__*/_jsx(IconButton, {
297
+ className: "".concat(sparkPrefix, "-media-preview-close-button"),
298
+ onClick: onClose,
299
+ "aria-label": "\u5173\u95ED\u9884\u89C8",
300
+ bordered: false,
301
+ size: "large",
302
+ icon: /*#__PURE__*/_jsx(SparkFalseLine, {
303
+ className: "".concat(sparkPrefix, "-media-preview-tool-icon")
304
+ })
305
+ })
306
+ })]
307
+ }), /*#__PURE__*/_jsx("div", {
308
+ className: "".concat(sparkPrefix, "-media-preview-thumbnail-carousel"),
309
+ children: /*#__PURE__*/_jsxs("div", {
310
+ className: "".concat(sparkPrefix, "-media-preview-thumbnail-wrapper"),
311
+ children: [/*#__PURE__*/_jsx(IconButton, {
312
+ className: "".concat(sparkPrefix, "-media-preview-thumbnail-nav-icon"),
313
+ onClick: handlePrev,
314
+ "aria-label": "\u4E0A\u4E00\u5F20",
315
+ bordered: false,
316
+ icon: /*#__PURE__*/_jsx(SparkLeftLine, {})
317
+ }), /*#__PURE__*/_jsx("div", {
318
+ className: "".concat(sparkPrefix, "-media-preview-thumbnail-list"),
319
+ children: mediaList.map(function (item, index) {
320
+ return /*#__PURE__*/_jsx("div", {
321
+ className: classNames("".concat(sparkPrefix, "-media-preview-thumbnail-item"), {
322
+ active: index === activeIndex
323
+ }),
324
+ onClick: function onClick() {
325
+ return handleThumbnailClick(index);
326
+ },
327
+ children: item.type === 'image' ? /*#__PURE__*/_jsx("img", {
328
+ src: item.src,
329
+ alt: item.alt || "\u5A92\u4F53 ".concat(index + 1)
330
+ }) :
331
+ /*#__PURE__*/
332
+ // 问题4: 添加 preload 和 muted 优化视频缩略图
333
+ _jsx("video", {
334
+ src: item.src,
335
+ preload: "metadata",
336
+ muted: true
337
+ })
338
+ }, index);
339
+ })
340
+ }), /*#__PURE__*/_jsx(IconButton, {
341
+ className: "".concat(sparkPrefix, "-media-preview-thumbnail-nav-icon"),
342
+ onClick: handleNext,
343
+ "aria-label": "\u4E0B\u4E00\u5F20",
344
+ bordered: false,
345
+ icon: /*#__PURE__*/_jsx(SparkRightLine, {})
346
+ })]
347
+ })
348
+ })]
349
+ })]
350
+ }));
351
+ };
352
+ export default MediaPreview;
@@ -0,0 +1 @@
1
+ export declare const useStyle: () => () => import("react/jsx-runtime").JSX.Element;