@qingwu-ui/scroll-fab 0.9.0-beta.1 → 0.9.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -0
- package/dist/index.cjs +264 -37
- package/dist/index.d.cts +114 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +114 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +264 -37
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +32 -2
- package/package.json +14 -2
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../icon/icons.ts","../src/scroll-fab.ts"],"sourcesContent":["/* ============================================================\n 青梧 UI · 图标库\n ============================================================\n 零依赖 · 纯字符串常量 · tree-shakeable named exports\n 所有图标统一使用:viewBox=\"0 0 24 24\", stroke=\"currentColor\",\n stroke-width=\"2\", stroke-linecap=\"round\", stroke-linejoin=\"round\".\n\n 使用方式:\n import { ICON_CALENDAR, ICON_SEARCH } from \"@/icon/icons\";\n element.innerHTML = ICON_CALENDAR;\n 或者通过 dangerouslySetInnerHTML 渲染。\n ============================================================ */\n\nconst S = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S16 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S18 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S20 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S36 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\n/* ---- 通用 UI 图标 ---- */\n\nexport const ICON_CALENDAR = S(\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M8 2v4M16 2v4M3 10h18\"/>',\n);\n\nexport const ICON_CALENDAR_DOT = S(\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/><line x1=\"8\" y1=\"14\" x2=\"8.01\" y2=\"14\"/>',\n);\n\nexport const ICON_SEARCH = S('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.35-4.35\"/>');\n\nexport const ICON_UPLOAD = S(\n '<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/>',\n);\n\nexport const ICON_UPLOAD_ARROW = S(\n '<path d=\"M12 16V4\"/><path d=\"m6 9 6-5 6 5\"/><path d=\"M4 20h16\"/>',\n);\n\nexport const ICON_MENU = S('<path d=\"M3 7h18M3 12h18M3 17h18\"/>');\n\nexport const ICON_BELL = S(\n '<path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\"/><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\"/>',\n);\n\nexport const ICON_CLOSE = S(\n '<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>',\n);\n\nexport const ICON_CHECK = S('<polyline points=\"20 6 9 17 4 12\"/>');\n\nexport const ICON_PLUS = S(\n '<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>',\n);\n\nexport const ICON_MINUS = S('<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>');\n\nexport const ICON_BOX = S(\n '<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"/>',\n);\n\nexport const ICON_EDIT = S(\n '<path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"/><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"/>',\n);\n\nexport const ICON_FILE = S(\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/>',\n);\n\nexport const ICON_FOLDER = S(\n '<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"/>',\n);\n\nexport const ICON_INFO = S(\n '<circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>',\n);\n\nexport const ICON_WARNING = S(\n '<path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/>',\n);\n\nexport const ICON_TRASH = S(\n '<polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/>',\n);\n\nexport const ICON_DOWNLOAD = S(\n '<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"/>',\n);\n\nexport const ICON_COPY = S(\n '<rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/>',\n);\n\nexport const ICON_EYE = S(\n '<path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n);\n\nexport const ICON_STAR = S(\n '<polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"/>',\n);\n\nexport const ICON_STAR_FILLED = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" aria-hidden=\"true\"><polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"/></svg>`;\n\nexport const ICON_BOOKMARK = S('<path d=\"M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"/>');\n\nexport const ICON_EXTERNAL_LINK = S(\n '<path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/>',\n);\nexport const ICON_GITHUB = S(\n '<path d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\"/><path d=\"M9 18c-4.51 2-5-2-7-2\"/>',\n);\n\n/* ---- 导航箭头 ---- */\n\nexport const ICON_CHEVRON_LEFT = S16('<path d=\"m15 18-6-6 6-6\"/>');\nexport const ICON_CHEVRON_RIGHT = S16('<path d=\"m9 18 6-6-6-6\"/>');\nexport const ICON_CHEVRON_UP = S('<polyline points=\"18 15 12 9 6 15\"/>');\nexport const ICON_CHEVRON_DOWN = S('<polyline points=\"6 9 12 15 18 9\"/>');\nexport const ICON_CODE = S(\n '<polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/>',\n);\n\n/* ---- 全屏 ---- */\n\nexport const ICON_FULLSCREEN = S(\n '<polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>',\n);\nexport const ICON_FULLSCREEN_EXIT = S(\n '<polyline points=\"4 8 4 3 9 3\"/><polyline points=\"20 16 20 21 15 21\"/><line x1=\"4\" y1=\"3\" x2=\"11\" y2=\"10\"/><line x1=\"20\" y1=\"21\" x2=\"13\" y2=\"14\"/>',\n);\n\n/* ---- 功能图标 ---- */\n\nexport const ICON_CLOCK = S('<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 6v6l4 2\"/>');\nexport const ICON_TYPE = S(\n '<polyline points=\"4 7 4 4 20 4 20 7\"/><line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\"/><line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\"/>',\n);\nexport const ICON_USERS = S(\n '<path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"/><circle cx=\"9\" cy=\"7\" r=\"4\"/><path d=\"M23 21v-2a4 4 0 0 0-3-3.87\"/><path d=\"M16 3.13a4 4 0 0 1 0 7.75\"/>',\n);\nexport const ICON_MICROPHONE = S(\n '<path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"/><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"/>',\n);\nexport const ICON_MUSIC = S(\n '<path d=\"M9 18V5l12-2v13\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><circle cx=\"18\" cy=\"16\" r=\"3\"/>',\n);\nexport const ICON_VIDEO = S(\n '<polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\" ry=\"2\"/>',\n);\nexport const ICON_IMAGE = S(\n '<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/>',\n);\n\n/* ---- 主题 ---- */\n\nexport const ICON_SUN = S(\n '<circle cx=\"12\" cy=\"12\" r=\"5\"/><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"/><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"/><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"/><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"/><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"/><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"/><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"/>',\n);\nexport const ICON_MOON = S('<path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"/>');\n\n/* ---- 侧边栏 ---- */\n\nexport const ICON_SIDEBAR_TOGGLE = S(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M9 3v18\"/><path d=\"m14 9-3 3 3 3\"/>',\n);\n\n/* ---- 编辑器图标 ---- */\n\nexport const ICON_LIST = S(\n '<line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"/><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"/>',\n);\nexport const ICON_AI = S(\n '<path d=\"M12 2l2.4 7.2h7.6l-6 4.8 2.4 7.2-6.4-4.8-6.4 4.8 2.4-7.2-6-4.8h7.6z\"/>',\n);\nexport const ICON_BOLT = S('<polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"/>');\nexport const ICON_REFRESH = S(\n '<polyline points=\"23 4 23 10 17 10\"/><polyline points=\"1 20 1 14 7 14\"/><path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"/>',\n);\nexport const ICON_RETRY = S(\n '<polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/>',\n);\nexport const ICON_SETTINGS = S(\n '<circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"/>',\n);\nexport const ICON_HISTORY = S(\n '<path d=\"M3 3v5h5\"/><path d=\"M3.05 13A9 9 0 1 0 6.11 6.11L3 8\"/><path d=\"M12 7v5l4 2\"/>',\n);\nexport const ICON_PUSH = S(\n '<line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/><polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>',\n);\nexport const ICON_TRANSLATE = S(\n '<path d=\"M5 8l6 6\"/><path d=\"M4 14l6-6 2-3\"/><path d=\"M2 5h12\"/><path d=\"M7 2h1\"/><path d=\"M22 22l-5-10-5 10\"/><path d=\"M14 18h6\"/>',\n);\nexport const ICON_SUMMARY = S(\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/><polyline points=\"10 9 9 9 8 9\"/>',\n);\nexport const ICON_RENAME = S('<path d=\"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z\"/>');\nexport const ICON_SELECTION = S(\n '<circle cx=\"12\" cy=\"12\" r=\"1\"/><path d=\"M20 12a8 8 0 1 1-8-8\"/><path d=\"m16 2 4 4-4 4\"/>',\n);\nexport const ICON_TAG = S(\n '<path d=\"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z\"/><line x1=\"7\" y1=\"7\" x2=\"7.01\" y2=\"7\"/>',\n);\nexport const ICON_GRIP = S(\n '<circle cx=\"9\" cy=\"12\" r=\"1\"/><circle cx=\"15\" cy=\"12\" r=\"1\"/><circle cx=\"9\" cy=\"6\" r=\"1\"/><circle cx=\"15\" cy=\"6\" r=\"1\"/><circle cx=\"9\" cy=\"18\" r=\"1\"/><circle cx=\"15\" cy=\"18\" r=\"1\"/>',\n);\nexport const ICON_DIAGRAM = S(\n '<rect x=\"2\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"14\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"2\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\"/>',\n);\nexport const ICON_LANGUAGE = S(\n '<circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/>',\n);\nexport const ICON_PAPERCLIP = S(\n '<path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"/>',\n);\nexport const ICON_BROKEN_IMAGE =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"2\"/><path d=\"M2 14l4-4 4 4 4-4 4 4 4-4\"/><path d=\"M6 6h.01M18 6h.01\"/></svg>';\n\n/* ---- 包级别图标(用于 upload/search/calendar 包) ---- */\n\nexport const ICO_UPLOAD = S36('<path d=\"M12 16V4\"/><path d=\"m6 9 6-5 6 5\"/><path d=\"M4 20h16\"/>');\nconst S18c = (d: string) =>\n `<svg class=\"qs-ico\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S20c = (d: string) =>\n `<svg class=\"qw-cal-svg\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nexport const ICO_SEARCH = S18c('<circle cx=\"11\" cy=\"11\" r=\"7\"/><path d=\"m20 20-3.2-3.2\"/>');\nexport const ICO_MENU = S18('<path d=\"M4 7h16M4 12h16M4 17h16\"/>');\nexport const ICO_CALENDAR = S20c(\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M8 2v4M16 2v4M3 10h18\"/>',\n);\nexport const ICO_ARROW_LEFT = S16('<path d=\"m15 18-6-6 6-6\"/>');\nexport const ICO_ARROW_RIGHT = S16('<path d=\"m9 18 6-6-6-6\"/>');\n\n/* ---- 搜索插图(大尺寸 art) ---- */\n\nexport const SEARCH_ART =\n '<svg viewBox=\"0 0 160 140\" role=\"img\" aria-label=\"Search illustration\">' +\n '<ellipse class=\"qs-art-shadow\" cx=\"80\" cy=\"124\" rx=\"46\" ry=\"6\"/>' +\n '<g class=\"qs-art-float\">' +\n '<rect class=\"qs-art-paper\" x=\"40\" y=\"20\" width=\"80\" height=\"82\" rx=\"13\"/>' +\n '<line class=\"qs-art-row-accent\" x1=\"54\" y1=\"42\" x2=\"92\" y2=\"42\"/>' +\n '<line class=\"qs-art-row\" x1=\"54\" y1=\"56\" x2=\"106\" y2=\"56\"/>' +\n '<line class=\"qs-art-row\" x1=\"54\" y1=\"70\" x2=\"84\" y2=\"70\"/>' +\n '<circle class=\"qs-art-glass\" cx=\"96\" cy=\"86\" r=\"23\"/>' +\n '<line class=\"qs-art-handle\" x1=\"113\" y1=\"103\" x2=\"129\" y2=\"119\"/>' +\n '<text class=\"qs-art-seal\" x=\"96\" y=\"94\" text-anchor=\"middle\" font-size=\"24\">寻</text>' +\n \"</g>\" +\n '<circle class=\"qs-art-dot-a qs-art-twinkle\" cx=\"34\" cy=\"32\" r=\"3\"/>' +\n '<circle class=\"qs-art-dot-b qs-art-twinkle\" cx=\"126\" cy=\"40\" r=\"2.6\" style=\"animation-delay:.8s\"/>' +\n '<circle class=\"qs-art-dot-c qs-art-twinkle\" cx=\"30\" cy=\"98\" r=\"2.4\" style=\"animation-delay:1.5s\"/>' +\n \"</svg>\";\n","/** 青梧UI ScrollFab 悬浮滚动栏:默认“滚动到底部”,桌面悬停/触屏按住绕满描边一圈翻转为“返回顶部”,点击(轻点)直接执行当前模式动作 */\n\nimport { ICON_CHEVRON_DOWN } from \"../../../icon/icons\";\nimport type { ScrollFabMode, ScrollFabOptions } from \"./types\";\n\nconst RADIUS = 21;\nconst DEFAULT_LABEL_BOTTOM = \"滚动到底部(悬停或按住绕圈可切换为返回顶部)\";\nconst DEFAULT_LABEL_TOP = \"返回顶部(悬停或按住绕圈可切换为滚动到底部)\";\n\nfunction easeInOutCubic(p: number): number {\n return p < 0.5 ? 4 * p * p * p : 1 - (-2 * p + 2) ** 3 / 2;\n}\n\nexport class ScrollFab {\n readonly el: HTMLButtonElement;\n\n private readonly ring: SVGCircleElement;\n private readonly track: SVGCircleElement;\n private readonly icon: HTMLElement;\n private readonly len: number;\n\n private readonly targetEl: HTMLElement | null;\n private readonly ringMs: number;\n private readonly decayMs: number;\n private readonly cancelPx: number;\n private readonly animate: boolean;\n private readonly labelBottom: string;\n private readonly labelTop: string;\n private readonly onModeChange?: (mode: ScrollFabMode) => void;\n\n private mode: ScrollFabMode = \"to-bottom\";\n private progress = 0;\n private hovering = false;\n private pressing = false;\n private flipped = false;\n private pointerId: number | null = null;\n private startX = 0;\n private startY = 0;\n private ringRaf: number | null = null;\n private lastTs: number | null = null;\n private scrollRaf: number | null = null;\n private flashTimer: ReturnType<typeof setTimeout> | null = null;\n private tapResetTimer: ReturnType<typeof setTimeout> | null = null;\n private touchTap = false;\n private ro: ResizeObserver | null = null;\n\n constructor(options: ScrollFabOptions = {}) {\n this.targetEl = options.target ?? null;\n this.ringMs = Math.max(100, Math.min(5000, options.ringDuration ?? 800));\n this.decayMs = Math.max(100, options.decayDuration ?? 300);\n this.cancelPx = Math.max(4, options.cancelThreshold ?? 10);\n this.animate = options.animate ?? true;\n this.labelBottom = options.ariaLabelToBottom ?? DEFAULT_LABEL_BOTTOM;\n this.labelTop = options.ariaLabelToTop ?? DEFAULT_LABEL_TOP;\n this.onModeChange = options.onModeChange;\n\n this.el = document.createElement(\"button\");\n this.el.type = \"button\";\n this.el.className = `qsf-root${options.className ? ` ${options.className}` : \"\"}`;\n this.el.dataset.mode = this.mode;\n this.el.setAttribute(\"aria-label\", this.labelBottom);\n this.el.style.setProperty(\"--qsf-size\", `${Math.max(44, options.size ?? 48)}px`);\n if (options.zIndex != null) this.el.style.setProperty(\"--qsf-z\", String(options.zIndex));\n if (options.position?.right != null)\n this.el.style.setProperty(\"--qsf-right\", `${options.position.right}px`);\n if (options.position?.bottom != null)\n this.el.style.setProperty(\"--qsf-bottom\", `${options.position.bottom}px`);\n if (options.position?.left != null)\n this.el.style.setProperty(\"--qsf-left\", `${options.position.left}px`);\n if (options.position?.top != null)\n this.el.style.setProperty(\"--qsf-top\", `${options.position.top}px`);\n\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"class\", \"qsf-svg\");\n svg.setAttribute(\"viewBox\", \"0 0 48 48\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n this.track = this.makeCircle(\"qsf-track\");\n this.ring = this.makeCircle(\"qsf-bar\");\n svg.append(this.track, this.ring);\n let len = 2 * Math.PI * RADIUS;\n try {\n // 浏览器对未渲染 SVG 抛错(happy-dom 返回 NaN),失败时用几何公式回退\n const measured = this.ring.getTotalLength();\n if (Number.isFinite(measured)) len = measured;\n } catch {\n /* 回退 2πr */\n }\n this.len = len;\n this.ring.style.strokeDasharray = String(this.len);\n this.renderRing();\n\n this.icon = document.createElement(\"span\");\n this.icon.className = \"qsf-icon\";\n this.icon.setAttribute(\"aria-hidden\", \"true\");\n if (options.content != null) {\n if (typeof options.content === \"string\") this.icon.innerHTML = options.content;\n else this.icon.append(options.content);\n } else {\n this.icon.innerHTML = ICON_CHEVRON_DOWN;\n }\n\n this.el.append(svg, this.icon);\n document.body.append(this.el);\n\n this.el.addEventListener(\"pointerenter\", this.onEnter);\n this.el.addEventListener(\"pointerleave\", this.onLeave);\n this.el.addEventListener(\"pointerdown\", this.onDown);\n this.el.addEventListener(\"pointermove\", this.onMove);\n this.el.addEventListener(\"pointerup\", this.onUp);\n this.el.addEventListener(\"pointercancel\", this.onCancel);\n this.el.addEventListener(\"keydown\", this.onKey);\n this.el.addEventListener(\"click\", this.onClick);\n window.addEventListener(\"resize\", this.onRecheck);\n (this.targetEl ?? window).addEventListener(\"scroll\", this.onRecheck, { passive: true });\n if (typeof ResizeObserver === \"function\") {\n this.ro = new ResizeObserver(this.onRecheck);\n this.ro.observe(this.targetEl ?? document.documentElement);\n }\n this.syncVisible();\n }\n\n /** 当前模式 */\n get currentMode(): ScrollFabMode {\n return this.mode;\n }\n\n /** 内容懒加载等外部高度变化后可显式触发重估(滚动/resize 时也会自动重估) */\n refresh(): void {\n this.onRecheck();\n }\n\n scrollToBottom(): void {\n this.animateScroll(\"bottom\");\n }\n\n scrollToTop(): void {\n this.scrollTo(0);\n }\n\n destroy(): void {\n this.el.removeEventListener(\"pointerenter\", this.onEnter);\n this.el.removeEventListener(\"pointerleave\", this.onLeave);\n this.el.removeEventListener(\"pointerdown\", this.onDown);\n this.el.removeEventListener(\"pointermove\", this.onMove);\n this.el.removeEventListener(\"pointerup\", this.onUp);\n this.el.removeEventListener(\"pointercancel\", this.onCancel);\n this.el.removeEventListener(\"keydown\", this.onKey);\n this.el.removeEventListener(\"click\", this.onClick);\n window.removeEventListener(\"resize\", this.onRecheck);\n (this.targetEl ?? window).removeEventListener(\"scroll\", this.onRecheck);\n this.ro?.disconnect();\n this.cancelScroll();\n if (this.ringRaf != null) cancelAnimationFrame(this.ringRaf);\n this.ringRaf = null;\n if (this.flashTimer != null) clearTimeout(this.flashTimer);\n if (this.tapResetTimer != null) clearTimeout(this.tapResetTimer);\n this.el.remove();\n }\n\n private makeCircle(cls: string): SVGCircleElement {\n const c = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n c.setAttribute(\"class\", cls);\n c.setAttribute(\"cx\", \"24\");\n c.setAttribute(\"cy\", \"24\");\n c.setAttribute(\"r\", String(RADIUS));\n return c;\n }\n\n /* ---------------- 输入状态机 ----------------\n * 桌面(mouse):pointerenter 推进描边 / pointerleave 衰减倒转;click 恒为动作\n * 触屏(非 mouse):pointerdown 按住推进(首指针独占,位移超阈值放弃并放行手势);\n * 轻点 = 动作;绕满翻转过 → 本次释放被消费(不在同一手势里翻转+滚动)\n */\n\n private onEnter = (e: PointerEvent): void => {\n if (e.pointerType !== \"mouse\") return;\n this.hovering = true;\n this.kickRing();\n };\n\n private onLeave = (e: PointerEvent): void => {\n if (e.pointerType !== \"mouse\") return;\n this.hovering = false;\n this.flipped = false;\n };\n\n private onDown = (e: PointerEvent): void => {\n if (e.button !== 0 || this.pointerId !== null) return;\n // 桌面描边由 hover 驱动,鼠标按压不接管\n if (e.pointerType === \"mouse\") return;\n e.preventDefault();\n this.touchTap = true;\n if (this.tapResetTimer != null) clearTimeout(this.tapResetTimer);\n this.pointerId = e.pointerId;\n this.startX = e.clientX;\n this.startY = e.clientY;\n this.pressing = true;\n this.flipped = false;\n this.kickRing();\n };\n\n private onMove = (e: PointerEvent): void => {\n if (e.pointerId !== this.pointerId || !this.pressing) return;\n // 超阈值 = 放弃描边且放行页面手势(不拦截 move,浏览器原生滚动照常)\n if (Math.hypot(e.clientX - this.startX, e.clientY - this.startY) > this.cancelPx) {\n this.pressing = false;\n this.pointerId = null;\n this.flipped = false;\n }\n };\n\n private onUp = (e: PointerEvent): void => {\n if (e.pointerId !== this.pointerId) return;\n this.pointerId = null;\n this.pressing = false;\n const consumed = this.flipped;\n this.flipped = false;\n // ghost click 兜底标记延迟复位,避免吞掉下一次真实鼠标点击\n this.tapResetTimer = setTimeout(() => {\n this.touchTap = false;\n this.tapResetTimer = null;\n }, 400);\n if (consumed) return;\n this.doAction();\n };\n\n private onCancel = (e: PointerEvent): void => {\n if (e.pointerId !== this.pointerId) return;\n this.pointerId = null;\n this.pressing = false;\n this.flipped = false;\n };\n\n private onClick = (e: MouseEvent): void => {\n // 触屏 pointerdown 已 preventDefault,正常不合成 click;此处兜底吞掉,防双触发\n if (this.touchTap) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n this.doAction();\n };\n\n private onKey = (e: KeyboardEvent): void => {\n if (e.repeat || (e.key !== \"Enter\" && e.key !== \" \")) return;\n e.preventDefault();\n this.setMode(this.mode === \"to-bottom\" ? \"to-top\" : \"to-bottom\");\n };\n\n /* ---------------- 描边 rAF:悬停/按住推进 · 离开/松手衰减倒转 ---------------- */\n\n private holding(): boolean {\n return this.hovering || this.pressing;\n }\n\n private kickRing(): void {\n if (this.ringRaf != null) return;\n this.lastTs = null;\n this.ringRaf = requestAnimationFrame(this.stepRing);\n }\n\n private stepRing = (ts: number): void => {\n const dt = this.lastTs == null ? 0 : ts - this.lastTs;\n this.lastTs = ts;\n if (this.holding()) {\n if (!this.flipped) {\n this.progress = Math.min(1, this.progress + dt / this.ringMs);\n if (this.progress >= 1) this.completeRing();\n }\n } else {\n this.progress = Math.max(0, this.progress - dt / this.decayMs);\n }\n this.renderRing();\n if (this.holding() || this.progress > 0) {\n this.ringRaf = requestAnimationFrame(this.stepRing);\n } else {\n this.ringRaf = null;\n }\n };\n\n /** 绕满一圈 = 纯模式翻转(不附带任何滚动) */\n private completeRing(): void {\n this.flipped = true;\n const next: ScrollFabMode = this.mode === \"to-bottom\" ? \"to-top\" : \"to-bottom\";\n this.setMode(next);\n this.el.classList.add(\"is-complete\");\n if (this.flashTimer != null) clearTimeout(this.flashTimer);\n this.flashTimer = setTimeout(() => {\n this.el.classList.remove(\"is-complete\");\n this.flashTimer = null;\n }, 350);\n }\n\n private renderRing(): void {\n const vis = this.progress > 0;\n this.track.toggleAttribute(\"hidden\", !vis);\n this.ring.toggleAttribute(\"hidden\", !vis);\n this.ring.style.strokeDashoffset = String(this.len * (1 - this.progress));\n }\n\n private setMode(mode: ScrollFabMode): void {\n if (mode === this.mode) return;\n this.mode = mode;\n this.el.dataset.mode = mode;\n this.el.setAttribute(\"aria-label\", mode === \"to-bottom\" ? this.labelBottom : this.labelTop);\n this.onModeChange?.(mode);\n }\n\n /* ---------------- 程序滚动:rAF 缓动 + 打断 + 懒加载追击 ---------------- */\n\n private doAction(): void {\n this.animateScroll(this.mode === \"to-bottom\" ? \"bottom\" : \"top\");\n }\n\n private animateScroll(dest: \"bottom\" | \"top\"): void {\n this.cancelScroll();\n if (!this.animate || this.reducedMotion()) {\n this.setScrollPos(this.targetPos(dest));\n return;\n }\n this.attachInterrupt();\n let init = false;\n let start = 0;\n let end = 0;\n let t0 = 0;\n let dur = 0;\n const step = (ts: number): void => {\n if (!init) {\n init = true;\n start = this.scrollPos();\n end = this.targetPos(dest);\n t0 = ts;\n dur = Math.min(1200, Math.max(400, Math.abs(end - start) / 3));\n } else if (dest === \"bottom\") {\n // 追击:懒加载变长时以当前实测底端为准重设行程\n const live = this.targetPos(dest);\n if (Math.abs(live - end) > 2) {\n end = live;\n start = this.scrollPos();\n t0 = ts;\n dur = Math.min(1200, Math.max(400, Math.abs(end - start) / 3));\n }\n }\n const p = Math.min(1, (ts - t0) / dur);\n this.setScrollPos(start + (end - start) * easeInOutCubic(p));\n if (p < 1) this.scrollRaf = requestAnimationFrame(step);\n else {\n this.scrollRaf = null;\n this.detachInterrupt();\n }\n };\n this.scrollRaf = requestAnimationFrame(step);\n }\n\n private reducedMotion(): boolean {\n return (\n typeof matchMedia === \"function\" && matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n );\n }\n\n private onInterrupt = (): void => {\n this.cancelScroll();\n };\n\n private interruptSource(): Window | HTMLElement {\n return this.targetEl ?? window;\n }\n\n private attachInterrupt(): void {\n const src = this.interruptSource();\n for (const ev of [\"wheel\", \"touchstart\", \"keydown\"])\n src.addEventListener(ev, this.onInterrupt, { passive: true });\n }\n\n private detachInterrupt(): void {\n const src = this.interruptSource();\n for (const ev of [\"wheel\", \"touchstart\", \"keydown\"])\n src.removeEventListener(ev, this.onInterrupt);\n }\n\n private cancelScroll(): void {\n if (this.scrollRaf != null) {\n cancelAnimationFrame(this.scrollRaf);\n this.scrollRaf = null;\n }\n this.detachInterrupt();\n }\n\n /* ---------------- 度量与可见性(可滚动才渲染) ---------------- */\n\n private maxScroll(): number {\n if (this.targetEl) return Math.max(0, this.targetEl.scrollHeight - this.targetEl.clientHeight);\n return Math.max(0, document.documentElement.scrollHeight - window.innerHeight);\n }\n\n private targetPos(dest: \"bottom\" | \"top\"): number {\n return dest === \"bottom\" ? this.maxScroll() : 0;\n }\n\n private scrollPos(): number {\n if (this.targetEl) return this.targetEl.scrollTop;\n return window.scrollY || document.documentElement.scrollTop || 0;\n }\n\n private setScrollPos(v: number): void {\n if (this.targetEl) this.targetEl.scrollTop = v;\n else window.scrollTo(0, v);\n }\n\n private scrollTo(v: number): void {\n this.animateScroll(v === 0 ? \"top\" : \"bottom\");\n }\n\n private onRecheck = (): void => {\n this.syncVisible();\n };\n\n private syncVisible(): void {\n this.el.hidden = this.maxScroll() <= 1;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../icon/icons.ts","../src/scroll-fab.ts"],"sourcesContent":["/* ============================================================\n 青梧 UI · 图标库\n ============================================================\n 零依赖 · 纯字符串常量 · tree-shakeable named exports\n 所有图标统一使用:viewBox=\"0 0 24 24\", stroke=\"currentColor\",\n stroke-width=\"2\", stroke-linecap=\"round\", stroke-linejoin=\"round\".\n\n 使用方式:\n import { ICON_CALENDAR, ICON_SEARCH } from \"@/icon/icons\";\n element.innerHTML = ICON_CALENDAR;\n 或者通过 dangerouslySetInnerHTML 渲染。\n ============================================================ */\n\nconst S = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S16 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S18 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S20 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S36 = (d: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\n/* ---- 通用 UI 图标 ---- */\n\nexport const ICON_CALENDAR = S(\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M8 2v4M16 2v4M3 10h18\"/>',\n);\n\nexport const ICON_CALENDAR_DOT = S(\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/><line x1=\"8\" y1=\"14\" x2=\"8.01\" y2=\"14\"/>',\n);\n\nexport const ICON_SEARCH = S('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.35-4.35\"/>');\n\nexport const ICON_UPLOAD = S(\n '<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/>',\n);\n\nexport const ICON_UPLOAD_ARROW = S(\n '<path d=\"M12 16V4\"/><path d=\"m6 9 6-5 6 5\"/><path d=\"M4 20h16\"/>',\n);\n\nexport const ICON_MENU = S('<path d=\"M3 7h18M3 12h18M3 17h18\"/>');\n\nexport const ICON_BELL = S(\n '<path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\"/><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\"/>',\n);\n\nexport const ICON_CLOSE = S(\n '<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>',\n);\n\nexport const ICON_CHECK = S('<polyline points=\"20 6 9 17 4 12\"/>');\n\nexport const ICON_PLUS = S(\n '<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>',\n);\n\nexport const ICON_MINUS = S('<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>');\n\nexport const ICON_BOX = S(\n '<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"/>',\n);\n\nexport const ICON_EDIT = S(\n '<path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"/><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"/>',\n);\n\nexport const ICON_FILE = S(\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/>',\n);\n\nexport const ICON_FOLDER = S(\n '<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"/>',\n);\n\nexport const ICON_INFO = S(\n '<circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>',\n);\n\nexport const ICON_WARNING = S(\n '<path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/>',\n);\n\nexport const ICON_TRASH = S(\n '<polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/>',\n);\n\nexport const ICON_DOWNLOAD = S(\n '<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"/>',\n);\n\nexport const ICON_COPY = S(\n '<rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/>',\n);\n\nexport const ICON_EYE = S(\n '<path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n);\n\nexport const ICON_STAR = S(\n '<polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"/>',\n);\n\nexport const ICON_STAR_FILLED = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" aria-hidden=\"true\"><polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"/></svg>`;\n\nexport const ICON_BOOKMARK = S('<path d=\"M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"/>');\n\nexport const ICON_EXTERNAL_LINK = S(\n '<path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/>',\n);\nexport const ICON_GITHUB = S(\n '<path d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\"/><path d=\"M9 18c-4.51 2-5-2-7-2\"/>',\n);\n\n/* ---- 导航箭头 ---- */\n\nexport const ICON_CHEVRON_LEFT = S16('<path d=\"m15 18-6-6 6-6\"/>');\nexport const ICON_CHEVRON_RIGHT = S16('<path d=\"m9 18 6-6-6-6\"/>');\nexport const ICON_CHEVRON_UP = S('<polyline points=\"18 15 12 9 6 15\"/>');\nexport const ICON_CHEVRON_DOWN = S('<polyline points=\"6 9 12 15 18 9\"/>');\nexport const ICON_CODE = S(\n '<polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/>',\n);\n\n/* ---- 全屏 ---- */\n\nexport const ICON_FULLSCREEN = S(\n '<polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>',\n);\nexport const ICON_FULLSCREEN_EXIT = S(\n '<polyline points=\"4 8 4 3 9 3\"/><polyline points=\"20 16 20 21 15 21\"/><line x1=\"4\" y1=\"3\" x2=\"11\" y2=\"10\"/><line x1=\"20\" y1=\"21\" x2=\"13\" y2=\"14\"/>',\n);\n\n/* ---- 功能图标 ---- */\n\nexport const ICON_CLOCK = S('<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 6v6l4 2\"/>');\nexport const ICON_TYPE = S(\n '<polyline points=\"4 7 4 4 20 4 20 7\"/><line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\"/><line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\"/>',\n);\nexport const ICON_USERS = S(\n '<path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"/><circle cx=\"9\" cy=\"7\" r=\"4\"/><path d=\"M23 21v-2a4 4 0 0 0-3-3.87\"/><path d=\"M16 3.13a4 4 0 0 1 0 7.75\"/>',\n);\nexport const ICON_MICROPHONE = S(\n '<path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"/><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"/>',\n);\nexport const ICON_MUSIC = S(\n '<path d=\"M9 18V5l12-2v13\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><circle cx=\"18\" cy=\"16\" r=\"3\"/>',\n);\nexport const ICON_VIDEO = S(\n '<polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\" ry=\"2\"/>',\n);\nexport const ICON_IMAGE = S(\n '<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/>',\n);\n\n/* ---- 主题 ---- */\n\nexport const ICON_SUN = S(\n '<circle cx=\"12\" cy=\"12\" r=\"5\"/><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"/><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"/><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"/><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"/><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"/><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"/><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"/>',\n);\nexport const ICON_MOON = S('<path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"/>');\n\n/* ---- 侧边栏 ---- */\n\nexport const ICON_SIDEBAR_TOGGLE = S(\n '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M9 3v18\"/><path d=\"m14 9-3 3 3 3\"/>',\n);\n\n/* ---- 编辑器图标 ---- */\n\nexport const ICON_LIST = S(\n '<line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"/><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"/>',\n);\nexport const ICON_AI = S(\n '<path d=\"M12 2l2.4 7.2h7.6l-6 4.8 2.4 7.2-6.4-4.8-6.4 4.8 2.4-7.2-6-4.8h7.6z\"/>',\n);\nexport const ICON_BOLT = S('<polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"/>');\nexport const ICON_REFRESH = S(\n '<polyline points=\"23 4 23 10 17 10\"/><polyline points=\"1 20 1 14 7 14\"/><path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"/>',\n);\nexport const ICON_RETRY = S(\n '<polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/>',\n);\nexport const ICON_SETTINGS = S(\n '<circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"/>',\n);\nexport const ICON_HISTORY = S(\n '<path d=\"M3 3v5h5\"/><path d=\"M3.05 13A9 9 0 1 0 6.11 6.11L3 8\"/><path d=\"M12 7v5l4 2\"/>',\n);\nexport const ICON_PUSH = S(\n '<line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/><polygon points=\"22 2 15 22 11 13 2 9 22 2\"/>',\n);\nexport const ICON_TRANSLATE = S(\n '<path d=\"M5 8l6 6\"/><path d=\"M4 14l6-6 2-3\"/><path d=\"M2 5h12\"/><path d=\"M7 2h1\"/><path d=\"M22 22l-5-10-5 10\"/><path d=\"M14 18h6\"/>',\n);\nexport const ICON_SUMMARY = S(\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/><polyline points=\"10 9 9 9 8 9\"/>',\n);\nexport const ICON_RENAME = S('<path d=\"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z\"/>');\nexport const ICON_SELECTION = S(\n '<circle cx=\"12\" cy=\"12\" r=\"1\"/><path d=\"M20 12a8 8 0 1 1-8-8\"/><path d=\"m16 2 4 4-4 4\"/>',\n);\nexport const ICON_TAG = S(\n '<path d=\"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z\"/><line x1=\"7\" y1=\"7\" x2=\"7.01\" y2=\"7\"/>',\n);\nexport const ICON_GRIP = S(\n '<circle cx=\"9\" cy=\"12\" r=\"1\"/><circle cx=\"15\" cy=\"12\" r=\"1\"/><circle cx=\"9\" cy=\"6\" r=\"1\"/><circle cx=\"15\" cy=\"6\" r=\"1\"/><circle cx=\"9\" cy=\"18\" r=\"1\"/><circle cx=\"15\" cy=\"18\" r=\"1\"/>',\n);\nexport const ICON_DIAGRAM = S(\n '<rect x=\"2\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"14\" y=\"2\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"2\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"8\" height=\"8\" rx=\"1\"/>',\n);\nexport const ICON_LANGUAGE = S(\n '<circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/>',\n);\nexport const ICON_PAPERCLIP = S(\n '<path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"/>',\n);\nexport const ICON_BROKEN_IMAGE =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"2\"/><path d=\"M2 14l4-4 4 4 4-4 4 4 4-4\"/><path d=\"M6 6h.01M18 6h.01\"/></svg>';\n\n/* ---- 包级别图标(用于 upload/search/calendar 包) ---- */\n\nexport const ICO_UPLOAD = S36('<path d=\"M12 16V4\"/><path d=\"m6 9 6-5 6 5\"/><path d=\"M4 20h16\"/>');\nconst S18c = (d: string) =>\n `<svg class=\"qs-ico\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nconst S20c = (d: string) =>\n `<svg class=\"qw-cal-svg\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n\nexport const ICO_SEARCH = S18c('<circle cx=\"11\" cy=\"11\" r=\"7\"/><path d=\"m20 20-3.2-3.2\"/>');\nexport const ICO_MENU = S18('<path d=\"M4 7h16M4 12h16M4 17h16\"/>');\nexport const ICO_CALENDAR = S20c(\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M8 2v4M16 2v4M3 10h18\"/>',\n);\nexport const ICO_ARROW_LEFT = S16('<path d=\"m15 18-6-6 6-6\"/>');\nexport const ICO_ARROW_RIGHT = S16('<path d=\"m9 18 6-6-6-6\"/>');\n\n/* ---- 搜索插图(大尺寸 art) ---- */\n\nexport const SEARCH_ART =\n '<svg viewBox=\"0 0 160 140\" role=\"img\" aria-label=\"Search illustration\">' +\n '<ellipse class=\"qs-art-shadow\" cx=\"80\" cy=\"124\" rx=\"46\" ry=\"6\"/>' +\n '<g class=\"qs-art-float\">' +\n '<rect class=\"qs-art-paper\" x=\"40\" y=\"20\" width=\"80\" height=\"82\" rx=\"13\"/>' +\n '<line class=\"qs-art-row-accent\" x1=\"54\" y1=\"42\" x2=\"92\" y2=\"42\"/>' +\n '<line class=\"qs-art-row\" x1=\"54\" y1=\"56\" x2=\"106\" y2=\"56\"/>' +\n '<line class=\"qs-art-row\" x1=\"54\" y1=\"70\" x2=\"84\" y2=\"70\"/>' +\n '<circle class=\"qs-art-glass\" cx=\"96\" cy=\"86\" r=\"23\"/>' +\n '<line class=\"qs-art-handle\" x1=\"113\" y1=\"103\" x2=\"129\" y2=\"119\"/>' +\n '<text class=\"qs-art-seal\" x=\"96\" y=\"94\" text-anchor=\"middle\" font-size=\"24\">寻</text>' +\n \"</g>\" +\n '<circle class=\"qs-art-dot-a qs-art-twinkle\" cx=\"34\" cy=\"32\" r=\"3\"/>' +\n '<circle class=\"qs-art-dot-b qs-art-twinkle\" cx=\"126\" cy=\"40\" r=\"2.6\" style=\"animation-delay:.8s\"/>' +\n '<circle class=\"qs-art-dot-c qs-art-twinkle\" cx=\"30\" cy=\"98\" r=\"2.4\" style=\"animation-delay:1.5s\"/>' +\n \"</svg>\";\n","/** 青梧UI ScrollFab 悬浮滚动栏:默认“滚动到底部”,桌面悬停/触屏按住绕满描边一圈翻转为“返回顶部”,点击(轻点)直接执行当前模式动作 */\n\nimport { ICON_CHEVRON_DOWN } from \"../../../icon/icons\";\nimport type {\n LenisLike,\n ScrollFabLenisConfig,\n ScrollFabMode,\n ScrollFabOptions,\n ScrollFabShape,\n} from \"./types\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nconst RADIUS = 21;\nconst FALLBACK_PATH_LEN = 100;\nconst DEFAULT_LABEL_BOTTOM = \"滚动到底部(悬停或按住绕圈可切换为返回顶部)\";\nconst DEFAULT_LABEL_TOP = \"返回顶部(悬停或按住绕圈可切换为滚动到底部)\";\nconst STATIC_LABEL_BOTTOM = \"滚动到底部\";\nconst STATIC_LABEL_TOP = \"返回顶部\";\n\nfunction easeInOutCubic(p: number): number {\n return p < 0.5 ? 4 * p * p * p : 1 - (-2 * p + 2) ** 3 / 2;\n}\n\nfunction isLenisInstance(v: unknown): v is LenisLike {\n return (\n typeof v === \"object\" &&\n v !== null &&\n typeof (v as LenisLike).scrollTo === \"function\"\n );\n}\n\nexport class ScrollFab {\n readonly el: HTMLButtonElement;\n\n private ring: SVGGeometryElement;\n private track: SVGGeometryElement;\n private fillPath: SVGPathElement | null = null;\n private readonly icon: HTMLElement;\n private len: number;\n\n private readonly targetEl: HTMLElement | null;\n private readonly shape: ScrollFabShape | null;\n private readonly ringMs: number;\n private readonly decayMs: number;\n private readonly cancelPx: number;\n private readonly animate: boolean;\n private readonly labelBottom: string;\n private readonly labelTop: string;\n private readonly onModeChange?: (mode: ScrollFabMode) => void;\n private readonly onLenisReady?: (lenis: LenisLike) => void;\n private readonly onScroll?: (pct: number) => void;\n private readonly modes: ScrollFabMode[];\n private readonly single: boolean;\n private readonly threshold: number;\n\n /** 外部注入:宿主实例,组件永不销毁 */\n private externalLenis: LenisLike | null = null;\n /** 自建配置:null = 不走 lenis;true 形态也归一成对象 */\n private ownLenisConfig: ScrollFabLenisConfig | null = null;\n private ownLenis: LenisLike | null = null;\n private ownLenisPromise: Promise<LenisLike | null> | null = null;\n\n private mode: ScrollFabMode;\n private progress = 0;\n private hovering = false;\n private pressing = false;\n private flipped = false;\n private pointerId: number | null = null;\n private startX = 0;\n private startY = 0;\n private ringRaf: number | null = null;\n private lastTs: number | null = null;\n private scrollRaf: number | null = null;\n private lenisLoopRaf: number | null = null;\n private lenisScrolling = false;\n private lenisDest: \"bottom\" | \"top\" | null = null;\n private flashTimer: ReturnType<typeof setTimeout> | null = null;\n private tapResetTimer: ReturnType<typeof setTimeout> | null = null;\n private touchTap = false;\n private ro: ResizeObserver | null = null;\n private actionSeq = 0;\n private destroyed = false;\n private emitRaf: number | null = null;\n private lastPct = -1;\n\n constructor(options: ScrollFabOptions = {}) {\n this.targetEl = options.target ?? null;\n this.shape = options.shape ?? null;\n this.ringMs = Math.max(100, Math.min(5000, options.ringDuration ?? 800));\n this.decayMs = Math.max(100, options.decayDuration ?? 300);\n this.cancelPx = Math.max(4, options.cancelThreshold ?? 10);\n this.animate = options.animate ?? true;\n this.threshold = Math.max(0, options.showThreshold ?? 0);\n this.onModeChange = options.onModeChange;\n this.onLenisReady = options.onLenisReady;\n this.onScroll = options.onScroll;\n\n this.modes = this.normalizeModes(options.modes);\n this.single = this.modes.length === 1;\n this.mode = this.modes[0]!;\n\n this.labelBottom =\n options.ariaLabelToBottom ?? (this.single ? STATIC_LABEL_BOTTOM : DEFAULT_LABEL_BOTTOM);\n this.labelTop = options.ariaLabelToTop ?? (this.single ? STATIC_LABEL_TOP : DEFAULT_LABEL_TOP);\n\n if (isLenisInstance(options.lenis)) {\n this.externalLenis = options.lenis;\n } else if (options.lenis != null && options.lenis !== false) {\n const cfg = options.lenis === true ? {} : options.lenis;\n // 自建实例默认不劫持宿主滚轮:只驱动按钮触发的程序滚动\n this.ownLenisConfig = { smoothWheel: false, ...cfg };\n }\n\n this.el = document.createElement(\"button\");\n this.el.type = \"button\";\n this.el.className = `qsf-root${options.className ? ` ${options.className}` : \"\"}`;\n this.el.dataset.mode = this.mode;\n if (this.shape) this.el.dataset.shape = \"on\";\n this.el.setAttribute(\n \"aria-label\",\n this.mode === \"to-bottom\" ? this.labelBottom : this.labelTop,\n );\n this.el.style.setProperty(\"--qsf-size\", `${Math.max(44, options.size ?? 48)}px`);\n if (options.zIndex != null) this.el.style.setProperty(\"--qsf-z\", String(options.zIndex));\n if (options.position?.right != null)\n this.el.style.setProperty(\"--qsf-right\", `${options.position.right}px`);\n if (options.position?.bottom != null)\n this.el.style.setProperty(\"--qsf-bottom\", `${options.position.bottom}px`);\n if (options.position?.left != null)\n this.el.style.setProperty(\"--qsf-left\", `${options.position.left}px`);\n if (options.position?.top != null)\n this.el.style.setProperty(\"--qsf-top\", `${options.position.top}px`);\n\n const svg = document.createElementNS(SVG_NS, \"svg\");\n svg.setAttribute(\"class\", \"qsf-svg\");\n svg.setAttribute(\"viewBox\", this.shape?.viewBox ?? \"0 0 48 48\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n\n if (this.shape) {\n this.fillPath = document.createElementNS(SVG_NS, \"path\");\n this.fillPath.setAttribute(\"class\", \"qsf-shape-fill\");\n this.fillPath.setAttribute(\"d\", this.shape.fill);\n this.track = this.makePath(\"qsf-track\", this.shape.outline);\n this.ring = this.makePath(\"qsf-bar\", this.shape.outline);\n if (this.shape.outlineTransform) {\n this.track.setAttribute(\"transform\", this.shape.outlineTransform);\n this.ring.setAttribute(\"transform\", this.shape.outlineTransform);\n }\n svg.append(this.fillPath, this.track, this.ring);\n } else {\n this.track = this.makeCircle(\"qsf-track\");\n this.ring = this.makeCircle(\"qsf-bar\");\n svg.append(this.track, this.ring);\n }\n\n let len: number;\n if (this.shape) {\n len = FALLBACK_PATH_LEN;\n } else {\n len = 2 * Math.PI * RADIUS;\n }\n try {\n // 浏览器对未渲染 SVG 抛错(happy-dom 返回 NaN),失败时用回退值\n const measured = this.ring.getTotalLength();\n if (Number.isFinite(measured) && measured > 0) len = measured;\n } catch {\n /* 几何/经验回退 */\n }\n this.len = len;\n this.ring.style.strokeDasharray = String(this.len);\n this.renderRing();\n\n this.icon = document.createElement(\"span\");\n this.icon.className = \"qsf-icon\";\n this.icon.setAttribute(\"aria-hidden\", \"true\");\n if (options.content != null) {\n if (typeof options.content === \"string\") this.icon.innerHTML = options.content;\n else this.icon.append(options.content);\n } else {\n this.icon.innerHTML = ICON_CHEVRON_DOWN;\n }\n\n this.el.append(svg, this.icon);\n document.body.append(this.el);\n\n // 单模式没有绕环翻转:不绑绕环手势,只保留按钮激活与(双模式的)方向键翻转\n if (!this.single) {\n this.el.addEventListener(\"pointerenter\", this.onEnter);\n this.el.addEventListener(\"pointerleave\", this.onLeave);\n this.el.addEventListener(\"pointerdown\", this.onDown);\n this.el.addEventListener(\"pointermove\", this.onMove);\n this.el.addEventListener(\"pointerup\", this.onUp);\n this.el.addEventListener(\"pointercancel\", this.onCancel);\n }\n this.el.addEventListener(\"keydown\", this.onKey);\n this.el.addEventListener(\"click\", this.onClick);\n window.addEventListener(\"resize\", this.onRecheck);\n (this.targetEl ?? window).addEventListener(\"scroll\", this.onRecheck, { passive: true });\n if (typeof ResizeObserver === \"function\") {\n this.ro = new ResizeObserver(this.onRecheck);\n this.ro.observe(this.targetEl ?? document.documentElement);\n }\n this.syncVisible();\n // 初始补发一次进度(同步吐出,宿主无需先滚再读)\n this.emitScroll();\n }\n\n /** 当前模式 */\n get currentMode(): ScrollFabMode {\n return this.mode;\n }\n\n /** 内容懒加载等外部高度变化后可显式触发重估(滚动/resize 时也会自动重估),并强制补发一次进度 */\n refresh(): void {\n this.syncVisible();\n this.lastPct = -1;\n this.emitScroll();\n }\n\n scrollToBottom(): void {\n this.animateScroll(\"bottom\");\n }\n\n scrollToTop(): void {\n this.animateScroll(\"top\");\n }\n\n destroy(): void {\n this.destroyed = true;\n if (!this.single) {\n this.el.removeEventListener(\"pointerenter\", this.onEnter);\n this.el.removeEventListener(\"pointerleave\", this.onLeave);\n this.el.removeEventListener(\"pointerdown\", this.onDown);\n this.el.removeEventListener(\"pointermove\", this.onMove);\n this.el.removeEventListener(\"pointerup\", this.onUp);\n this.el.removeEventListener(\"pointercancel\", this.onCancel);\n }\n this.el.removeEventListener(\"keydown\", this.onKey);\n this.el.removeEventListener(\"click\", this.onClick);\n window.removeEventListener(\"resize\", this.onRecheck);\n (this.targetEl ?? window).removeEventListener(\"scroll\", this.onRecheck);\n this.ro?.disconnect();\n this.cancelScroll();\n this.stopLenisLoop();\n // 只销毁自建实例;外部宿主实例交还宿主\n this.ownLenis?.destroy?.();\n this.ownLenis = null;\n if (this.ringRaf != null) cancelAnimationFrame(this.ringRaf);\n this.ringRaf = null;\n if (this.emitRaf != null) cancelAnimationFrame(this.emitRaf);\n this.emitRaf = null;\n if (this.flashTimer != null) clearTimeout(this.flashTimer);\n if (this.tapResetTimer != null) clearTimeout(this.tapResetTimer);\n this.el.remove();\n }\n\n /** 规范化 modes:缺省双模式;去重、过滤非法值;结果为空直接抛错 */\n private normalizeModes(input?: ScrollFabMode[]): ScrollFabMode[] {\n if (!input) return [\"to-bottom\", \"to-top\"];\n const out: ScrollFabMode[] = [];\n for (const m of input) {\n if ((m === \"to-bottom\" || m === \"to-top\") && !out.includes(m)) out.push(m);\n }\n if (out.length === 0) {\n throw new TypeError(\n \"ScrollFab: modes 至少需要一个有效模式('to-bottom' | 'to-top')\",\n );\n }\n return out;\n }\n\n private makeCircle(cls: string): SVGCircleElement {\n const c = document.createElementNS(SVG_NS, \"circle\");\n c.setAttribute(\"class\", cls);\n c.setAttribute(\"cx\", \"24\");\n c.setAttribute(\"cy\", \"24\");\n c.setAttribute(\"r\", String(RADIUS));\n return c;\n }\n\n private makePath(cls: string, d: string): SVGPathElement {\n const p = document.createElementNS(SVG_NS, \"path\");\n p.setAttribute(\"class\", cls);\n p.setAttribute(\"d\", d);\n return p;\n }\n\n /* ---------------- 输入状态机 ----------------\n * 桌面(mouse):pointerenter 推进描边 / pointerleave 衰减倒转;click 恒为动作\n * 触屏(非 mouse):pointerdown 按住推进(首指针独占,位移超阈值放弃并放行手势);\n * 轻点 = 动作;绕满翻转过 → 本次释放被消费(不在同一手势里翻转+滚动)\n * 键盘:Enter/Space 走原生按钮激活(click → doAction);双模式下方向键翻转模式\n */\n\n private onEnter = (e: PointerEvent): void => {\n if (e.pointerType !== \"mouse\") return;\n this.hovering = true;\n this.kickRing();\n };\n\n private onLeave = (e: PointerEvent): void => {\n if (e.pointerType !== \"mouse\") return;\n this.hovering = false;\n this.flipped = false;\n };\n\n private onDown = (e: PointerEvent): void => {\n if (e.button !== 0 || this.pointerId !== null) return;\n // 桌面描边由 hover 驱动,鼠标按压不接管\n if (e.pointerType === \"mouse\") return;\n e.preventDefault();\n this.touchTap = true;\n if (this.tapResetTimer != null) clearTimeout(this.tapResetTimer);\n this.pointerId = e.pointerId;\n this.startX = e.clientX;\n this.startY = e.clientY;\n this.pressing = true;\n this.flipped = false;\n this.kickRing();\n };\n\n private onMove = (e: PointerEvent): void => {\n if (e.pointerId !== this.pointerId || !this.pressing) return;\n // 超阈值 = 放弃描边且放行页面手势(不拦截 move,浏览器原生滚动照常)\n if (Math.hypot(e.clientX - this.startX, e.clientY - this.startY) > this.cancelPx) {\n this.pressing = false;\n this.pointerId = null;\n this.flipped = false;\n }\n };\n\n private onUp = (e: PointerEvent): void => {\n if (e.pointerId !== this.pointerId) return;\n this.pointerId = null;\n this.pressing = false;\n const consumed = this.flipped;\n this.flipped = false;\n // ghost click 兜底标记延迟复位,避免吞掉下一次真实鼠标点击\n this.tapResetTimer = setTimeout(() => {\n this.touchTap = false;\n this.tapResetTimer = null;\n }, 400);\n if (consumed) return;\n this.doAction();\n };\n\n private onCancel = (e: PointerEvent): void => {\n if (e.pointerId !== this.pointerId) return;\n this.pointerId = null;\n this.pressing = false;\n this.flipped = false;\n };\n\n private onClick = (e: MouseEvent): void => {\n // 触屏 pointerdown 已 preventDefault,正常不合成 click;此处兜底吞掉,防双触发\n if (this.touchTap) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n this.doAction();\n };\n\n private onKey = (e: KeyboardEvent): void => {\n if (e.repeat || (e.key !== \"ArrowUp\" && e.key !== \"ArrowDown\")) return;\n if (this.single) return;\n const want: ScrollFabMode = e.key === \"ArrowUp\" ? \"to-top\" : \"to-bottom\";\n if (want === this.mode) return;\n // 翻转与滚动正交:拦截方向键的原生页面滚动,只做模式翻转\n e.preventDefault();\n this.setMode(want);\n };\n\n /* ---------------- 描边 rAF:悬停/按住推进 · 离开/松手衰减倒转 ---------------- */\n\n private holding(): boolean {\n return this.hovering || this.pressing;\n }\n\n private kickRing(): void {\n if (this.ringRaf != null) return;\n this.lastTs = null;\n this.ringRaf = requestAnimationFrame(this.stepRing);\n }\n\n private stepRing = (ts: number): void => {\n const dt = this.lastTs == null ? 0 : ts - this.lastTs;\n this.lastTs = ts;\n if (this.holding()) {\n if (!this.flipped) {\n this.progress = Math.min(1, this.progress + dt / this.ringMs);\n if (this.progress >= 1) this.completeRing();\n }\n } else {\n this.progress = Math.max(0, this.progress - dt / this.decayMs);\n }\n this.renderRing();\n if (this.holding() || this.progress > 0) {\n this.ringRaf = requestAnimationFrame(this.stepRing);\n } else {\n this.ringRaf = null;\n }\n };\n\n /** 绕满一圈 = 纯模式翻转(不附带任何滚动) */\n private completeRing(): void {\n this.flipped = true;\n const next: ScrollFabMode = this.mode === \"to-bottom\" ? \"to-top\" : \"to-bottom\";\n this.setMode(next);\n this.el.classList.add(\"is-complete\");\n if (this.flashTimer != null) clearTimeout(this.flashTimer);\n this.flashTimer = setTimeout(() => {\n this.el.classList.remove(\"is-complete\");\n this.flashTimer = null;\n }, 350);\n }\n\n private renderRing(): void {\n const vis = this.progress > 0;\n this.track.toggleAttribute(\"hidden\", !vis);\n this.ring.toggleAttribute(\"hidden\", !vis);\n this.ring.style.strokeDashoffset = String(this.len * (1 - this.progress));\n }\n\n private setMode(mode: ScrollFabMode): void {\n if (mode === this.mode) return;\n this.mode = mode;\n this.el.dataset.mode = mode;\n this.el.setAttribute(\"aria-label\", mode === \"to-bottom\" ? this.labelBottom : this.labelTop);\n this.onModeChange?.(mode);\n }\n\n /* ---------------- 程序滚动:Lenis 后端可插拔,缺省内置 rAF ---------------- */\n\n private doAction(): void {\n this.animateScroll(this.mode === \"to-bottom\" ? \"bottom\" : \"top\");\n }\n\n private animateScroll(dest: \"bottom\" | \"top\"): void {\n const seq = ++this.actionSeq;\n this.cancelScroll();\n if (!this.animate || this.reducedMotion()) {\n this.setScrollPos(this.targetPos(dest));\n return;\n }\n if (this.externalLenis) {\n this.scrollWithLenis(this.externalLenis, dest, false);\n return;\n }\n if (this.ownLenisConfig) {\n const seq = ++this.actionSeq;\n void this.resolveOwnLenis().then((lenis) => {\n // await 期间可能已被新动作或 destroy 取代\n if (this.destroyed || seq !== this.actionSeq) return;\n if (lenis) this.scrollWithLenis(lenis, dest, true);\n else this.animateRaf(dest);\n });\n return;\n }\n this.animateRaf(dest);\n }\n\n /** 首次点击时动态 import lenis 并自建实例;未安装(或加载失败)→ null 永久回退 rAF */\n private resolveOwnLenis(): Promise<LenisLike | null> {\n if (this.ownLenis) return Promise.resolve(this.ownLenis);\n if (this.ownLenisPromise) return this.ownLenisPromise;\n this.ownLenisPromise = import(\"lenis\")\n .then((mod) => {\n const LenisCtor =\n (mod as { default?: new (opts: Record<string, unknown>) => LenisLike }).default ??\n (mod as unknown as new (opts: Record<string,unknown>) => LenisLike);\n const cfg: Record<string, unknown> = { ...this.ownLenisConfig };\n // target 容器映射为 Lenis wrapper;window 形态留空(Lenis 默认即 window)\n if (this.targetEl) cfg.wrapper = this.targetEl;\n this.ownLenis = new LenisCtor(cfg);\n this.onLenisReady?.(this.ownLenis);\n return this.ownLenis\n })\n .catch(() => {\n // lenis 未安装/不可用:放弃 lenis 路线,避免每次点击重复尝试\n this.ownLenisConfig = null;\n this.ownLenisPromise = null;\n return null;\n });\n return this.ownLenisPromise;\n }\n\n /**\n * 用 Lenis 执行程序滚动。\n * 自建实例(own):组件自跑 raf loop(Lenis 需外部驱动 raf),保留 wheel/touch/keydown 打断与到底追击;\n * 外部实例:宿主自带 raf loop 与手势处理,组件只发 scrollTo,不追击不打断。\n */\n private scrollWithLenis(\n lenis: LenisLike,\n dest: \"bottom\" | \"top\",\n own: boolean,\n ): void {\n const immediate = !this.animate || this.reducedMotion();\n const target = this.targetPos(dest);\n this.lenisDest = dest;\n if (own) {\n // 上次打断可能调过 stop,发起前复位\n (lenis as LenisLike & { start?: () => void }).start?.();\n lenis.scrollTo(target, {\n immediate,\n onComplete: () => this.endLenisScroll(),\n });\n if (!immediate) {\n this.lenisScrolling = true;\n this.attachInterrupt();\n this.startLenisLoop(lenis, dest);\n } else {\n this.endLenisScroll();\n }\n } else {\n lenis.scrollTo(target, { immediate });\n this.lenisDest = null;\n }\n }\n\n /** 自建实例的 raf 驱动 + 懒加载到底追击(对齐内置 rAF 语义) */\n private startLenisLoop(lenis: LenisLike, dest: \"bottom\" | \"top\"): void {\n let lastEnd = this.targetPos(dest);\n const loop = (time: number): void => {\n if (!this.lenisScrolling) return;\n if (dest === \"bottom\") {\n const live = this.targetPos(\"bottom\");\n if (Math.abs(live - lastEnd) > 2) {\n // 内容变长:追击新底端(force 覆盖当前程序动画)\n lastEnd = live;\n lenis.scrollTo(live, {\n force: true,\n onComplete: () => this.endLenisScroll(),\n });\n }\n }\n lenis.raf?.(time);\n this.lenisLoopRaf = requestAnimationFrame(loop);\n };\n this.lenisLoopRaf = requestAnimationFrame(loop);\n }\n\n private stopLenisLoop(): void {\n if (this.lenisLoopRaf != null) {\n cancelAnimationFrame(this.lenisLoopRaf);\n this.lenisLoopRaf = null;\n }\n }\n\n /** 打断自建 Lenis 程序滚动:stop 冻结动画(下次发起前 start 复位) */\n private onLenisInterrupt = (): void => {\n if (!this.lenisScrolling) return;\n (this.ownLenis as (LenisLike & { stop?: () => void }) | null)?.stop?.();\n this.endLenisScroll();\n };\n\n private endLenisScroll(): void {\n this.lenisScrolling = false;\n this.lenisDest = null;\n this.stopLenisLoop();\n this.detachInterrupt();\n }\n\n /* ---------------- 内置 rAF:缓动 + 打断 + 懒加载追击 ---------------- */\n\n private animateRaf(dest: \"bottom\" | \"top\"): void {\n this.attachRafInterrupt();\n let init = false;\n let start = 0;\n let end = 0;\n let t0 = 0;\n let dur = 0;\n const step = (ts: number): void => {\n if (!init) {\n init = true;\n start = this.scrollPos();\n end = this.targetPos(dest);\n t0 = ts;\n dur = Math.min(1200, Math.max(400, Math.abs(end - start) / 3));\n } else if (dest === \"bottom\") {\n // 追击:懒加载变长时以当前实测底端为准重设行程\n const live = this.targetPos(dest);\n if (Math.abs(live - end) > 2) {\n end = live;\n start = this.scrollPos();\n t0 = ts;\n dur = Math.min(1200, Math.max(400, Math.abs(end - start) / 3));\n }\n }\n const p = Math.min(1, (ts - t0) / dur);\n this.setScrollPos(start + (end - start) * easeInOutCubic(p));\n if (p < 1) this.scrollRaf = requestAnimationFrame(step);\n else {\n this.scrollRaf = null;\n this.detachRafInterrupt();\n }\n };\n this.scrollRaf = requestAnimationFrame(step);\n }\n\n private reducedMotion(): boolean {\n return (\n typeof matchMedia === \"function\" && matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n );\n }\n\n private onInterrupt = (): void => {\n this.cancelScroll();\n };\n\n private interruptSource(): Window | HTMLElement {\n return this.targetEl ?? window;\n }\n\n /** 自建 Lenis 路线的打断监听 */\n private attachInterrupt(): void {\n const src = this.interruptSource();\n for (const ev of [\"wheel\", \"touchstart\", \"keydown\"])\n src.addEventListener(ev, this.onLenisInterrupt, { passive: true });\n }\n\n private detachInterrupt(): void {\n const src = this.interruptSource();\n for (const ev of [\"wheel\", \"touchstart\", \"keydown\"])\n src.removeEventListener(ev, this.onLenisInterrupt);\n }\n\n /** 内置 rAF 路线的打断监听 */\n private attachRafInterrupt(): void {\n const src = this.interruptSource();\n for (const ev of [\"wheel\", \"touchstart\", \"keydown\"])\n src.addEventListener(ev, this.onInterrupt, { passive: true });\n }\n\n private detachRafInterrupt(): void {\n const src = this.interruptSource();\n for (const ev of [\"wheel\", \"touchstart\", \"keydown\"])\n src.removeEventListener(ev, this.onInterrupt);\n }\n\n private cancelScroll(): void {\n if (this.scrollRaf != null) {\n cancelAnimationFrame(this.scrollRaf);\n this.scrollRaf = null;\n }\n if (this.lenisScrolling) this.endLenisScroll();\n const src = this.interruptSource();\n for (const ev of [\"wheel\", \"touchstart\", \"keydown\"]) {\n src.removeEventListener(ev, this.onInterrupt);\n src.removeEventListener(ev, this.onLenisInterrupt);\n }\n }\n\n /* ---------------- 度量、显隐与进度(可滚动且越过阈值才渲染) ---------------- */\n\n private maxScroll(): number {\n if (this.targetEl) return Math.max(0, this.targetEl.scrollHeight - this.targetEl.clientHeight);\n return Math.max(0, document.documentElement.scrollHeight - window.innerHeight);\n }\n\n private targetPos(dest: \"bottom\" | \"top\"): number {\n return dest === \"bottom\" ? this.maxScroll() : 0;\n }\n\n private scrollPos(): number {\n if (this.targetEl) return this.targetEl.scrollTop;\n return window.scrollY || document.documentElement.scrollTop || 0;\n }\n\n private setScrollPos(v: number): void {\n if (this.targetEl) this.targetEl.scrollTop = v;\n else window.scrollTo(0, v);\n }\n\n private onRecheck = (): void => {\n this.syncVisible();\n this.scheduleScroll();\n };\n\n private syncVisible(): void {\n this.el.hidden = this.maxScroll() <= 1 || this.scrollPos() < this.threshold;\n }\n\n /** rAF 节流:一帧内多次重估只吐一次;按钮隐藏期间照常调度 */\n private scheduleScroll(): void {\n if (this.emitRaf != null || this.destroyed) return;\n this.emitRaf = requestAnimationFrame(() => {\n this.emitRaf = null;\n this.emitScroll();\n });\n }\n\n private emitScroll(): void {\n if (this.destroyed) return;\n const max = this.maxScroll();\n const pct = max <= 0 ? 0 : Math.min(1, Math.max(0, this.scrollPos() / max));\n if (pct === this.lastPct) return;\n this.lastPct = pct;\n this.onScroll?.(pct);\n }\n}\n"],"mappings":"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"}
|
package/dist/style.css
CHANGED
|
@@ -70,6 +70,36 @@
|
|
|
70
70
|
/* 12 点钟为描边起点 */
|
|
71
71
|
transform: rotate(-90deg);
|
|
72
72
|
pointer-events: none;
|
|
73
|
+
overflow: visible;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ------------------------------------------------------------
|
|
77
|
+
异形模式(银杏叶等):圆形外壳退场,一切由 SVG path 承担
|
|
78
|
+
------------------------------------------------------------ */
|
|
79
|
+
.qsf-root[data-shape="on"] {
|
|
80
|
+
--qsf-icon: 38%;
|
|
81
|
+
background: none;
|
|
82
|
+
border: none;
|
|
83
|
+
border-radius: 0;
|
|
84
|
+
/* box-shadow 只能投矩形;异形阴影跟随叶片真实形状 */
|
|
85
|
+
box-shadow: none;
|
|
86
|
+
filter: drop-shadow(0 10px 14px rgba(20, 31, 30, 0.28));
|
|
87
|
+
}
|
|
88
|
+
.qsf-root[data-shape="on"]:active {
|
|
89
|
+
/* 压住时连异形阴影一起收 */
|
|
90
|
+
filter: drop-shadow(0 4px 8px rgba(20, 31, 30, 0.28));
|
|
91
|
+
}
|
|
92
|
+
.qsf-root[data-shape="on"] .qsf-svg {
|
|
93
|
+
/* 异形轮廓的起点约定已在 path 数据里对准 12 点,不再整体旋转 */
|
|
94
|
+
transform: none;
|
|
95
|
+
}
|
|
96
|
+
.qsf-shape-fill {
|
|
97
|
+
fill: var(--qsf-card);
|
|
98
|
+
stroke: var(--qsf-line);
|
|
99
|
+
stroke-width: 1;
|
|
100
|
+
}
|
|
101
|
+
.qsf-root[data-shape="on"][data-mode="to-top"] .qsf-shape-fill {
|
|
102
|
+
stroke: var(--qsf-amber);
|
|
73
103
|
}
|
|
74
104
|
.qsf-track {
|
|
75
105
|
fill: none;
|
|
@@ -91,8 +121,8 @@
|
|
|
91
121
|
.qsf-icon {
|
|
92
122
|
display: grid;
|
|
93
123
|
place-items: center;
|
|
94
|
-
width: 46
|
|
95
|
-
height: 46
|
|
124
|
+
width: var(--qsf-icon, 46%);
|
|
125
|
+
height: var(--qsf-icon, 46%);
|
|
96
126
|
}
|
|
97
127
|
.qsf-icon svg {
|
|
98
128
|
display: block;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qingwu-ui/scroll-fab",
|
|
3
|
-
"version": "0.9.0-beta.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.9.0-beta.3",
|
|
4
|
+
"description": "青梧 UI 悬浮滚动栏 —— 描边绕圈翻转「滚到底/回顶部」、Lenis 可插拔(未装回退 rAF)、异形形状(银杏叶等进度完全包裹)、单模式/阈值显隐/onScroll 进度回调、零强依赖",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"sideEffects": [
|
|
@@ -29,7 +29,16 @@
|
|
|
29
29
|
"test:watch": "vitest",
|
|
30
30
|
"size": "size-limit"
|
|
31
31
|
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"lenis": "^1.1.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependenciesMeta": {
|
|
36
|
+
"lenis": {
|
|
37
|
+
"optional": true
|
|
38
|
+
}
|
|
39
|
+
},
|
|
32
40
|
"devDependencies": {
|
|
41
|
+
"lenis": "^1.3.26",
|
|
33
42
|
"@qingwu-ui/tsconfig": "workspace:*",
|
|
34
43
|
"@size-limit/preset-small-lib": "^13.0.1",
|
|
35
44
|
"happy-dom": "^20.11.1",
|
|
@@ -57,6 +66,9 @@
|
|
|
57
66
|
"keywords": [
|
|
58
67
|
"scroll",
|
|
59
68
|
"fab",
|
|
69
|
+
"lenis",
|
|
70
|
+
"ginkgo",
|
|
71
|
+
"custom-shape",
|
|
60
72
|
"back-to-top",
|
|
61
73
|
"scroll-to-bottom",
|
|
62
74
|
"progress-ring",
|