@robot-admin/naive-ui-components 0.6.20 → 0.6.21
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/CHANGELOG.md +48 -48
- package/README.md +277 -277
- package/dist/C_ActionBar-jZPsiXtT.css.map +1 -0
- package/dist/C_ActionBar-nnfbZCea.css.map +1 -0
- package/dist/C_ActionBar.css +47 -47
- package/dist/C_ActionBar.js.map +1 -1
- package/dist/C_ActionBar2.js +1 -1
- package/dist/C_ActionBar2.js.map +1 -1
- package/dist/{C_AntV-BY8jqqmi.css.map → C_AntV-A3NXx_sF.css.map} +1 -1
- package/dist/{C_AntV-BbkHc-_a.css.map → C_AntV-D2Zp2qQF.css.map} +1 -1
- package/dist/C_AntV.css +78 -78
- package/dist/C_AntV.js.map +1 -1
- package/dist/C_AntV2.js +2 -2
- package/dist/C_AntV2.js.map +1 -1
- package/dist/{C_AudioPlayer-DKRIGhi7.css.map → C_AudioPlayer-CXl4yP_m.css.map} +1 -1
- package/dist/{C_AudioPlayer-DlB6eNsa.css.map → C_AudioPlayer-CcBtt71m.css.map} +1 -1
- package/dist/C_AudioPlayer.css +47 -47
- package/dist/C_AudioPlayer.js.map +1 -1
- package/dist/C_AudioPlayer2.js +1 -1
- package/dist/C_AudioPlayer2.js.map +1 -1
- package/dist/{C_AvatarGroup-D02zci-i.css.map → C_AvatarGroup-CtPhfH9h.css.map} +1 -1
- package/dist/{C_AvatarGroup-DatHaUlY.css.map → C_AvatarGroup-M1dNPH3E.css.map} +1 -1
- package/dist/C_AvatarGroup.css +21 -21
- package/dist/C_AvatarGroup.js.map +1 -1
- package/dist/C_AvatarGroup2.js +1 -1
- package/dist/C_AvatarGroup2.js.map +1 -1
- package/dist/{C_Barcode-DYDRDe2O.css.map → C_Barcode-DjTmDkbQ.css.map} +1 -1
- package/dist/{C_Barcode-muJdc_O4.css.map → C_Barcode-Do1Ozsmh.css.map} +1 -1
- package/dist/C_Barcode.css +7 -7
- package/dist/C_Barcode.js.map +1 -1
- package/dist/C_Barcode2.js +1 -1
- package/dist/C_Barcode2.js.map +1 -1
- package/dist/C_Breadcrumb.js.map +1 -1
- package/dist/C_Breadcrumb2.js.map +1 -1
- package/dist/{C_Captcha-9_hk6VmY.css.map → C_Captcha-CZmAETly.css.map} +1 -1
- package/dist/{C_Captcha-MtASlJ0f.css.map → C_Captcha-Ccq3DMrR.css.map} +1 -1
- package/dist/C_Captcha.css +19 -19
- package/dist/C_Captcha.js.map +1 -1
- package/dist/C_Captcha2.js +1 -1
- package/dist/C_Captcha2.js.map +1 -1
- package/dist/{C_Chat-CcjZdAwu.css.map → C_Chat-CcdWgVE8.css.map} +1 -1
- package/dist/{C_Chat-Diq7tyWU.css.map → C_Chat-Cx0woEEe.css.map} +1 -1
- package/dist/C_Chat.css +65 -65
- package/dist/C_Chat.js.map +1 -1
- package/dist/C_Chat2.js +1 -1
- package/dist/C_Chat2.js.map +1 -1
- package/dist/{C_City-Bam08Qv3.css.map → C_City-Cv5BESaN.css.map} +1 -1
- package/dist/{C_City-Bb3W-KaN.css.map → C_City-DNKv4MpH.css.map} +1 -1
- package/dist/C_City.css +29 -29
- package/dist/C_City.js.map +1 -1
- package/dist/C_City2.js +1 -1
- package/dist/C_City2.js.map +1 -1
- package/dist/C_Code-DPZlNSxL.css.map +1 -0
- package/dist/C_Code-avZjAnHD.css.map +1 -0
- package/dist/C_Code.css +3 -3
- package/dist/C_Code.js.map +1 -1
- package/dist/C_Code2.js +1 -1
- package/dist/C_Code2.js.map +1 -1
- package/dist/{C_CollapsePanel-BCmTFuDz.css.map → C_CollapsePanel-B18ryXwh.css.map} +1 -1
- package/dist/{C_CollapsePanel-Bxnh4Zy-.css.map → C_CollapsePanel-BiGoiHgh.css.map} +1 -1
- package/dist/C_CollapsePanel.css +35 -35
- package/dist/C_CollapsePanel.js.map +1 -1
- package/dist/C_CollapsePanel2.js +1 -1
- package/dist/C_CollapsePanel2.js.map +1 -1
- package/dist/{C_ContextMenu-B3Cgz_wJ.css.map → C_ContextMenu-CCsCeI39.css.map} +1 -1
- package/dist/{C_ContextMenu-u1LixF3_.css.map → C_ContextMenu-DOTBeltf.css.map} +1 -1
- package/dist/C_ContextMenu.css +17 -17
- package/dist/C_ContextMenu.js.map +1 -1
- package/dist/C_ContextMenu2.js +1 -1
- package/dist/C_ContextMenu2.js.map +1 -1
- package/dist/{C_Cron-Civir5-I.css.map → C_Cron-C0-8b5af.css.map} +1 -1
- package/dist/{C_Cron-iw3qpMsy.css.map → C_Cron-DqHQ92LN.css.map} +1 -1
- package/dist/C_Cron.css +37 -37
- package/dist/C_Cron.js.map +1 -1
- package/dist/C_Cron2.js +1 -1
- package/dist/C_Cron2.js.map +1 -1
- package/dist/C_Date.js.map +1 -1
- package/dist/C_Date2.js.map +1 -1
- package/dist/{C_Draggable-BCjIvIwT.css.map → C_Draggable-Bq6o0qXn.css.map} +1 -1
- package/dist/{C_Draggable-DwkSlCOS.css.map → C_Draggable-r6nhx3yM.css.map} +1 -1
- package/dist/C_Draggable.css +46 -46
- package/dist/C_Draggable.js.map +1 -1
- package/dist/C_Draggable2.js +1 -1
- package/dist/C_Draggable2.js.map +1 -1
- package/dist/{C_FilePreview-BhcbiXsV.css.map → C_FilePreview-BVarVvnD.css.map} +1 -1
- package/dist/{C_FilePreview-DJudcIbW.css.map → C_FilePreview-DHGlV4OR.css.map} +1 -1
- package/dist/C_FilePreview.css +91 -91
- package/dist/C_FilePreview.js.map +1 -1
- package/dist/C_FilePreview2.js +1 -1
- package/dist/C_FilePreview2.js.map +1 -1
- package/dist/{C_Form-BtcAPIRi.css.map → C_Form-BciQUPpS.css.map} +1 -1
- package/dist/{C_Form-D_gwQ7hC.css.map → C_Form-CKHvXL3O.css.map} +1 -1
- package/dist/C_Form.css +222 -222
- package/dist/C_Form.js.map +1 -1
- package/dist/C_Form2.js +1 -1
- package/dist/C_Form2.js.map +1 -1
- package/dist/{C_FormSearch-Bi4XYjjk.css.map → C_FormSearch-Bmd2CmG6.css.map} +1 -1
- package/dist/{C_FormSearch-DUGOoX0u.css.map → C_FormSearch-DBNtnjaL.css.map} +1 -1
- package/dist/C_FormSearch.css +45 -45
- package/dist/C_FormSearch.js.map +1 -1
- package/dist/C_FormSearch2.js +1 -1
- package/dist/C_FormSearch2.js.map +1 -1
- package/dist/{C_FormulaEditor-CJk3SSUJ.css.map → C_FormulaEditor-3WG2vtQl.css.map} +1 -1
- package/dist/{C_FormulaEditor-Cy7mjfVO.css.map → C_FormulaEditor-Cm0CokN5.css.map} +1 -1
- package/dist/C_FormulaEditor.css +78 -78
- package/dist/C_FormulaEditor.js.map +1 -1
- package/dist/C_FormulaEditor2.js +1 -1
- package/dist/C_FormulaEditor2.js.map +1 -1
- package/dist/C_FullCalendar-1U4VlG7X.css.map +1 -0
- package/dist/C_FullCalendar-DLUdCtqf.css.map +1 -0
- package/dist/C_FullCalendar.css +3 -3
- package/dist/C_FullCalendar.js.map +1 -1
- package/dist/C_FullCalendar2.js +1 -1
- package/dist/C_FullCalendar2.js.map +1 -1
- package/dist/C_Icon.js.map +1 -1
- package/dist/C_Icon2.js.map +1 -1
- package/dist/{C_ImageCropper-BqZpkZfU.css.map → C_ImageCropper-D3L2-J_J.css.map} +1 -1
- package/dist/{C_ImageCropper-CylwGuzS.css.map → C_ImageCropper-DrmUlaLi.css.map} +1 -1
- package/dist/C_ImageCropper.css +10 -10
- package/dist/C_ImageCropper.js.map +1 -1
- package/dist/C_ImageCropper2.js +1 -1
- package/dist/C_ImageCropper2.js.map +1 -1
- package/dist/C_Language.js.map +1 -1
- package/dist/C_Language2.js.map +1 -1
- package/dist/{C_Login-BkdnkBKX.css.map → C_Login-Cst_W1XC.css.map} +1 -1
- package/dist/{C_Login-VkMM6OJ2.css.map → C_Login-DWZ_6K1x.css.map} +1 -1
- package/dist/C_Login.css +72 -72
- package/dist/C_Login.js.map +1 -1
- package/dist/C_Login2.js +1 -1
- package/dist/C_Login2.js.map +1 -1
- package/dist/{C_Map-DNnBcY70.css.map → C_Map-BCJmDnJT.css.map} +1 -1
- package/dist/{C_Map-LEXIx6zM.css.map → C_Map-WUMXSAfy.css.map} +1 -1
- package/dist/C_Map.css +4 -4
- package/dist/C_Map.js.map +1 -1
- package/dist/C_Map2.js +1 -1
- package/dist/C_Map2.js.map +1 -1
- package/dist/{C_Markdown-Kujzx1qG.css.map → C_Markdown-7iBnLDtL.css.map} +1 -1
- package/dist/{C_Markdown-YCAmBbNF.css.map → C_Markdown-BbTvdFCl.css.map} +1 -1
- package/dist/C_Markdown.css +33 -33
- package/dist/C_Markdown.js.map +1 -1
- package/dist/C_Markdown2.js +1 -1
- package/dist/C_Markdown2.js.map +1 -1
- package/dist/{C_QRCode-CFNTda_1.css.map → C_QRCode-DMxSyogU.css.map} +1 -1
- package/dist/{C_QRCode-CmWr9lK-.css.map → C_QRCode-G7fiAkm4.css.map} +1 -1
- package/dist/C_QRCode.css +9 -9
- package/dist/C_QRCode.js.map +1 -1
- package/dist/C_QRCode2.js +1 -1
- package/dist/C_QRCode2.js.map +1 -1
- package/dist/{C_Signature-PN4GOLRX.css.map → C_Signature-B5fFz6RD.css.map} +1 -1
- package/dist/{C_Signature-fWQqGIZ-.css.map → C_Signature-es-ZNPzr.css.map} +1 -1
- package/dist/C_Signature.css +14 -14
- package/dist/C_Signature.js.map +1 -1
- package/dist/C_Signature2.js +1 -1
- package/dist/C_Signature2.js.map +1 -1
- package/dist/{C_SplitPane-BOwr1C7K.css.map → C_SplitPane-Br2eK8IG.css.map} +1 -1
- package/dist/{C_SplitPane-N-a_D-7F.css.map → C_SplitPane-DuyzUhKB.css.map} +1 -1
- package/dist/C_SplitPane.css +31 -31
- package/dist/C_SplitPane.js.map +1 -1
- package/dist/C_SplitPane2.js +1 -1
- package/dist/C_SplitPane2.js.map +1 -1
- package/dist/C_Steps-BHYNJI1l.css.map +1 -0
- package/dist/C_Steps-DY7vl-4I.css.map +1 -0
- package/dist/C_Steps.css +38 -38
- package/dist/C_Steps.js.map +1 -1
- package/dist/C_Steps2.js +1 -1
- package/dist/C_Steps2.js.map +1 -1
- package/dist/{C_Table-BV1wUw6f.css.map → C_Table-vZlcgH6x.css.map} +1 -1
- package/dist/{C_Table-LlJ-JEdm.css.map → C_Table-wzAO43l0.css.map} +1 -1
- package/dist/C_Table.css +93 -93
- package/dist/C_Table.js.map +1 -1
- package/dist/C_Table2.js +1 -1
- package/dist/C_Table2.js.map +1 -1
- package/dist/{C_TagsView-DX3LecK1.css.map → C_TagsView-BsutyC3U.css.map} +1 -1
- package/dist/{C_TagsView-DqOTa8bL.css.map → C_TagsView-Crm7yWg9.css.map} +1 -1
- package/dist/C_TagsView.css +36 -36
- package/dist/C_TagsView.js.map +1 -1
- package/dist/C_TagsView2.js +1 -1
- package/dist/C_TagsView2.js.map +1 -1
- package/dist/C_Time-Bd_e1YDN.css.map +1 -0
- package/dist/C_Time-CKb_fwdm.css.map +1 -0
- package/dist/C_Time.css +5 -5
- package/dist/C_Time.js.map +1 -1
- package/dist/C_Time2.js +1 -1
- package/dist/C_Time2.js.map +1 -1
- package/dist/{C_Timeline-BIvw3f41.css.map → C_Timeline-CGTFTMX0.css.map} +1 -1
- package/dist/{C_Timeline-VsDfCv4Q.css.map → C_Timeline-DxKyvKer.css.map} +1 -1
- package/dist/C_Timeline.css +42 -42
- package/dist/C_Timeline.js.map +1 -1
- package/dist/C_Timeline2.js +1 -1
- package/dist/C_Timeline2.js.map +1 -1
- package/dist/{C_Transfer-BOB6OBqS.css.map → C_Transfer-CCEqnC-v.css.map} +1 -1
- package/dist/{C_Transfer-Dpq7ezWC.css.map → C_Transfer-CStPm4NP.css.map} +1 -1
- package/dist/C_Transfer.css +31 -31
- package/dist/C_Transfer.js.map +1 -1
- package/dist/C_Transfer2.js +1 -1
- package/dist/C_Transfer2.js.map +1 -1
- package/dist/{C_Tree-D98nX9qT.css.map → C_Tree-B-Le4hjQ.css.map} +1 -1
- package/dist/{C_Tree-ulfm7b-P.css.map → C_Tree-DnGc_MPb.css.map} +1 -1
- package/dist/C_Tree.css +33 -33
- package/dist/C_Tree.js.map +1 -1
- package/dist/C_Tree2.js +1 -1
- package/dist/C_Tree2.js.map +1 -1
- package/dist/{C_VideoPlayer-4J96tKfK.css.map → C_VideoPlayer-Cdgv4Zq0.css.map} +1 -1
- package/dist/{C_VideoPlayer-D35seHkm.css.map → C_VideoPlayer-rm0MODUv.css.map} +1 -1
- package/dist/C_VideoPlayer.css +13 -13
- package/dist/C_VideoPlayer.js.map +1 -1
- package/dist/C_VideoPlayer2.js +1 -1
- package/dist/C_VideoPlayer2.js.map +1 -1
- package/dist/{C_VtableGantt-C2lxFmWg.css.map → C_VtableGantt-BpY-Rng3.css.map} +1 -1
- package/dist/{C_VtableGantt-Dwnkw_WL.css.map → C_VtableGantt-DB87-jdS.css.map} +1 -1
- package/dist/C_VtableGantt.css +15 -15
- package/dist/C_VtableGantt.js.map +1 -1
- package/dist/C_VtableGantt2.js +1 -1
- package/dist/C_VtableGantt2.js.map +1 -1
- package/dist/{C_WorkFlow-2hJfvvTK.css.map → C_WorkFlow-7F6op6qN.css.map} +1 -1
- package/dist/{C_WorkFlow-DHoNjl8-.css.map → C_WorkFlow-Cy3HWA6A.css.map} +1 -1
- package/dist/C_WorkFlow.css +108 -108
- package/dist/C_WorkFlow.js.map +1 -1
- package/dist/C_WorkFlow2.js +1 -1
- package/dist/C_WorkFlow2.js.map +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants2.d.ts +1 -1
- package/dist/constants3.d.ts +1 -1
- package/dist/constants4.d.ts +5 -5
- package/dist/data.d.ts +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index10.vue.d.ts +1 -1
- package/dist/index11.vue.d.ts +4 -4
- package/dist/index12.vue.d.ts +1 -1
- package/dist/index13.vue.d.ts +2 -2
- package/dist/index15.vue.d.ts +3 -3
- package/dist/index17.vue.d.ts +1 -1
- package/dist/index18.vue.d.ts +3 -3
- package/dist/index2.vue.d.ts +1 -1
- package/dist/index20.vue.d.ts +2 -2
- package/dist/index21.vue.d.ts +1 -1
- package/dist/index24.vue.d.ts +1 -1
- package/dist/index26.vue.d.ts +3 -3
- package/dist/index3.vue.d.ts +2 -2
- package/dist/index4.vue.d.ts +5 -5
- package/dist/index6.vue.d.ts +3 -3
- package/dist/index8.vue.d.ts +1 -1
- package/dist/menuAdapter.js.map +1 -1
- package/dist/resolver.cjs.map +1 -1
- package/dist/resolver.js.map +1 -1
- package/dist/style.css +1512 -1512
- package/dist/useCalendarEvents.d.ts +1 -1
- package/dist/useCollapsePanel.d.ts +3 -1
- package/dist/useCropperCore.d.ts +5 -5
- package/dist/useDraggableLayout.d.ts +9 -9
- package/dist/useDynamicFormState.d.ts +4 -4
- package/dist/useEdgeInteraction.d.ts +1 -1
- package/dist/useFullscreen.d.ts +2 -2
- package/dist/useInfiniteScroll.d.ts +3 -3
- package/dist/useModalEdit.d.ts +3 -3
- package/dist/useQRCode.d.ts +3 -3
- package/dist/useSignatureHistory.d.ts +1 -1
- package/dist/useSplitResize.d.ts +5 -5
- package/dist/useTimeSelection.d.ts +3 -3
- package/dist/useTreeOperations.d.ts +6 -6
- package/dist/useWorkflowValidation.d.ts +2 -2
- package/package.json +1 -1
- package/dist/C_ActionBar-DYG0Yf3A.css.map +0 -1
- package/dist/C_ActionBar-MAjRhqcI.css.map +0 -1
- package/dist/C_Code-BFi5xxnM.css.map +0 -1
- package/dist/C_Code-CZ7yfnri.css.map +0 -1
- package/dist/C_FullCalendar-BQA0OjGB.css.map +0 -1
- package/dist/C_FullCalendar-ChJUosAi.css.map +0 -1
- package/dist/C_Steps-Bk1krgiR.css.map +0 -1
- package/dist/C_Steps-Dn2CMpy1.css.map +0 -1
- package/dist/C_Time-BzyQVvTS.css.map +0 -1
- package/dist/C_Time-DmpKLQHc.css.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_AvatarGroup2.js","names":[],"sources":["../src/components/C_AvatarGroup/types.ts","../src/components/C_AvatarGroup/index.vue","../src/components/C_AvatarGroup/index.vue","../src/components/C_AvatarGroup/index.vue"],"sourcesContent":["/**\n * @Description: 头像组组件类型定义\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\n */\n\n/** 单个头像数据 */\nexport interface AvatarItem {\n /** 唯一标识 */\n id: string | number\n /** 头像图片 URL */\n src?: string\n /** 姓名(用于首字母 fallback 和 tooltip) */\n name: string\n /** 悬浮提示(默认取 name) */\n tooltip?: string\n /** 在线状态 */\n status?: 'online' | 'offline' | 'busy' | 'away'\n /** 额外数据 */\n extra?: Record<string, unknown>\n}\n\n/** 组件 Props */\nexport interface AvatarGroupProps {\n /** 头像数据列表 */\n items: AvatarItem[]\n /** 最多显示数量(超出 +N) */\n max?: number\n /** 头像尺寸 (px) */\n size?: number\n /** 头像间重叠偏移量 (px),负值表示堆叠 */\n overlap?: number\n /** 形状 */\n shape?: 'circle' | 'square'\n /** 是否显示状态指示点 */\n showStatus?: boolean\n /** 是否显示悬浮提示 */\n showTooltip?: boolean\n /** 是否可点击 */\n clickable?: boolean\n /** +N 溢出按钮是否可点击 */\n overflowClickable?: boolean\n /** 堆叠方向 */\n direction?: 'ltr' | 'rtl'\n}\n\n/** 默认 Props */\nexport const DEFAULT_AVATAR_GROUP_PROPS: Partial<AvatarGroupProps> = {\n max: 5,\n size: 40,\n overlap: -10,\n shape: 'circle',\n showStatus: true,\n showTooltip: true,\n clickable: false,\n overflowClickable: true,\n direction: 'ltr',\n}\n\n/** 状态颜色映射 */\nexport const STATUS_COLOR_MAP: Record<string, string> = {\n online: '#18a058',\n offline: '#909399',\n busy: '#e53e3e',\n away: '#f0a020',\n}\n\n/** 从名字中提取首字母 */\nexport function getInitials(name: string): string {\n if (!name) return '?'\n const parts = name.trim().split(/\\s+/)\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase()\n // 中文直接取最后一个字\n if (/[\\u4E00-\\u9FFF]/.test(name)) return name.slice(-1)\n return name.slice(0, 2).toUpperCase()\n}\n\n/** 根据名字生成稳定的背景色 */\nexport function nameToColor(name: string): string {\n const palette = [\n '#6366f1',\n '#8b5cf6',\n '#a855f7',\n '#d946ef',\n '#ec4899',\n '#f43f5e',\n '#ef4444',\n '#f97316',\n '#eab308',\n '#84cc16',\n '#22c55e',\n '#14b8a6',\n '#06b6d4',\n '#0ea5e9',\n '#3b82f6',\n '#6d28d9',\n ]\n let hash = 0\n for (let i = 0; i < name.length; i++) {\n hash = name.charCodeAt(i) + ((hash * 31) | 0)\n }\n return palette[Math.abs(hash) % palette.length]\n}\n","/* unplugin-vue-components disabled */<!--\n * @Description: 头像组组件\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\n-->\n<template>\n <div\n class=\"c-avatar-group\"\n :class=\"{ 'is-rtl': mergedProps.direction === 'rtl' }\"\n >\n <NTooltip\n v-for=\"(item, idx) in visibleItems\"\n :key=\"item.id\"\n :disabled=\"!mergedProps.showTooltip\"\n placement=\"top\"\n >\n <template #trigger>\n <div\n class=\"c-avatar-group__item\"\n :class=\"[\n `is-${mergedProps.shape}`,\n { 'is-clickable': mergedProps.clickable },\n ]\"\n :style=\"itemStyle(idx)\"\n @click=\"mergedProps.clickable && emit('itemClick', item)\"\n >\n <img\n v-if=\"item.src\"\n :src=\"item.src\"\n :alt=\"item.name\"\n class=\"c-avatar-group__img\"\n />\n <div\n v-else\n class=\"c-avatar-group__initials\"\n :style=\"{\n background: nameToColor(item.name),\n fontSize: initialsFontSize,\n }\"\n >\n {{ getInitials(item.name) }}\n </div>\n\n <span\n v-if=\"mergedProps.showStatus && item.status\"\n class=\"c-avatar-group__status\"\n :style=\"statusStyle(item.status)\"\n />\n </div>\n </template>\n {{ item.tooltip ?? item.name }}\n </NTooltip>\n\n <!-- 溢出 +N -->\n <NTooltip\n v-if=\"overflowCount > 0\"\n placement=\"top\"\n >\n <template #trigger>\n <div\n class=\"c-avatar-group__overflow\"\n :class=\"[\n `is-${mergedProps.shape}`,\n { 'is-clickable': mergedProps.overflowClickable },\n ]\"\n :style=\"overflowStyle\"\n @click=\"\n mergedProps.overflowClickable && emit('overflowClick', hiddenItems)\n \"\n >\n +{{ overflowCount }}\n </div>\n </template>\n <div style=\"max-width: 200px\">\n <div\n v-for=\"h in hiddenItems\"\n :key=\"h.id\"\n style=\"line-height: 1.6\"\n >\n {{ h.name }}\n </div>\n </div>\n </NTooltip>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import {\n DEFAULT_AVATAR_GROUP_PROPS,\n getInitials,\n nameToColor,\n STATUS_COLOR_MAP,\n type AvatarGroupProps,\n type AvatarItem,\n } from './types'\n\n const props = withDefaults(\n defineProps<{\n items: AvatarGroupProps['items']\n max?: number\n size?: number\n overlap?: number\n shape?: AvatarGroupProps['shape']\n showStatus?: boolean\n showTooltip?: boolean\n clickable?: boolean\n overflowClickable?: boolean\n direction?: AvatarGroupProps['direction']\n }>(),\n {\n max: DEFAULT_AVATAR_GROUP_PROPS.max,\n size: DEFAULT_AVATAR_GROUP_PROPS.size,\n overlap: DEFAULT_AVATAR_GROUP_PROPS.overlap,\n shape: DEFAULT_AVATAR_GROUP_PROPS.shape,\n showStatus: DEFAULT_AVATAR_GROUP_PROPS.showStatus,\n showTooltip: DEFAULT_AVATAR_GROUP_PROPS.showTooltip,\n clickable: DEFAULT_AVATAR_GROUP_PROPS.clickable,\n overflowClickable: DEFAULT_AVATAR_GROUP_PROPS.overflowClickable,\n direction: DEFAULT_AVATAR_GROUP_PROPS.direction,\n }\n )\n\n const emit = defineEmits<{\n itemClick: [item: AvatarItem]\n overflowClick: [hiddenItems: AvatarItem[]]\n }>()\n\n const mergedProps = computed(() => ({\n ...DEFAULT_AVATAR_GROUP_PROPS,\n ...props,\n }))\n\n const visibleItems = computed(() => {\n const max = mergedProps.value.max!\n return props.items.length > max ? props.items.slice(0, max) : props.items\n })\n\n const hiddenItems = computed(() => {\n const max = mergedProps.value.max!\n return props.items.length > max ? props.items.slice(max) : []\n })\n\n const overflowCount = computed(() => hiddenItems.value.length)\n\n const initialsFontSize = computed(\n () => `${Math.round(mergedProps.value.size! * 0.38)}px`\n )\n\n /** 计算头像项定位样式 */\n function itemStyle(idx: number) {\n const s = mergedProps.value.size!\n const overlap = mergedProps.value.overlap!\n return {\n width: `${s}px`,\n height: `${s}px`,\n marginLeft: idx === 0 ? '0' : `${overlap}px`,\n }\n }\n\n const overflowStyle = computed(() => {\n const s = mergedProps.value.size!\n const overlap = mergedProps.value.overlap!\n return {\n width: `${s}px`,\n height: `${s}px`,\n marginLeft: `${overlap}px`,\n fontSize: `${Math.round(s * 0.32)}px`,\n }\n })\n\n /** 计算状态指示点样式 */\n function statusStyle(status: string) {\n const dotSize = Math.max(8, Math.round(mergedProps.value.size! * 0.24))\n return {\n width: `${dotSize}px`,\n height: `${dotSize}px`,\n backgroundColor: STATUS_COLOR_MAP[status] ?? STATUS_COLOR_MAP.offline,\n }\n }\n</script>\n\n<style scoped lang=\"scss\">\n @use './index.scss';\n</style>\n","/* unplugin-vue-components disabled */<!--\n * @Description: 头像组组件\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\n-->\n<template>\n <div\n class=\"c-avatar-group\"\n :class=\"{ 'is-rtl': mergedProps.direction === 'rtl' }\"\n >\n <NTooltip\n v-for=\"(item, idx) in visibleItems\"\n :key=\"item.id\"\n :disabled=\"!mergedProps.showTooltip\"\n placement=\"top\"\n >\n <template #trigger>\n <div\n class=\"c-avatar-group__item\"\n :class=\"[\n `is-${mergedProps.shape}`,\n { 'is-clickable': mergedProps.clickable },\n ]\"\n :style=\"itemStyle(idx)\"\n @click=\"mergedProps.clickable && emit('itemClick', item)\"\n >\n <img\n v-if=\"item.src\"\n :src=\"item.src\"\n :alt=\"item.name\"\n class=\"c-avatar-group__img\"\n />\n <div\n v-else\n class=\"c-avatar-group__initials\"\n :style=\"{\n background: nameToColor(item.name),\n fontSize: initialsFontSize,\n }\"\n >\n {{ getInitials(item.name) }}\n </div>\n\n <span\n v-if=\"mergedProps.showStatus && item.status\"\n class=\"c-avatar-group__status\"\n :style=\"statusStyle(item.status)\"\n />\n </div>\n </template>\n {{ item.tooltip ?? item.name }}\n </NTooltip>\n\n <!-- 溢出 +N -->\n <NTooltip\n v-if=\"overflowCount > 0\"\n placement=\"top\"\n >\n <template #trigger>\n <div\n class=\"c-avatar-group__overflow\"\n :class=\"[\n `is-${mergedProps.shape}`,\n { 'is-clickable': mergedProps.overflowClickable },\n ]\"\n :style=\"overflowStyle\"\n @click=\"\n mergedProps.overflowClickable && emit('overflowClick', hiddenItems)\n \"\n >\n +{{ overflowCount }}\n </div>\n </template>\n <div style=\"max-width: 200px\">\n <div\n v-for=\"h in hiddenItems\"\n :key=\"h.id\"\n style=\"line-height: 1.6\"\n >\n {{ h.name }}\n </div>\n </div>\n </NTooltip>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import {\n DEFAULT_AVATAR_GROUP_PROPS,\n getInitials,\n nameToColor,\n STATUS_COLOR_MAP,\n type AvatarGroupProps,\n type AvatarItem,\n } from './types'\n\n const props = withDefaults(\n defineProps<{\n items: AvatarGroupProps['items']\n max?: number\n size?: number\n overlap?: number\n shape?: AvatarGroupProps['shape']\n showStatus?: boolean\n showTooltip?: boolean\n clickable?: boolean\n overflowClickable?: boolean\n direction?: AvatarGroupProps['direction']\n }>(),\n {\n max: DEFAULT_AVATAR_GROUP_PROPS.max,\n size: DEFAULT_AVATAR_GROUP_PROPS.size,\n overlap: DEFAULT_AVATAR_GROUP_PROPS.overlap,\n shape: DEFAULT_AVATAR_GROUP_PROPS.shape,\n showStatus: DEFAULT_AVATAR_GROUP_PROPS.showStatus,\n showTooltip: DEFAULT_AVATAR_GROUP_PROPS.showTooltip,\n clickable: DEFAULT_AVATAR_GROUP_PROPS.clickable,\n overflowClickable: DEFAULT_AVATAR_GROUP_PROPS.overflowClickable,\n direction: DEFAULT_AVATAR_GROUP_PROPS.direction,\n }\n )\n\n const emit = defineEmits<{\n itemClick: [item: AvatarItem]\n overflowClick: [hiddenItems: AvatarItem[]]\n }>()\n\n const mergedProps = computed(() => ({\n ...DEFAULT_AVATAR_GROUP_PROPS,\n ...props,\n }))\n\n const visibleItems = computed(() => {\n const max = mergedProps.value.max!\n return props.items.length > max ? props.items.slice(0, max) : props.items\n })\n\n const hiddenItems = computed(() => {\n const max = mergedProps.value.max!\n return props.items.length > max ? props.items.slice(max) : []\n })\n\n const overflowCount = computed(() => hiddenItems.value.length)\n\n const initialsFontSize = computed(\n () => `${Math.round(mergedProps.value.size! * 0.38)}px`\n )\n\n /** 计算头像项定位样式 */\n function itemStyle(idx: number) {\n const s = mergedProps.value.size!\n const overlap = mergedProps.value.overlap!\n return {\n width: `${s}px`,\n height: `${s}px`,\n marginLeft: idx === 0 ? '0' : `${overlap}px`,\n }\n }\n\n const overflowStyle = computed(() => {\n const s = mergedProps.value.size!\n const overlap = mergedProps.value.overlap!\n return {\n width: `${s}px`,\n height: `${s}px`,\n marginLeft: `${overlap}px`,\n fontSize: `${Math.round(s * 0.32)}px`,\n }\n })\n\n /** 计算状态指示点样式 */\n function statusStyle(status: string) {\n const dotSize = Math.max(8, Math.round(mergedProps.value.size! * 0.24))\n return {\n width: `${dotSize}px`,\n height: `${dotSize}px`,\n backgroundColor: STATUS_COLOR_MAP[status] ?? STATUS_COLOR_MAP.offline,\n }\n }\n</script>\n\n<style scoped lang=\"scss\">\n @use './index.scss';\n</style>\n","<!--\n * @Description: 头像组组件\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\n-->\n<template>\n <div\n class=\"c-avatar-group\"\n :class=\"{ 'is-rtl': mergedProps.direction === 'rtl' }\"\n >\n <NTooltip\n v-for=\"(item, idx) in visibleItems\"\n :key=\"item.id\"\n :disabled=\"!mergedProps.showTooltip\"\n placement=\"top\"\n >\n <template #trigger>\n <div\n class=\"c-avatar-group__item\"\n :class=\"[\n `is-${mergedProps.shape}`,\n { 'is-clickable': mergedProps.clickable },\n ]\"\n :style=\"itemStyle(idx)\"\n @click=\"mergedProps.clickable && emit('itemClick', item)\"\n >\n <img\n v-if=\"item.src\"\n :src=\"item.src\"\n :alt=\"item.name\"\n class=\"c-avatar-group__img\"\n />\n <div\n v-else\n class=\"c-avatar-group__initials\"\n :style=\"{\n background: nameToColor(item.name),\n fontSize: initialsFontSize,\n }\"\n >\n {{ getInitials(item.name) }}\n </div>\n\n <span\n v-if=\"mergedProps.showStatus && item.status\"\n class=\"c-avatar-group__status\"\n :style=\"statusStyle(item.status)\"\n />\n </div>\n </template>\n {{ item.tooltip ?? item.name }}\n </NTooltip>\n\n <!-- 溢出 +N -->\n <NTooltip\n v-if=\"overflowCount > 0\"\n placement=\"top\"\n >\n <template #trigger>\n <div\n class=\"c-avatar-group__overflow\"\n :class=\"[\n `is-${mergedProps.shape}`,\n { 'is-clickable': mergedProps.overflowClickable },\n ]\"\n :style=\"overflowStyle\"\n @click=\"\n mergedProps.overflowClickable && emit('overflowClick', hiddenItems)\n \"\n >\n +{{ overflowCount }}\n </div>\n </template>\n <div style=\"max-width: 200px\">\n <div\n v-for=\"h in hiddenItems\"\n :key=\"h.id\"\n style=\"line-height: 1.6\"\n >\n {{ h.name }}\n </div>\n </div>\n </NTooltip>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import {\n DEFAULT_AVATAR_GROUP_PROPS,\n getInitials,\n nameToColor,\n STATUS_COLOR_MAP,\n type AvatarGroupProps,\n type AvatarItem,\n } from './types'\n\n const props = withDefaults(\n defineProps<{\n items: AvatarGroupProps['items']\n max?: number\n size?: number\n overlap?: number\n shape?: AvatarGroupProps['shape']\n showStatus?: boolean\n showTooltip?: boolean\n clickable?: boolean\n overflowClickable?: boolean\n direction?: AvatarGroupProps['direction']\n }>(),\n {\n max: DEFAULT_AVATAR_GROUP_PROPS.max,\n size: DEFAULT_AVATAR_GROUP_PROPS.size,\n overlap: DEFAULT_AVATAR_GROUP_PROPS.overlap,\n shape: DEFAULT_AVATAR_GROUP_PROPS.shape,\n showStatus: DEFAULT_AVATAR_GROUP_PROPS.showStatus,\n showTooltip: DEFAULT_AVATAR_GROUP_PROPS.showTooltip,\n clickable: DEFAULT_AVATAR_GROUP_PROPS.clickable,\n overflowClickable: DEFAULT_AVATAR_GROUP_PROPS.overflowClickable,\n direction: DEFAULT_AVATAR_GROUP_PROPS.direction,\n }\n )\n\n const emit = defineEmits<{\n itemClick: [item: AvatarItem]\n overflowClick: [hiddenItems: AvatarItem[]]\n }>()\n\n const mergedProps = computed(() => ({\n ...DEFAULT_AVATAR_GROUP_PROPS,\n ...props,\n }))\n\n const visibleItems = computed(() => {\n const max = mergedProps.value.max!\n return props.items.length > max ? props.items.slice(0, max) : props.items\n })\n\n const hiddenItems = computed(() => {\n const max = mergedProps.value.max!\n return props.items.length > max ? props.items.slice(max) : []\n })\n\n const overflowCount = computed(() => hiddenItems.value.length)\n\n const initialsFontSize = computed(\n () => `${Math.round(mergedProps.value.size! * 0.38)}px`\n )\n\n /** 计算头像项定位样式 */\n function itemStyle(idx: number) {\n const s = mergedProps.value.size!\n const overlap = mergedProps.value.overlap!\n return {\n width: `${s}px`,\n height: `${s}px`,\n marginLeft: idx === 0 ? '0' : `${overlap}px`,\n }\n }\n\n const overflowStyle = computed(() => {\n const s = mergedProps.value.size!\n const overlap = mergedProps.value.overlap!\n return {\n width: `${s}px`,\n height: `${s}px`,\n marginLeft: `${overlap}px`,\n fontSize: `${Math.round(s * 0.32)}px`,\n }\n })\n\n /** 计算状态指示点样式 */\n function statusStyle(status: string) {\n const dotSize = Math.max(8, Math.round(mergedProps.value.size! * 0.24))\n return {\n width: `${dotSize}px`,\n height: `${dotSize}px`,\n backgroundColor: STATUS_COLOR_MAP[status] ?? STATUS_COLOR_MAP.offline,\n }\n }\n</script>\n\n<style scoped lang=\"scss\">\n @use './index.scss';\n</style>\n"],"mappings":"+WA8CA,MAAa,EAAwD,CACnE,IAAK,EACL,KAAM,GACN,QAAS,IACT,MAAO,SACP,WAAY,GACZ,YAAa,GACb,UAAW,GACX,kBAAmB,GACnB,UAAW,MACZ,CAGY,EAA2C,CACtD,OAAQ,UACR,QAAS,UACT,KAAM,UACN,KAAM,UACP,CAGD,SAAgB,EAAY,EAAsB,CAChD,GAAI,CAAC,EAAM,MAAO,IAClB,IAAM,EAAQ,EAAK,MAAM,CAAC,MAAM,MAAM,CAItC,OAHI,EAAM,QAAU,GAAW,EAAM,GAAG,GAAK,EAAM,GAAG,IAAI,aAAa,CAEnE,kBAAkB,KAAK,EAAK,CAAS,EAAK,MAAM,GAAG,CAChD,EAAK,MAAM,EAAG,EAAE,CAAC,aAAa,CAIvC,SAAgB,EAAY,EAAsB,CAChD,IAAM,EAAU,CACd,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACD,CACG,EAAO,EACX,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAC/B,EAAO,EAAK,WAAW,EAAE,EAAK,EAAO,GAAM,GAE7C,OAAO,EAAQ,KAAK,IAAI,EAAK,CAAG,EAAQ,qfGJxC,IAAM,EAAQ,EA0BR,EAAO,EAKP,EAAc,OAAgB,CAClC,GAAG,EACH,GAAG,EACJ,EAAC,CAEI,EAAe,MAAe,CAClC,IAAM,EAAM,EAAY,MAAM,IAC9B,OAAO,EAAM,MAAM,OAAS,EAAM,EAAM,MAAM,MAAM,EAAG,EAAI,CAAG,EAAM,OACrE,CAEK,EAAc,MAAe,CACjC,IAAM,EAAM,EAAY,MAAM,IAC9B,OAAO,EAAM,MAAM,OAAS,EAAM,EAAM,MAAM,MAAM,EAAI,CAAG,EAAC,EAC7D,CAEK,EAAgB,MAAe,EAAY,MAAM,OAAM,CAEvD,EAAmB,MACjB,GAAG,KAAK,MAAM,EAAY,MAAM,KAAQ,IAAK,CAAC,IACtD,CAGA,SAAS,EAAU,EAAa,CAC9B,IAAM,EAAI,EAAY,MAAM,KACtB,EAAU,EAAY,MAAM,QAClC,MAAO,CACL,MAAO,GAAG,EAAE,IACZ,OAAQ,GAAG,EAAE,IACb,WAAY,IAAQ,EAAI,IAAM,GAAG,EAAQ,IAC3C,CAGF,IAAM,EAAgB,MAAe,CACnC,IAAM,EAAI,EAAY,MAAM,KACtB,EAAU,EAAY,MAAM,QAClC,MAAO,CACL,MAAO,GAAG,EAAE,IACZ,OAAQ,GAAG,EAAE,IACb,WAAY,GAAG,EAAQ,IACvB,SAAU,GAAG,KAAK,MAAM,EAAI,IAAK,CAAC,IACpC,EACD,CAGD,SAAS,EAAY,EAAgB,CACnC,IAAM,EAAU,KAAK,IAAI,EAAG,KAAK,MAAM,EAAY,MAAM,KAAQ,IAAK,CAAA,CACtE,MAAO,CACL,MAAO,GAAG,EAAQ,IAClB,OAAQ,GAAG,EAAQ,IACnB,gBAAiB,EAAiB,IAAW,EAAiB,QAChE,kCA5KF,EA6EM,MAAA,CA5EJ,MAAK,EAAA,CAAC,iBAAgB,CAAA,SACF,EAAA,MAAY,YAAS,MAAA,CAAA,CAAA,CAAA,CAAA,QAEzC,EAyCW,EAAA,KAAA,EAxCa,EAAA,OAAd,EAAM,SADhB,EAyCW,EAAA,CAvCR,IAAK,EAAK,GACV,SAAQ,CAAG,EAAA,MAAY,YACxB,UAAU,QAEC,QAAO,MAgCV,CA/BN,EA+BM,MAAA,CA9BJ,MAAK,EAAA,CAAC,uBAAsB,CAAA,MACA,EAAA,MAAY,QAAA,CAAA,eAAuC,EAAA,MAAY,UAAS,CAAA,CAAA,CAAA,CAInG,MAAK,EAAE,EAAU,EAAG,CAAA,CACpB,QAAK,GAAE,EAAA,MAAY,WAAa,EAAI,YAAc,EAAI,GAG/C,EAAK,KAAA,GAAA,CADb,EAKE,MAAA,OAHC,IAAK,EAAK,IACV,IAAK,EAAK,KACX,MAAM,uCAER,EASM,MAAA,OAPJ,MAAM,2BACL,MAAK,EAAA,YAA8B,EAAA,EAAW,CAAC,EAAK,KAAI,UAA2B,EAAA,WAKjF,EAAA,EAAW,CAAC,EAAK,KAAI,CAAA,CAAA,EAAA,EAIlB,EAAA,MAAY,YAAc,EAAK,QAAA,GAAA,CADvC,EAIE,OAAA,OAFA,MAAM,yBACL,MAAK,EAAE,EAAY,EAAK,OAAM,CAAA,+CAIrC,CAAA,EADW,IACX,EAAG,EAAK,SAAW,EAAK,KAAI,CAAA,EAAA,CAAA,CAAA,iCAG9B,EAAA,UAAc,CAEN,EAAA,MAAa,GAAA,GAAA,CADrB,EA4BW,EAAA,OA1BT,UAAU,QAEC,QAAO,MAaV,CAZN,EAYM,MAAA,CAXJ,MAAK,EAAA,CAAC,2BAA0B,CAAA,MACJ,EAAA,MAAY,QAAA,CAAA,eAAuC,EAAA,MAAY,kBAAiB,CAAA,CAAA,CAAA,CAI3G,MAAK,EAAE,EAAA,MAAa,CACpB,QAAK,AAAA,EAAA,KAAA,GAAe,EAAA,MAAY,mBAAqB,EAAI,gBAAkB,EAAA,MAAW,EAGxF,KACE,EAAG,EAAA,MAAa,CAAA,EAAA,CAAA,CAAA,eAWf,CARN,EAQM,MARN,EAQM,EAAA,EAAA,GAAA,CAPJ,EAMM,EAAA,KAAA,EALQ,EAAA,MAAL,QADT,EAMM,MAAA,CAJH,IAAK,EAAE,GACR,MAAA,CAAA,cAAA,MAAA,IAEG,EAAE,KAAI,CAAA,EAAA"}
|
|
1
|
+
{"version":3,"file":"C_AvatarGroup2.js","names":[],"sources":["../src/components/C_AvatarGroup/types.ts","../src/components/C_AvatarGroup/index.vue","../src/components/C_AvatarGroup/index.vue","../src/components/C_AvatarGroup/index.vue"],"sourcesContent":["/**\r\n * @Description: 头像组组件类型定义\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\r\n */\r\n\r\n/** 单个头像数据 */\r\nexport interface AvatarItem {\r\n /** 唯一标识 */\r\n id: string | number\r\n /** 头像图片 URL */\r\n src?: string\r\n /** 姓名(用于首字母 fallback 和 tooltip) */\r\n name: string\r\n /** 悬浮提示(默认取 name) */\r\n tooltip?: string\r\n /** 在线状态 */\r\n status?: 'online' | 'offline' | 'busy' | 'away'\r\n /** 额外数据 */\r\n extra?: Record<string, unknown>\r\n}\r\n\r\n/** 组件 Props */\r\nexport interface AvatarGroupProps {\r\n /** 头像数据列表 */\r\n items: AvatarItem[]\r\n /** 最多显示数量(超出 +N) */\r\n max?: number\r\n /** 头像尺寸 (px) */\r\n size?: number\r\n /** 头像间重叠偏移量 (px),负值表示堆叠 */\r\n overlap?: number\r\n /** 形状 */\r\n shape?: 'circle' | 'square'\r\n /** 是否显示状态指示点 */\r\n showStatus?: boolean\r\n /** 是否显示悬浮提示 */\r\n showTooltip?: boolean\r\n /** 是否可点击 */\r\n clickable?: boolean\r\n /** +N 溢出按钮是否可点击 */\r\n overflowClickable?: boolean\r\n /** 堆叠方向 */\r\n direction?: 'ltr' | 'rtl'\r\n}\r\n\r\n/** 默认 Props */\r\nexport const DEFAULT_AVATAR_GROUP_PROPS: Partial<AvatarGroupProps> = {\r\n max: 5,\r\n size: 40,\r\n overlap: -10,\r\n shape: 'circle',\r\n showStatus: true,\r\n showTooltip: true,\r\n clickable: false,\r\n overflowClickable: true,\r\n direction: 'ltr',\r\n}\r\n\r\n/** 状态颜色映射 */\r\nexport const STATUS_COLOR_MAP: Record<string, string> = {\r\n online: '#18a058',\r\n offline: '#909399',\r\n busy: '#e53e3e',\r\n away: '#f0a020',\r\n}\r\n\r\n/** 从名字中提取首字母 */\r\nexport function getInitials(name: string): string {\r\n if (!name) return '?'\r\n const parts = name.trim().split(/\\s+/)\r\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase()\r\n // 中文直接取最后一个字\r\n if (/[\\u4E00-\\u9FFF]/.test(name)) return name.slice(-1)\r\n return name.slice(0, 2).toUpperCase()\r\n}\r\n\r\n/** 根据名字生成稳定的背景色 */\r\nexport function nameToColor(name: string): string {\r\n const palette = [\r\n '#6366f1',\r\n '#8b5cf6',\r\n '#a855f7',\r\n '#d946ef',\r\n '#ec4899',\r\n '#f43f5e',\r\n '#ef4444',\r\n '#f97316',\r\n '#eab308',\r\n '#84cc16',\r\n '#22c55e',\r\n '#14b8a6',\r\n '#06b6d4',\r\n '#0ea5e9',\r\n '#3b82f6',\r\n '#6d28d9',\r\n ]\r\n let hash = 0\r\n for (let i = 0; i < name.length; i++) {\r\n hash = name.charCodeAt(i) + ((hash * 31) | 0)\r\n }\r\n return palette[Math.abs(hash) % palette.length]\r\n}\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Description: 头像组组件\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-avatar-group\"\r\n :class=\"{ 'is-rtl': mergedProps.direction === 'rtl' }\"\r\n >\r\n <NTooltip\r\n v-for=\"(item, idx) in visibleItems\"\r\n :key=\"item.id\"\r\n :disabled=\"!mergedProps.showTooltip\"\r\n placement=\"top\"\r\n >\r\n <template #trigger>\r\n <div\r\n class=\"c-avatar-group__item\"\r\n :class=\"[\r\n `is-${mergedProps.shape}`,\r\n { 'is-clickable': mergedProps.clickable },\r\n ]\"\r\n :style=\"itemStyle(idx)\"\r\n @click=\"mergedProps.clickable && emit('itemClick', item)\"\r\n >\r\n <img\r\n v-if=\"item.src\"\r\n :src=\"item.src\"\r\n :alt=\"item.name\"\r\n class=\"c-avatar-group__img\"\r\n />\r\n <div\r\n v-else\r\n class=\"c-avatar-group__initials\"\r\n :style=\"{\r\n background: nameToColor(item.name),\r\n fontSize: initialsFontSize,\r\n }\"\r\n >\r\n {{ getInitials(item.name) }}\r\n </div>\r\n\r\n <span\r\n v-if=\"mergedProps.showStatus && item.status\"\r\n class=\"c-avatar-group__status\"\r\n :style=\"statusStyle(item.status)\"\r\n />\r\n </div>\r\n </template>\r\n {{ item.tooltip ?? item.name }}\r\n </NTooltip>\r\n\r\n <!-- 溢出 +N -->\r\n <NTooltip\r\n v-if=\"overflowCount > 0\"\r\n placement=\"top\"\r\n >\r\n <template #trigger>\r\n <div\r\n class=\"c-avatar-group__overflow\"\r\n :class=\"[\r\n `is-${mergedProps.shape}`,\r\n { 'is-clickable': mergedProps.overflowClickable },\r\n ]\"\r\n :style=\"overflowStyle\"\r\n @click=\"\r\n mergedProps.overflowClickable && emit('overflowClick', hiddenItems)\r\n \"\r\n >\r\n +{{ overflowCount }}\r\n </div>\r\n </template>\r\n <div style=\"max-width: 200px\">\r\n <div\r\n v-for=\"h in hiddenItems\"\r\n :key=\"h.id\"\r\n style=\"line-height: 1.6\"\r\n >\r\n {{ h.name }}\r\n </div>\r\n </div>\r\n </NTooltip>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import {\r\n DEFAULT_AVATAR_GROUP_PROPS,\r\n getInitials,\r\n nameToColor,\r\n STATUS_COLOR_MAP,\r\n type AvatarGroupProps,\r\n type AvatarItem,\r\n } from './types'\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n items: AvatarGroupProps['items']\r\n max?: number\r\n size?: number\r\n overlap?: number\r\n shape?: AvatarGroupProps['shape']\r\n showStatus?: boolean\r\n showTooltip?: boolean\r\n clickable?: boolean\r\n overflowClickable?: boolean\r\n direction?: AvatarGroupProps['direction']\r\n }>(),\r\n {\r\n max: DEFAULT_AVATAR_GROUP_PROPS.max,\r\n size: DEFAULT_AVATAR_GROUP_PROPS.size,\r\n overlap: DEFAULT_AVATAR_GROUP_PROPS.overlap,\r\n shape: DEFAULT_AVATAR_GROUP_PROPS.shape,\r\n showStatus: DEFAULT_AVATAR_GROUP_PROPS.showStatus,\r\n showTooltip: DEFAULT_AVATAR_GROUP_PROPS.showTooltip,\r\n clickable: DEFAULT_AVATAR_GROUP_PROPS.clickable,\r\n overflowClickable: DEFAULT_AVATAR_GROUP_PROPS.overflowClickable,\r\n direction: DEFAULT_AVATAR_GROUP_PROPS.direction,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n itemClick: [item: AvatarItem]\r\n overflowClick: [hiddenItems: AvatarItem[]]\r\n }>()\r\n\r\n const mergedProps = computed(() => ({\r\n ...DEFAULT_AVATAR_GROUP_PROPS,\r\n ...props,\r\n }))\r\n\r\n const visibleItems = computed(() => {\r\n const max = mergedProps.value.max!\r\n return props.items.length > max ? props.items.slice(0, max) : props.items\r\n })\r\n\r\n const hiddenItems = computed(() => {\r\n const max = mergedProps.value.max!\r\n return props.items.length > max ? props.items.slice(max) : []\r\n })\r\n\r\n const overflowCount = computed(() => hiddenItems.value.length)\r\n\r\n const initialsFontSize = computed(\r\n () => `${Math.round(mergedProps.value.size! * 0.38)}px`\r\n )\r\n\r\n /** 计算头像项定位样式 */\r\n function itemStyle(idx: number) {\r\n const s = mergedProps.value.size!\r\n const overlap = mergedProps.value.overlap!\r\n return {\r\n width: `${s}px`,\r\n height: `${s}px`,\r\n marginLeft: idx === 0 ? '0' : `${overlap}px`,\r\n }\r\n }\r\n\r\n const overflowStyle = computed(() => {\r\n const s = mergedProps.value.size!\r\n const overlap = mergedProps.value.overlap!\r\n return {\r\n width: `${s}px`,\r\n height: `${s}px`,\r\n marginLeft: `${overlap}px`,\r\n fontSize: `${Math.round(s * 0.32)}px`,\r\n }\r\n })\r\n\r\n /** 计算状态指示点样式 */\r\n function statusStyle(status: string) {\r\n const dotSize = Math.max(8, Math.round(mergedProps.value.size! * 0.24))\r\n return {\r\n width: `${dotSize}px`,\r\n height: `${dotSize}px`,\r\n backgroundColor: STATUS_COLOR_MAP[status] ?? STATUS_COLOR_MAP.offline,\r\n }\r\n }\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n @use './index.scss';\r\n</style>\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Description: 头像组组件\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-avatar-group\"\r\n :class=\"{ 'is-rtl': mergedProps.direction === 'rtl' }\"\r\n >\r\n <NTooltip\r\n v-for=\"(item, idx) in visibleItems\"\r\n :key=\"item.id\"\r\n :disabled=\"!mergedProps.showTooltip\"\r\n placement=\"top\"\r\n >\r\n <template #trigger>\r\n <div\r\n class=\"c-avatar-group__item\"\r\n :class=\"[\r\n `is-${mergedProps.shape}`,\r\n { 'is-clickable': mergedProps.clickable },\r\n ]\"\r\n :style=\"itemStyle(idx)\"\r\n @click=\"mergedProps.clickable && emit('itemClick', item)\"\r\n >\r\n <img\r\n v-if=\"item.src\"\r\n :src=\"item.src\"\r\n :alt=\"item.name\"\r\n class=\"c-avatar-group__img\"\r\n />\r\n <div\r\n v-else\r\n class=\"c-avatar-group__initials\"\r\n :style=\"{\r\n background: nameToColor(item.name),\r\n fontSize: initialsFontSize,\r\n }\"\r\n >\r\n {{ getInitials(item.name) }}\r\n </div>\r\n\r\n <span\r\n v-if=\"mergedProps.showStatus && item.status\"\r\n class=\"c-avatar-group__status\"\r\n :style=\"statusStyle(item.status)\"\r\n />\r\n </div>\r\n </template>\r\n {{ item.tooltip ?? item.name }}\r\n </NTooltip>\r\n\r\n <!-- 溢出 +N -->\r\n <NTooltip\r\n v-if=\"overflowCount > 0\"\r\n placement=\"top\"\r\n >\r\n <template #trigger>\r\n <div\r\n class=\"c-avatar-group__overflow\"\r\n :class=\"[\r\n `is-${mergedProps.shape}`,\r\n { 'is-clickable': mergedProps.overflowClickable },\r\n ]\"\r\n :style=\"overflowStyle\"\r\n @click=\"\r\n mergedProps.overflowClickable && emit('overflowClick', hiddenItems)\r\n \"\r\n >\r\n +{{ overflowCount }}\r\n </div>\r\n </template>\r\n <div style=\"max-width: 200px\">\r\n <div\r\n v-for=\"h in hiddenItems\"\r\n :key=\"h.id\"\r\n style=\"line-height: 1.6\"\r\n >\r\n {{ h.name }}\r\n </div>\r\n </div>\r\n </NTooltip>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import {\r\n DEFAULT_AVATAR_GROUP_PROPS,\r\n getInitials,\r\n nameToColor,\r\n STATUS_COLOR_MAP,\r\n type AvatarGroupProps,\r\n type AvatarItem,\r\n } from './types'\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n items: AvatarGroupProps['items']\r\n max?: number\r\n size?: number\r\n overlap?: number\r\n shape?: AvatarGroupProps['shape']\r\n showStatus?: boolean\r\n showTooltip?: boolean\r\n clickable?: boolean\r\n overflowClickable?: boolean\r\n direction?: AvatarGroupProps['direction']\r\n }>(),\r\n {\r\n max: DEFAULT_AVATAR_GROUP_PROPS.max,\r\n size: DEFAULT_AVATAR_GROUP_PROPS.size,\r\n overlap: DEFAULT_AVATAR_GROUP_PROPS.overlap,\r\n shape: DEFAULT_AVATAR_GROUP_PROPS.shape,\r\n showStatus: DEFAULT_AVATAR_GROUP_PROPS.showStatus,\r\n showTooltip: DEFAULT_AVATAR_GROUP_PROPS.showTooltip,\r\n clickable: DEFAULT_AVATAR_GROUP_PROPS.clickable,\r\n overflowClickable: DEFAULT_AVATAR_GROUP_PROPS.overflowClickable,\r\n direction: DEFAULT_AVATAR_GROUP_PROPS.direction,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n itemClick: [item: AvatarItem]\r\n overflowClick: [hiddenItems: AvatarItem[]]\r\n }>()\r\n\r\n const mergedProps = computed(() => ({\r\n ...DEFAULT_AVATAR_GROUP_PROPS,\r\n ...props,\r\n }))\r\n\r\n const visibleItems = computed(() => {\r\n const max = mergedProps.value.max!\r\n return props.items.length > max ? props.items.slice(0, max) : props.items\r\n })\r\n\r\n const hiddenItems = computed(() => {\r\n const max = mergedProps.value.max!\r\n return props.items.length > max ? props.items.slice(max) : []\r\n })\r\n\r\n const overflowCount = computed(() => hiddenItems.value.length)\r\n\r\n const initialsFontSize = computed(\r\n () => `${Math.round(mergedProps.value.size! * 0.38)}px`\r\n )\r\n\r\n /** 计算头像项定位样式 */\r\n function itemStyle(idx: number) {\r\n const s = mergedProps.value.size!\r\n const overlap = mergedProps.value.overlap!\r\n return {\r\n width: `${s}px`,\r\n height: `${s}px`,\r\n marginLeft: idx === 0 ? '0' : `${overlap}px`,\r\n }\r\n }\r\n\r\n const overflowStyle = computed(() => {\r\n const s = mergedProps.value.size!\r\n const overlap = mergedProps.value.overlap!\r\n return {\r\n width: `${s}px`,\r\n height: `${s}px`,\r\n marginLeft: `${overlap}px`,\r\n fontSize: `${Math.round(s * 0.32)}px`,\r\n }\r\n })\r\n\r\n /** 计算状态指示点样式 */\r\n function statusStyle(status: string) {\r\n const dotSize = Math.max(8, Math.round(mergedProps.value.size! * 0.24))\r\n return {\r\n width: `${dotSize}px`,\r\n height: `${dotSize}px`,\r\n backgroundColor: STATUS_COLOR_MAP[status] ?? STATUS_COLOR_MAP.offline,\r\n }\r\n }\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n @use './index.scss';\r\n</style>\r\n","<!--\r\n * @Description: 头像组组件\r\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-avatar-group\"\r\n :class=\"{ 'is-rtl': mergedProps.direction === 'rtl' }\"\r\n >\r\n <NTooltip\r\n v-for=\"(item, idx) in visibleItems\"\r\n :key=\"item.id\"\r\n :disabled=\"!mergedProps.showTooltip\"\r\n placement=\"top\"\r\n >\r\n <template #trigger>\r\n <div\r\n class=\"c-avatar-group__item\"\r\n :class=\"[\r\n `is-${mergedProps.shape}`,\r\n { 'is-clickable': mergedProps.clickable },\r\n ]\"\r\n :style=\"itemStyle(idx)\"\r\n @click=\"mergedProps.clickable && emit('itemClick', item)\"\r\n >\r\n <img\r\n v-if=\"item.src\"\r\n :src=\"item.src\"\r\n :alt=\"item.name\"\r\n class=\"c-avatar-group__img\"\r\n />\r\n <div\r\n v-else\r\n class=\"c-avatar-group__initials\"\r\n :style=\"{\r\n background: nameToColor(item.name),\r\n fontSize: initialsFontSize,\r\n }\"\r\n >\r\n {{ getInitials(item.name) }}\r\n </div>\r\n\r\n <span\r\n v-if=\"mergedProps.showStatus && item.status\"\r\n class=\"c-avatar-group__status\"\r\n :style=\"statusStyle(item.status)\"\r\n />\r\n </div>\r\n </template>\r\n {{ item.tooltip ?? item.name }}\r\n </NTooltip>\r\n\r\n <!-- 溢出 +N -->\r\n <NTooltip\r\n v-if=\"overflowCount > 0\"\r\n placement=\"top\"\r\n >\r\n <template #trigger>\r\n <div\r\n class=\"c-avatar-group__overflow\"\r\n :class=\"[\r\n `is-${mergedProps.shape}`,\r\n { 'is-clickable': mergedProps.overflowClickable },\r\n ]\"\r\n :style=\"overflowStyle\"\r\n @click=\"\r\n mergedProps.overflowClickable && emit('overflowClick', hiddenItems)\r\n \"\r\n >\r\n +{{ overflowCount }}\r\n </div>\r\n </template>\r\n <div style=\"max-width: 200px\">\r\n <div\r\n v-for=\"h in hiddenItems\"\r\n :key=\"h.id\"\r\n style=\"line-height: 1.6\"\r\n >\r\n {{ h.name }}\r\n </div>\r\n </div>\r\n </NTooltip>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import {\r\n DEFAULT_AVATAR_GROUP_PROPS,\r\n getInitials,\r\n nameToColor,\r\n STATUS_COLOR_MAP,\r\n type AvatarGroupProps,\r\n type AvatarItem,\r\n } from './types'\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n items: AvatarGroupProps['items']\r\n max?: number\r\n size?: number\r\n overlap?: number\r\n shape?: AvatarGroupProps['shape']\r\n showStatus?: boolean\r\n showTooltip?: boolean\r\n clickable?: boolean\r\n overflowClickable?: boolean\r\n direction?: AvatarGroupProps['direction']\r\n }>(),\r\n {\r\n max: DEFAULT_AVATAR_GROUP_PROPS.max,\r\n size: DEFAULT_AVATAR_GROUP_PROPS.size,\r\n overlap: DEFAULT_AVATAR_GROUP_PROPS.overlap,\r\n shape: DEFAULT_AVATAR_GROUP_PROPS.shape,\r\n showStatus: DEFAULT_AVATAR_GROUP_PROPS.showStatus,\r\n showTooltip: DEFAULT_AVATAR_GROUP_PROPS.showTooltip,\r\n clickable: DEFAULT_AVATAR_GROUP_PROPS.clickable,\r\n overflowClickable: DEFAULT_AVATAR_GROUP_PROPS.overflowClickable,\r\n direction: DEFAULT_AVATAR_GROUP_PROPS.direction,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n itemClick: [item: AvatarItem]\r\n overflowClick: [hiddenItems: AvatarItem[]]\r\n }>()\r\n\r\n const mergedProps = computed(() => ({\r\n ...DEFAULT_AVATAR_GROUP_PROPS,\r\n ...props,\r\n }))\r\n\r\n const visibleItems = computed(() => {\r\n const max = mergedProps.value.max!\r\n return props.items.length > max ? props.items.slice(0, max) : props.items\r\n })\r\n\r\n const hiddenItems = computed(() => {\r\n const max = mergedProps.value.max!\r\n return props.items.length > max ? props.items.slice(max) : []\r\n })\r\n\r\n const overflowCount = computed(() => hiddenItems.value.length)\r\n\r\n const initialsFontSize = computed(\r\n () => `${Math.round(mergedProps.value.size! * 0.38)}px`\r\n )\r\n\r\n /** 计算头像项定位样式 */\r\n function itemStyle(idx: number) {\r\n const s = mergedProps.value.size!\r\n const overlap = mergedProps.value.overlap!\r\n return {\r\n width: `${s}px`,\r\n height: `${s}px`,\r\n marginLeft: idx === 0 ? '0' : `${overlap}px`,\r\n }\r\n }\r\n\r\n const overflowStyle = computed(() => {\r\n const s = mergedProps.value.size!\r\n const overlap = mergedProps.value.overlap!\r\n return {\r\n width: `${s}px`,\r\n height: `${s}px`,\r\n marginLeft: `${overlap}px`,\r\n fontSize: `${Math.round(s * 0.32)}px`,\r\n }\r\n })\r\n\r\n /** 计算状态指示点样式 */\r\n function statusStyle(status: string) {\r\n const dotSize = Math.max(8, Math.round(mergedProps.value.size! * 0.24))\r\n return {\r\n width: `${dotSize}px`,\r\n height: `${dotSize}px`,\r\n backgroundColor: STATUS_COLOR_MAP[status] ?? STATUS_COLOR_MAP.offline,\r\n }\r\n }\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n @use './index.scss';\r\n</style>\r\n"],"mappings":"+WA8CA,MAAa,EAAwD,CACnE,IAAK,EACL,KAAM,GACN,QAAS,IACT,MAAO,SACP,WAAY,GACZ,YAAa,GACb,UAAW,GACX,kBAAmB,GACnB,UAAW,MACZ,CAGY,EAA2C,CACtD,OAAQ,UACR,QAAS,UACT,KAAM,UACN,KAAM,UACP,CAGD,SAAgB,EAAY,EAAsB,CAChD,GAAI,CAAC,EAAM,MAAO,IAClB,IAAM,EAAQ,EAAK,MAAM,CAAC,MAAM,MAAM,CAItC,OAHI,EAAM,QAAU,GAAW,EAAM,GAAG,GAAK,EAAM,GAAG,IAAI,aAAa,CAEnE,kBAAkB,KAAK,EAAK,CAAS,EAAK,MAAM,GAAG,CAChD,EAAK,MAAM,EAAG,EAAE,CAAC,aAAa,CAIvC,SAAgB,EAAY,EAAsB,CAChD,IAAM,EAAU,CACd,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACD,CACG,EAAO,EACX,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAC/B,EAAO,EAAK,WAAW,EAAE,EAAK,EAAO,GAAM,GAE7C,OAAO,EAAQ,KAAK,IAAI,EAAK,CAAG,EAAQ,qfGJxC,IAAM,EAAQ,EA0BR,EAAO,EAKP,EAAc,OAAgB,CAClC,GAAG,EACH,GAAG,EACJ,EAAE,CAEG,EAAe,MAAe,CAClC,IAAM,EAAM,EAAY,MAAM,IAC9B,OAAO,EAAM,MAAM,OAAS,EAAM,EAAM,MAAM,MAAM,EAAG,EAAI,CAAG,EAAM,OACpE,CAEI,EAAc,MAAe,CACjC,IAAM,EAAM,EAAY,MAAM,IAC9B,OAAO,EAAM,MAAM,OAAS,EAAM,EAAM,MAAM,MAAM,EAAI,CAAG,EAAE,EAC7D,CAEI,EAAgB,MAAe,EAAY,MAAM,OAAO,CAExD,EAAmB,MACjB,GAAG,KAAK,MAAM,EAAY,MAAM,KAAQ,IAAK,CAAC,IACrD,CAGD,SAAS,EAAU,EAAa,CAC9B,IAAM,EAAI,EAAY,MAAM,KACtB,EAAU,EAAY,MAAM,QAClC,MAAO,CACL,MAAO,GAAG,EAAE,IACZ,OAAQ,GAAG,EAAE,IACb,WAAY,IAAQ,EAAI,IAAM,GAAG,EAAQ,IAC1C,CAGH,IAAM,EAAgB,MAAe,CACnC,IAAM,EAAI,EAAY,MAAM,KACtB,EAAU,EAAY,MAAM,QAClC,MAAO,CACL,MAAO,GAAG,EAAE,IACZ,OAAQ,GAAG,EAAE,IACb,WAAY,GAAG,EAAQ,IACvB,SAAU,GAAG,KAAK,MAAM,EAAI,IAAK,CAAC,IACnC,EACD,CAGF,SAAS,EAAY,EAAgB,CACnC,IAAM,EAAU,KAAK,IAAI,EAAG,KAAK,MAAM,EAAY,MAAM,KAAQ,IAAK,CAAC,CACvE,MAAO,CACL,MAAO,GAAG,EAAQ,IAClB,OAAQ,GAAG,EAAQ,IACnB,gBAAiB,EAAiB,IAAW,EAAiB,QAC/D,kCA5KH,EA6EM,MAAA,CA5EJ,MAAK,EAAA,CAAC,iBAAgB,CAAA,SACF,EAAA,MAAY,YAAS,MAAA,CAAA,CAAA,CAAA,CAAA,QAEzC,EAyCW,EAAA,KAAA,EAxCa,EAAA,OAAd,EAAM,SADhB,EAyCW,EAAA,CAvCR,IAAK,EAAK,GACV,SAAQ,CAAG,EAAA,MAAY,YACxB,UAAU,QAEC,QAAO,MAgCV,CA/BN,EA+BM,MAAA,CA9BJ,MAAK,EAAA,CAAC,uBAAsB,CAAA,MACC,EAAA,MAAY,QAAA,CAAA,eAAwC,EAAA,MAAY,UAAS,CAAA,CAAA,CAAA,CAIrG,MAAK,EAAE,EAAU,EAAG,CAAA,CACpB,QAAK,GAAE,EAAA,MAAY,WAAa,EAAI,YAAc,EAAI,GAG/C,EAAK,KAAA,GAAA,CADb,EAKE,MAAA,OAHC,IAAK,EAAK,IACV,IAAK,EAAK,KACX,MAAM,uCAER,EASM,MAAA,OAPJ,MAAM,2BACL,MAAK,EAAA,YAA+B,EAAA,EAAW,CAAC,EAAK,KAAI,UAA4B,EAAA,WAKnF,EAAA,EAAW,CAAC,EAAK,KAAI,CAAA,CAAA,EAAA,EAIlB,EAAA,MAAY,YAAc,EAAK,QAAA,GAAA,CADvC,EAIE,OAAA,OAFA,MAAM,yBACL,MAAK,EAAE,EAAY,EAAK,OAAM,CAAA,+CAIrC,CAAA,EADW,IACX,EAAG,EAAK,SAAW,EAAK,KAAI,CAAA,EAAA,CAAA,CAAA,iCAG9B,EAAA,UAAc,CAEN,EAAA,MAAa,GAAA,GAAA,CADrB,EA4BW,EAAA,OA1BT,UAAU,QAEC,QAAO,MAaV,CAZN,EAYM,MAAA,CAXJ,MAAK,EAAA,CAAC,2BAA0B,CAAA,MACH,EAAA,MAAY,QAAA,CAAA,eAAwC,EAAA,MAAY,kBAAiB,CAAA,CAAA,CAAA,CAI7G,MAAK,EAAE,EAAA,MAAa,CACpB,QAAK,AAAA,EAAA,KAAA,GAAgB,EAAA,MAAY,mBAAqB,EAAI,gBAAkB,EAAA,MAAW,EAGzF,KACE,EAAG,EAAA,MAAa,CAAA,EAAA,CAAA,CAAA,eAWf,CARN,EAQM,MARN,EAQM,EAAA,EAAA,GAAA,CAPJ,EAMM,EAAA,KAAA,EALQ,EAAA,MAAL,QADT,EAMM,MAAA,CAJH,IAAK,EAAE,GACR,MAAA,CAAA,cAAA,MAAA,IAEG,EAAE,KAAI,CAAA,EAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Barcode-
|
|
1
|
+
{"version":3,"file":"C_Barcode-DjTmDkbQ.css","names":[],"sources":["../src/components/C_Barcode/index.vue?vue&type=style&index=0&scoped=e44c361d&lang.scss"],"sourcesContent":["/* unplugin-vue-components disabled */.c-barcode[data-v-e44c361d] {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n max-width: 100%;\n}\n.c-barcode .barcode-wrapper[data-v-e44c361d] {\n display: inline-block;\n padding: 8px;\n background: #ffffff;\n border-radius: 4px;\n transition: all 0.3s ease;\n overflow: hidden;\n max-width: 100%;\n}\n.c-barcode .barcode-wrapper.with-border[data-v-e44c361d] {\n border: 1px dashed #e0e0e0;\n}\n.c-barcode .barcode-wrapper[data-v-e44c361d]:hover {\n border-color: var(--c-primary, #409eff);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n.c-barcode .barcode-wrapper[data-v-e44c361d] svg {\n max-width: 100%;\n height: auto;\n display: block;\n overflow: visible;\n}\n.c-barcode .barcode-label[data-v-e44c361d] {\n font-size: 14px;\n color: #666;\n text-align: center;\n font-weight: 500;\n word-break: break-all;\n max-width: 100%;\n}"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Barcode-
|
|
1
|
+
{"version":3,"file":"C_Barcode-Do1Ozsmh.css","names":[],"sources":["../src/components/C_Barcode/index.vue?vue&type=style&index=0&scoped=e44c361d&lang.scss"],"sourcesContent":["/* unplugin-vue-components disabled */.c-barcode[data-v-e44c361d] {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n max-width: 100%;\n}\n.c-barcode .barcode-wrapper[data-v-e44c361d] {\n display: inline-block;\n padding: 8px;\n background: #ffffff;\n border-radius: 4px;\n transition: all 0.3s ease;\n overflow: hidden;\n max-width: 100%;\n}\n.c-barcode .barcode-wrapper.with-border[data-v-e44c361d] {\n border: 1px dashed #e0e0e0;\n}\n.c-barcode .barcode-wrapper[data-v-e44c361d]:hover {\n border-color: var(--c-primary, #409eff);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n.c-barcode .barcode-wrapper[data-v-e44c361d] svg {\n max-width: 100%;\n height: auto;\n display: block;\n overflow: visible;\n}\n.c-barcode .barcode-label[data-v-e44c361d] {\n font-size: 14px;\n color: #666;\n text-align: center;\n font-weight: 500;\n word-break: break-all;\n max-width: 100%;\n}"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}
|
package/dist/C_Barcode.css
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/* unplugin-vue-components disabled */.c-barcode[data-v-
|
|
1
|
+
/* unplugin-vue-components disabled */.c-barcode[data-v-e44c361d] {
|
|
2
2
|
display: inline-flex;
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
align-items: center;
|
|
5
5
|
gap: 8px;
|
|
6
6
|
max-width: 100%;
|
|
7
7
|
}
|
|
8
|
-
.c-barcode .barcode-wrapper[data-v-
|
|
8
|
+
.c-barcode .barcode-wrapper[data-v-e44c361d] {
|
|
9
9
|
display: inline-block;
|
|
10
10
|
padding: 8px;
|
|
11
11
|
background: #ffffff;
|
|
@@ -14,20 +14,20 @@
|
|
|
14
14
|
overflow: hidden;
|
|
15
15
|
max-width: 100%;
|
|
16
16
|
}
|
|
17
|
-
.c-barcode .barcode-wrapper.with-border[data-v-
|
|
17
|
+
.c-barcode .barcode-wrapper.with-border[data-v-e44c361d] {
|
|
18
18
|
border: 1px dashed #e0e0e0;
|
|
19
19
|
}
|
|
20
|
-
.c-barcode .barcode-wrapper[data-v-
|
|
20
|
+
.c-barcode .barcode-wrapper[data-v-e44c361d]:hover {
|
|
21
21
|
border-color: var(--c-primary, #409eff);
|
|
22
22
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
23
23
|
}
|
|
24
|
-
.c-barcode .barcode-wrapper[data-v-
|
|
24
|
+
.c-barcode .barcode-wrapper[data-v-e44c361d] svg {
|
|
25
25
|
max-width: 100%;
|
|
26
26
|
height: auto;
|
|
27
27
|
display: block;
|
|
28
28
|
overflow: visible;
|
|
29
29
|
}
|
|
30
|
-
.c-barcode .barcode-label[data-v-
|
|
30
|
+
.c-barcode .barcode-label[data-v-e44c361d] {
|
|
31
31
|
font-size: 14px;
|
|
32
32
|
color: #666;
|
|
33
33
|
text-align: center;
|
|
@@ -36,4 +36,4 @@
|
|
|
36
36
|
max-width: 100%;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
/*# sourceMappingURL=C_Barcode-
|
|
39
|
+
/*# sourceMappingURL=C_Barcode-DjTmDkbQ.css.map*/
|
package/dist/C_Barcode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Barcode.js","names":["showBorder","showLabel","label"],"sources":["../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2025-12-02\n * @Description: 条形码组件\n * @Migration: naive-ui-components 组件库迁移版本\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div class=\"c-barcode\">\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\n </div>\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\n {{ label }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\n\ndefineOptions({ name: \"C_Barcode\" });\n\ninterface Props {\n value: string;\n format?:\n | \"CODE128\"\n | \"CODE39\"\n | \"EAN13\"\n | \"EAN8\"\n | \"UPC\"\n | \"ITF14\"\n | \"MSI\"\n | \"pharmacode\";\n width?: number;\n height?: number;\n showText?: boolean;\n fontSize?: number;\n textPosition?: \"bottom\" | \"top\";\n lineColor?: string;\n background?: string;\n showBorder?: boolean;\n label?: string;\n showLabel?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n format: \"CODE128\",\n width: 2,\n height: 80,\n showText: true,\n fontSize: 20,\n textPosition: \"bottom\",\n lineColor: \"#000000\",\n background: \"#FFFFFF\",\n showBorder: true,\n label: \"\",\n showLabel: false,\n});\n\nconst emit = defineEmits<{\n error: [error: Error];\n}>();\n\nconst barcodeProps = computed(() => ({\n value: props.value,\n format: props.format,\n width: props.width,\n height: props.height,\n displayValue: props.showText,\n fontSize: props.fontSize,\n textPosition: props.textPosition,\n lineColor: props.lineColor,\n background: props.background,\n}));\n\nconst handleError = (error: Error) => {\n console.error(\"条形码生成失败:\", error);\n emit(\"error\", error);\n};\n</script>\n\n<style lang=\"scss\" scoped>\n@use \"./index.scss\";\n</style>\n","/* unplugin-vue-components disabled */<!--\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2025-12-02\n * @Description: 条形码组件\n * @Migration: naive-ui-components 组件库迁移版本\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div class=\"c-barcode\">\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\n </div>\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\n {{ label }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\n\ndefineOptions({ name: \"C_Barcode\" });\n\ninterface Props {\n value: string;\n format?:\n | \"CODE128\"\n | \"CODE39\"\n | \"EAN13\"\n | \"EAN8\"\n | \"UPC\"\n | \"ITF14\"\n | \"MSI\"\n | \"pharmacode\";\n width?: number;\n height?: number;\n showText?: boolean;\n fontSize?: number;\n textPosition?: \"bottom\" | \"top\";\n lineColor?: string;\n background?: string;\n showBorder?: boolean;\n label?: string;\n showLabel?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n format: \"CODE128\",\n width: 2,\n height: 80,\n showText: true,\n fontSize: 20,\n textPosition: \"bottom\",\n lineColor: \"#000000\",\n background: \"#FFFFFF\",\n showBorder: true,\n label: \"\",\n showLabel: false,\n});\n\nconst emit = defineEmits<{\n error: [error: Error];\n}>();\n\nconst barcodeProps = computed(() => ({\n value: props.value,\n format: props.format,\n width: props.width,\n height: props.height,\n displayValue: props.showText,\n fontSize: props.fontSize,\n textPosition: props.textPosition,\n lineColor: props.lineColor,\n background: props.background,\n}));\n\nconst handleError = (error: Error) => {\n console.error(\"条形码生成失败:\", error);\n emit(\"error\", error);\n};\n</script>\n\n<style lang=\"scss\" scoped>\n@use \"./index.scss\";\n</style>\n","<!--\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2025-12-02\n * @Description: 条形码组件\n * @Migration: naive-ui-components 组件库迁移版本\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div class=\"c-barcode\">\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\n </div>\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\n {{ label }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\n\ndefineOptions({ name: \"C_Barcode\" });\n\ninterface Props {\n value: string;\n format?:\n | \"CODE128\"\n | \"CODE39\"\n | \"EAN13\"\n | \"EAN8\"\n | \"UPC\"\n | \"ITF14\"\n | \"MSI\"\n | \"pharmacode\";\n width?: number;\n height?: number;\n showText?: boolean;\n fontSize?: number;\n textPosition?: \"bottom\" | \"top\";\n lineColor?: string;\n background?: string;\n showBorder?: boolean;\n label?: string;\n showLabel?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n format: \"CODE128\",\n width: 2,\n height: 80,\n showText: true,\n fontSize: 20,\n textPosition: \"bottom\",\n lineColor: \"#000000\",\n background: \"#FFFFFF\",\n showBorder: true,\n label: \"\",\n showLabel: false,\n});\n\nconst emit = defineEmits<{\n error: [error: Error];\n}>();\n\nconst barcodeProps = computed(() => ({\n value: props.value,\n format: props.format,\n width: props.width,\n height: props.height,\n displayValue: props.showText,\n fontSize: props.fontSize,\n textPosition: props.textPosition,\n lineColor: props.lineColor,\n background: props.background,\n}));\n\nconst handleError = (error: Error) => {\n console.error(\"条形码生成失败:\", error);\n emit(\"error\", error);\n};\n</script>\n\n<style lang=\"scss\" scoped>\n@use \"./index.scss\";\n</style>\n"],"mappings":"kmBE+CA,IAAM,EAAQ,EAcR,EAAO,EAIP,GAAA,EAAA,EAAA,eAA+B,CACnC,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,aAAc,EAAM,SACpB,SAAU,EAAM,SAChB,aAAc,EAAM,aACpB,UAAW,EAAM,UACjB,WAAY,EAAM,WACnB,EAAE,CAEG,EAAe,GAAiB,CACpC,QAAQ,MAAM,WAAY,EAAM,CAChC,EAAK,QAAS,EAAM,2DAhEd,MAPN,EAOM,EAAA,EAAA,EAAA,oBAJE,MAAA,CAFD,OAAA,EAAA,EAAA,gBAAK,CAAC,kBAAiB,CAAA,cAA0BA,EAAAA,WAAU,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,EAAA,cAAA,EAAA,EAAA,OACL,EAAA,QAAA,EAAA,EAAA,EAAA,YAArC,EAAqC,MAAzB,CAAG,QAAO,EAAW,CAAA,CAAA,KAAA,GAAA,CAAA,CAAA,EAAA,CAE5CC,EAAAA,WAAaC,EAAAA,QAAAA,EAAAA,EAAAA,YAAAA,EAAAA,EAAAA,EAAAA,oBAElB,MAFN,GAAA,EAAA,EAAA,iBACKA,EAAAA,MAAK,CAAA,EAAA,GAAA,EAAA,EAAA,oBAAA,OAAA,GAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"C_Barcode.js","names":["showBorder","showLabel","label"],"sources":["../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2025-12-02\r\n * @Description: 条形码组件\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div class=\"c-barcode\">\r\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\r\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\r\n </div>\r\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\r\n {{ label }}\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from \"vue\";\r\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\r\n\r\ndefineOptions({ name: \"C_Barcode\" });\r\n\r\ninterface Props {\r\n value: string;\r\n format?:\r\n | \"CODE128\"\r\n | \"CODE39\"\r\n | \"EAN13\"\r\n | \"EAN8\"\r\n | \"UPC\"\r\n | \"ITF14\"\r\n | \"MSI\"\r\n | \"pharmacode\";\r\n width?: number;\r\n height?: number;\r\n showText?: boolean;\r\n fontSize?: number;\r\n textPosition?: \"bottom\" | \"top\";\r\n lineColor?: string;\r\n background?: string;\r\n showBorder?: boolean;\r\n label?: string;\r\n showLabel?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n format: \"CODE128\",\r\n width: 2,\r\n height: 80,\r\n showText: true,\r\n fontSize: 20,\r\n textPosition: \"bottom\",\r\n lineColor: \"#000000\",\r\n background: \"#FFFFFF\",\r\n showBorder: true,\r\n label: \"\",\r\n showLabel: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n error: [error: Error];\r\n}>();\r\n\r\nconst barcodeProps = computed(() => ({\r\n value: props.value,\r\n format: props.format,\r\n width: props.width,\r\n height: props.height,\r\n displayValue: props.showText,\r\n fontSize: props.fontSize,\r\n textPosition: props.textPosition,\r\n lineColor: props.lineColor,\r\n background: props.background,\r\n}));\r\n\r\nconst handleError = (error: Error) => {\r\n console.error(\"条形码生成失败:\", error);\r\n emit(\"error\", error);\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n@use \"./index.scss\";\r\n</style>\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2025-12-02\r\n * @Description: 条形码组件\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div class=\"c-barcode\">\r\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\r\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\r\n </div>\r\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\r\n {{ label }}\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from \"vue\";\r\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\r\n\r\ndefineOptions({ name: \"C_Barcode\" });\r\n\r\ninterface Props {\r\n value: string;\r\n format?:\r\n | \"CODE128\"\r\n | \"CODE39\"\r\n | \"EAN13\"\r\n | \"EAN8\"\r\n | \"UPC\"\r\n | \"ITF14\"\r\n | \"MSI\"\r\n | \"pharmacode\";\r\n width?: number;\r\n height?: number;\r\n showText?: boolean;\r\n fontSize?: number;\r\n textPosition?: \"bottom\" | \"top\";\r\n lineColor?: string;\r\n background?: string;\r\n showBorder?: boolean;\r\n label?: string;\r\n showLabel?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n format: \"CODE128\",\r\n width: 2,\r\n height: 80,\r\n showText: true,\r\n fontSize: 20,\r\n textPosition: \"bottom\",\r\n lineColor: \"#000000\",\r\n background: \"#FFFFFF\",\r\n showBorder: true,\r\n label: \"\",\r\n showLabel: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n error: [error: Error];\r\n}>();\r\n\r\nconst barcodeProps = computed(() => ({\r\n value: props.value,\r\n format: props.format,\r\n width: props.width,\r\n height: props.height,\r\n displayValue: props.showText,\r\n fontSize: props.fontSize,\r\n textPosition: props.textPosition,\r\n lineColor: props.lineColor,\r\n background: props.background,\r\n}));\r\n\r\nconst handleError = (error: Error) => {\r\n console.error(\"条形码生成失败:\", error);\r\n emit(\"error\", error);\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n@use \"./index.scss\";\r\n</style>\r\n","<!--\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2025-12-02\r\n * @Description: 条形码组件\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div class=\"c-barcode\">\r\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\r\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\r\n </div>\r\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\r\n {{ label }}\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from \"vue\";\r\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\r\n\r\ndefineOptions({ name: \"C_Barcode\" });\r\n\r\ninterface Props {\r\n value: string;\r\n format?:\r\n | \"CODE128\"\r\n | \"CODE39\"\r\n | \"EAN13\"\r\n | \"EAN8\"\r\n | \"UPC\"\r\n | \"ITF14\"\r\n | \"MSI\"\r\n | \"pharmacode\";\r\n width?: number;\r\n height?: number;\r\n showText?: boolean;\r\n fontSize?: number;\r\n textPosition?: \"bottom\" | \"top\";\r\n lineColor?: string;\r\n background?: string;\r\n showBorder?: boolean;\r\n label?: string;\r\n showLabel?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n format: \"CODE128\",\r\n width: 2,\r\n height: 80,\r\n showText: true,\r\n fontSize: 20,\r\n textPosition: \"bottom\",\r\n lineColor: \"#000000\",\r\n background: \"#FFFFFF\",\r\n showBorder: true,\r\n label: \"\",\r\n showLabel: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n error: [error: Error];\r\n}>();\r\n\r\nconst barcodeProps = computed(() => ({\r\n value: props.value,\r\n format: props.format,\r\n width: props.width,\r\n height: props.height,\r\n displayValue: props.showText,\r\n fontSize: props.fontSize,\r\n textPosition: props.textPosition,\r\n lineColor: props.lineColor,\r\n background: props.background,\r\n}));\r\n\r\nconst handleError = (error: Error) => {\r\n console.error(\"条形码生成失败:\", error);\r\n emit(\"error\", error);\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n@use \"./index.scss\";\r\n</style>\r\n"],"mappings":"kmBE+CA,IAAM,EAAQ,EAcR,EAAO,EAIP,GAAA,EAAA,EAAA,eAA+B,CACnC,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,aAAc,EAAM,SACpB,SAAU,EAAM,SAChB,aAAc,EAAM,aACpB,UAAW,EAAM,UACjB,WAAY,EAAM,WACnB,EAAE,CAEG,EAAe,GAAiB,CACpC,QAAQ,MAAM,WAAY,EAAM,CAChC,EAAK,QAAS,EAAM,2DAhEd,MAPN,EAOM,EAAA,EAAA,EAAA,oBAJE,MAAA,CAFD,OAAA,EAAA,EAAA,gBAAK,CAAC,kBAAiB,CAAA,cAA0BA,EAAAA,WAAU,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,EAAA,cAAA,EAAA,EAAA,OACL,EAAA,QAAA,EAAA,EAAA,EAAA,YAArC,EAAqC,MAAzB,CAAG,QAAO,EAAW,CAAA,CAAA,KAAA,GAAA,CAAA,CAAA,EAAA,CAE5CC,EAAAA,WAAaC,EAAAA,QAAAA,EAAAA,EAAAA,YAAAA,EAAAA,EAAAA,EAAAA,oBAElB,MAFN,GAAA,EAAA,EAAA,iBACKA,EAAAA,MAAK,CAAA,EAAA,GAAA,EAAA,EAAA,oBAAA,OAAA,GAAA,CAAA,CAAA"}
|
package/dist/C_Barcode2.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./export-helper.js";import{computed as t,createCommentVNode as n,createElementBlock as r,createElementVNode as i,createVNode as a,defineComponent as o,mergeProps as s,normalizeClass as c,openBlock as l,toDisplayString as u,unref as d}from"vue";import f from"@chenfengyuan/vue-barcode";const p={class:`c-barcode`},m={key:0,class:`barcode-label`};var h=e(o({name:`C_Barcode`,__name:`index`,props:{value:{},format:{default:`CODE128`},width:{default:2},height:{default:80},showText:{type:Boolean,default:!0},fontSize:{default:20},textPosition:{default:`bottom`},lineColor:{default:`#000000`},background:{default:`#FFFFFF`},showBorder:{type:Boolean,default:!0},label:{default:``},showLabel:{type:Boolean,default:!1}},emits:[`error`],setup(e,{emit:o}){let h=e,g=o,_=t(()=>({value:h.value,format:h.format,width:h.width,height:h.height,displayValue:h.showText,fontSize:h.fontSize,textPosition:h.textPosition,lineColor:h.lineColor,background:h.background})),v=e=>{console.error(`条形码生成失败:`,e),g(`error`,e)};return(e,t)=>(l(),r(`div`,p,[i(`div`,{class:c([`barcode-wrapper`,{"with-border":e.showBorder}])},[a(d(f),s(_.value,{onError:v}),null,16)],2),e.showLabel&&e.label?(l(),r(`div`,m,u(e.label),1)):n(`v-if`,!0)]))}}),[[`__scopeId`,`data-v-
|
|
1
|
+
import{t as e}from"./export-helper.js";import{computed as t,createCommentVNode as n,createElementBlock as r,createElementVNode as i,createVNode as a,defineComponent as o,mergeProps as s,normalizeClass as c,openBlock as l,toDisplayString as u,unref as d}from"vue";import f from"@chenfengyuan/vue-barcode";const p={class:`c-barcode`},m={key:0,class:`barcode-label`};var h=e(o({name:`C_Barcode`,__name:`index`,props:{value:{},format:{default:`CODE128`},width:{default:2},height:{default:80},showText:{type:Boolean,default:!0},fontSize:{default:20},textPosition:{default:`bottom`},lineColor:{default:`#000000`},background:{default:`#FFFFFF`},showBorder:{type:Boolean,default:!0},label:{default:``},showLabel:{type:Boolean,default:!1}},emits:[`error`],setup(e,{emit:o}){let h=e,g=o,_=t(()=>({value:h.value,format:h.format,width:h.width,height:h.height,displayValue:h.showText,fontSize:h.fontSize,textPosition:h.textPosition,lineColor:h.lineColor,background:h.background})),v=e=>{console.error(`条形码生成失败:`,e),g(`error`,e)};return(e,t)=>(l(),r(`div`,p,[i(`div`,{class:c([`barcode-wrapper`,{"with-border":e.showBorder}])},[a(d(f),s(_.value,{onError:v}),null,16)],2),e.showLabel&&e.label?(l(),r(`div`,m,u(e.label),1)):n(`v-if`,!0)]))}}),[[`__scopeId`,`data-v-e44c361d`]]);export{h as t};
|
|
2
2
|
//# sourceMappingURL=C_Barcode2.js.map
|
package/dist/C_Barcode2.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Barcode2.js","names":["showBorder","showLabel","label"],"sources":["../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2025-12-02\n * @Description: 条形码组件\n * @Migration: naive-ui-components 组件库迁移版本\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div class=\"c-barcode\">\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\n </div>\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\n {{ label }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\n\ndefineOptions({ name: \"C_Barcode\" });\n\ninterface Props {\n value: string;\n format?:\n | \"CODE128\"\n | \"CODE39\"\n | \"EAN13\"\n | \"EAN8\"\n | \"UPC\"\n | \"ITF14\"\n | \"MSI\"\n | \"pharmacode\";\n width?: number;\n height?: number;\n showText?: boolean;\n fontSize?: number;\n textPosition?: \"bottom\" | \"top\";\n lineColor?: string;\n background?: string;\n showBorder?: boolean;\n label?: string;\n showLabel?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n format: \"CODE128\",\n width: 2,\n height: 80,\n showText: true,\n fontSize: 20,\n textPosition: \"bottom\",\n lineColor: \"#000000\",\n background: \"#FFFFFF\",\n showBorder: true,\n label: \"\",\n showLabel: false,\n});\n\nconst emit = defineEmits<{\n error: [error: Error];\n}>();\n\nconst barcodeProps = computed(() => ({\n value: props.value,\n format: props.format,\n width: props.width,\n height: props.height,\n displayValue: props.showText,\n fontSize: props.fontSize,\n textPosition: props.textPosition,\n lineColor: props.lineColor,\n background: props.background,\n}));\n\nconst handleError = (error: Error) => {\n console.error(\"条形码生成失败:\", error);\n emit(\"error\", error);\n};\n</script>\n\n<style lang=\"scss\" scoped>\n@use \"./index.scss\";\n</style>\n","/* unplugin-vue-components disabled */<!--\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2025-12-02\n * @Description: 条形码组件\n * @Migration: naive-ui-components 组件库迁移版本\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div class=\"c-barcode\">\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\n </div>\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\n {{ label }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\n\ndefineOptions({ name: \"C_Barcode\" });\n\ninterface Props {\n value: string;\n format?:\n | \"CODE128\"\n | \"CODE39\"\n | \"EAN13\"\n | \"EAN8\"\n | \"UPC\"\n | \"ITF14\"\n | \"MSI\"\n | \"pharmacode\";\n width?: number;\n height?: number;\n showText?: boolean;\n fontSize?: number;\n textPosition?: \"bottom\" | \"top\";\n lineColor?: string;\n background?: string;\n showBorder?: boolean;\n label?: string;\n showLabel?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n format: \"CODE128\",\n width: 2,\n height: 80,\n showText: true,\n fontSize: 20,\n textPosition: \"bottom\",\n lineColor: \"#000000\",\n background: \"#FFFFFF\",\n showBorder: true,\n label: \"\",\n showLabel: false,\n});\n\nconst emit = defineEmits<{\n error: [error: Error];\n}>();\n\nconst barcodeProps = computed(() => ({\n value: props.value,\n format: props.format,\n width: props.width,\n height: props.height,\n displayValue: props.showText,\n fontSize: props.fontSize,\n textPosition: props.textPosition,\n lineColor: props.lineColor,\n background: props.background,\n}));\n\nconst handleError = (error: Error) => {\n console.error(\"条形码生成失败:\", error);\n emit(\"error\", error);\n};\n</script>\n\n<style lang=\"scss\" scoped>\n@use \"./index.scss\";\n</style>\n","<!--\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2025-12-02\n * @Description: 条形码组件\n * @Migration: naive-ui-components 组件库迁移版本\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div class=\"c-barcode\">\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\n </div>\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\n {{ label }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\n\ndefineOptions({ name: \"C_Barcode\" });\n\ninterface Props {\n value: string;\n format?:\n | \"CODE128\"\n | \"CODE39\"\n | \"EAN13\"\n | \"EAN8\"\n | \"UPC\"\n | \"ITF14\"\n | \"MSI\"\n | \"pharmacode\";\n width?: number;\n height?: number;\n showText?: boolean;\n fontSize?: number;\n textPosition?: \"bottom\" | \"top\";\n lineColor?: string;\n background?: string;\n showBorder?: boolean;\n label?: string;\n showLabel?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n format: \"CODE128\",\n width: 2,\n height: 80,\n showText: true,\n fontSize: 20,\n textPosition: \"bottom\",\n lineColor: \"#000000\",\n background: \"#FFFFFF\",\n showBorder: true,\n label: \"\",\n showLabel: false,\n});\n\nconst emit = defineEmits<{\n error: [error: Error];\n}>();\n\nconst barcodeProps = computed(() => ({\n value: props.value,\n format: props.format,\n width: props.width,\n height: props.height,\n displayValue: props.showText,\n fontSize: props.fontSize,\n textPosition: props.textPosition,\n lineColor: props.lineColor,\n background: props.background,\n}));\n\nconst handleError = (error: Error) => {\n console.error(\"条形码生成失败:\", error);\n emit(\"error\", error);\n};\n</script>\n\n<style lang=\"scss\" scoped>\n@use \"./index.scss\";\n</style>\n"],"mappings":"6vBE+CA,IAAM,EAAQ,EAcR,EAAO,EAIP,EAAe,OAAgB,CACnC,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,aAAc,EAAM,SACpB,SAAU,EAAM,SAChB,aAAc,EAAM,aACpB,UAAW,EAAM,UACjB,WAAY,EAAM,WACnB,EAAE,CAEG,EAAe,GAAiB,CACpC,QAAQ,MAAM,WAAY,EAAM,CAChC,EAAK,QAAS,EAAM,oBAvEpB,EAOM,MAPN,EAOM,CANJ,EAEM,MAAA,CAFD,MAAK,EAAA,CAAC,kBAAiB,CAAA,cAA0BA,EAAAA,WAAU,CAAA,CAAA,CAAA,CAAA,CAC9D,EAAyD,EAAA,EAAA,CAAzD,EAAoB,EAAqC,MAAzB,CAAG,QAAO,EAAW,CAAA,CAAA,KAAA,GAAA,CAAA,CAAA,EAAA,CAE5CC,EAAAA,WAAaC,EAAAA,OAAAA,GAAAA,CAAxB,EAEM,MAFN,EAEM,EADDA,EAAAA,MAAK,CAAA,EAAA,EAAA,EAAA,OAAA,GAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"C_Barcode2.js","names":["showBorder","showLabel","label"],"sources":["../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue","../src/components/C_Barcode/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2025-12-02\r\n * @Description: 条形码组件\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div class=\"c-barcode\">\r\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\r\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\r\n </div>\r\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\r\n {{ label }}\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from \"vue\";\r\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\r\n\r\ndefineOptions({ name: \"C_Barcode\" });\r\n\r\ninterface Props {\r\n value: string;\r\n format?:\r\n | \"CODE128\"\r\n | \"CODE39\"\r\n | \"EAN13\"\r\n | \"EAN8\"\r\n | \"UPC\"\r\n | \"ITF14\"\r\n | \"MSI\"\r\n | \"pharmacode\";\r\n width?: number;\r\n height?: number;\r\n showText?: boolean;\r\n fontSize?: number;\r\n textPosition?: \"bottom\" | \"top\";\r\n lineColor?: string;\r\n background?: string;\r\n showBorder?: boolean;\r\n label?: string;\r\n showLabel?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n format: \"CODE128\",\r\n width: 2,\r\n height: 80,\r\n showText: true,\r\n fontSize: 20,\r\n textPosition: \"bottom\",\r\n lineColor: \"#000000\",\r\n background: \"#FFFFFF\",\r\n showBorder: true,\r\n label: \"\",\r\n showLabel: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n error: [error: Error];\r\n}>();\r\n\r\nconst barcodeProps = computed(() => ({\r\n value: props.value,\r\n format: props.format,\r\n width: props.width,\r\n height: props.height,\r\n displayValue: props.showText,\r\n fontSize: props.fontSize,\r\n textPosition: props.textPosition,\r\n lineColor: props.lineColor,\r\n background: props.background,\r\n}));\r\n\r\nconst handleError = (error: Error) => {\r\n console.error(\"条形码生成失败:\", error);\r\n emit(\"error\", error);\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n@use \"./index.scss\";\r\n</style>\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2025-12-02\r\n * @Description: 条形码组件\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div class=\"c-barcode\">\r\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\r\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\r\n </div>\r\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\r\n {{ label }}\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from \"vue\";\r\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\r\n\r\ndefineOptions({ name: \"C_Barcode\" });\r\n\r\ninterface Props {\r\n value: string;\r\n format?:\r\n | \"CODE128\"\r\n | \"CODE39\"\r\n | \"EAN13\"\r\n | \"EAN8\"\r\n | \"UPC\"\r\n | \"ITF14\"\r\n | \"MSI\"\r\n | \"pharmacode\";\r\n width?: number;\r\n height?: number;\r\n showText?: boolean;\r\n fontSize?: number;\r\n textPosition?: \"bottom\" | \"top\";\r\n lineColor?: string;\r\n background?: string;\r\n showBorder?: boolean;\r\n label?: string;\r\n showLabel?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n format: \"CODE128\",\r\n width: 2,\r\n height: 80,\r\n showText: true,\r\n fontSize: 20,\r\n textPosition: \"bottom\",\r\n lineColor: \"#000000\",\r\n background: \"#FFFFFF\",\r\n showBorder: true,\r\n label: \"\",\r\n showLabel: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n error: [error: Error];\r\n}>();\r\n\r\nconst barcodeProps = computed(() => ({\r\n value: props.value,\r\n format: props.format,\r\n width: props.width,\r\n height: props.height,\r\n displayValue: props.showText,\r\n fontSize: props.fontSize,\r\n textPosition: props.textPosition,\r\n lineColor: props.lineColor,\r\n background: props.background,\r\n}));\r\n\r\nconst handleError = (error: Error) => {\r\n console.error(\"条形码生成失败:\", error);\r\n emit(\"error\", error);\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n@use \"./index.scss\";\r\n</style>\r\n","<!--\r\n * @Author: ChenYu ycyplus@gmail.com\r\n * @Date: 2025-12-02\r\n * @Description: 条形码组件\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div class=\"c-barcode\">\r\n <div class=\"barcode-wrapper\" :class=\"{ 'with-border': showBorder }\">\r\n <VueBarcode v-bind=\"barcodeProps\" @error=\"handleError\" />\r\n </div>\r\n <div v-if=\"showLabel && label\" class=\"barcode-label\">\r\n {{ label }}\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from \"vue\";\r\nimport VueBarcode from \"@chenfengyuan/vue-barcode\";\r\n\r\ndefineOptions({ name: \"C_Barcode\" });\r\n\r\ninterface Props {\r\n value: string;\r\n format?:\r\n | \"CODE128\"\r\n | \"CODE39\"\r\n | \"EAN13\"\r\n | \"EAN8\"\r\n | \"UPC\"\r\n | \"ITF14\"\r\n | \"MSI\"\r\n | \"pharmacode\";\r\n width?: number;\r\n height?: number;\r\n showText?: boolean;\r\n fontSize?: number;\r\n textPosition?: \"bottom\" | \"top\";\r\n lineColor?: string;\r\n background?: string;\r\n showBorder?: boolean;\r\n label?: string;\r\n showLabel?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n format: \"CODE128\",\r\n width: 2,\r\n height: 80,\r\n showText: true,\r\n fontSize: 20,\r\n textPosition: \"bottom\",\r\n lineColor: \"#000000\",\r\n background: \"#FFFFFF\",\r\n showBorder: true,\r\n label: \"\",\r\n showLabel: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n error: [error: Error];\r\n}>();\r\n\r\nconst barcodeProps = computed(() => ({\r\n value: props.value,\r\n format: props.format,\r\n width: props.width,\r\n height: props.height,\r\n displayValue: props.showText,\r\n fontSize: props.fontSize,\r\n textPosition: props.textPosition,\r\n lineColor: props.lineColor,\r\n background: props.background,\r\n}));\r\n\r\nconst handleError = (error: Error) => {\r\n console.error(\"条形码生成失败:\", error);\r\n emit(\"error\", error);\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n@use \"./index.scss\";\r\n</style>\r\n"],"mappings":"6vBE+CA,IAAM,EAAQ,EAcR,EAAO,EAIP,EAAe,OAAgB,CACnC,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,aAAc,EAAM,SACpB,SAAU,EAAM,SAChB,aAAc,EAAM,aACpB,UAAW,EAAM,UACjB,WAAY,EAAM,WACnB,EAAE,CAEG,EAAe,GAAiB,CACpC,QAAQ,MAAM,WAAY,EAAM,CAChC,EAAK,QAAS,EAAM,oBAvEpB,EAOM,MAPN,EAOM,CANJ,EAEM,MAAA,CAFD,MAAK,EAAA,CAAC,kBAAiB,CAAA,cAA0BA,EAAAA,WAAU,CAAA,CAAA,CAAA,CAAA,CAC9D,EAAyD,EAAA,EAAA,CAAzD,EAAoB,EAAqC,MAAzB,CAAG,QAAO,EAAW,CAAA,CAAA,KAAA,GAAA,CAAA,CAAA,EAAA,CAE5CC,EAAAA,WAAaC,EAAAA,OAAAA,GAAAA,CAAxB,EAEM,MAFN,EAEM,EADDA,EAAAA,MAAK,CAAA,EAAA,EAAA,EAAA,OAAA,GAAA,CAAA,CAAA"}
|
package/dist/C_Breadcrumb.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Breadcrumb.js","names":["iconSize","showIcon"],"sources":["../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\n *\n * 支持两种模式:\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\n * 2. 手动模式 — 传入 `items` 完全自定义\n *\n * @example 自动模式(零配置)\n * ```vue\n * <C_Breadcrumb\n * :label-formatter=\"$t\"\n * @select=\"router.push\"\n * />\n * ```\n *\n * @example 手动模式\n * ```vue\n * <C_Breadcrumb\n * :items=\"customBreadcrumbs\"\n * @select=\"handleSelect\"\n * />\n * ```\n *\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div\n class=\"c-breadcrumb flex-1 min-w-0\"\n :style=\"{\n '--c-breadcrumb-icon-size': `${iconSize}px`,\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\n }\"\n >\n <NBreadcrumb>\n <NBreadcrumbItem\n v-for=\"(item, index) in breadcrumbItems\"\n :key=\"index\"\n >\n <NDropdown\n v-if=\"item.children?.length\"\n :options=\"item.children\"\n @select=\"handleSelect\"\n >\n <div class=\"c-breadcrumb__trigger\">\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </div>\n </NDropdown>\n <span\n v-else\n class=\"c-breadcrumb__link\"\n @click=\"handleSelect(item.key)\"\n >\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </span>\n </NBreadcrumbItem>\n </NBreadcrumb>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useRoute } from 'vue-router'\n import { C_Icon } from '../C_Icon'\n import type { BreadcrumbItem } from '../_shared'\n\n defineOptions({ name: 'C_Breadcrumb' })\n\n const props = withDefaults(\n defineProps<{\n /**\n * 手动传入面包屑数据\n * 不传时自动从 `route.matched` 生成(零配置)\n */\n items?: BreadcrumbItem[]\n /** 是否显示图标 */\n showIcon?: boolean\n /** 图标大小 (px),默认 16 */\n iconSize?: number\n /**\n * 标签文本格式化函数(用于 i18n)\n * 仅在自动模式下生效\n */\n labelFormatter?: (label: string) => string\n }>(),\n {\n showIcon: true,\n iconSize: 16,\n }\n )\n\n const emit = defineEmits<{\n /** 面包屑项被选中(返回路径 key) */\n select: [path: string]\n }>()\n\n const route = useRoute()\n\n const formatLabel = (title: string): string =>\n props.labelFormatter ? props.labelFormatter(title) : title\n\n /** 从 route.matched 自动生成面包屑 */\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\n return route.matched\n .filter((record: any) => record.meta?.title)\n .map((record: any) => ({\n key: record.path,\n label: formatLabel((record.meta.title || '') as string),\n icon: record.meta.icon as string | undefined,\n children: record.children?.length\n ? record.children.map((child: any) => ({\n key: child.path,\n label: formatLabel((child.meta?.title || '') as string),\n ...(child.children?.length && {\n children: child.children.map((grandChild: any) => ({\n key: grandChild.path,\n label: formatLabel((grandChild.meta?.title || '') as string),\n })),\n }),\n }))\n : [],\n }))\n })\n\n const breadcrumbItems = computed<BreadcrumbItem[]>(\n () => props.items ?? autoBreadcrumb.value\n )\n\n const handleSelect = (key: string) => {\n emit('select', key)\n }\n</script>\n\n<style lang=\"scss\">\n .c-breadcrumb {\n // 暴露 CSS 变量,方便主项目覆盖\n --c-breadcrumb-icon-size: 16px;\n --c-breadcrumb-gap: 4px;\n --c-breadcrumb-font-size: inherit;\n\n display: flex;\n align-items: center;\n height: 100%;\n\n &__trigger,\n &__link {\n display: inline-flex;\n align-items: center;\n gap: var(--c-breadcrumb-gap);\n font-size: var(--c-breadcrumb-font-size);\n line-height: 1;\n cursor: pointer;\n }\n\n // 确保 C_Icon 在面包屑中尺寸一致\n .c-icon {\n flex-shrink: 0;\n }\n\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\n .n-breadcrumb-item {\n display: inline-flex !important;\n align-items: center;\n\n .n-breadcrumb-item__separator {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n margin-top: -4px;\n }\n }\n }\n</style>\n","/* unplugin-vue-components disabled */<!--\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\n *\n * 支持两种模式:\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\n * 2. 手动模式 — 传入 `items` 完全自定义\n *\n * @example 自动模式(零配置)\n * ```vue\n * <C_Breadcrumb\n * :label-formatter=\"$t\"\n * @select=\"router.push\"\n * />\n * ```\n *\n * @example 手动模式\n * ```vue\n * <C_Breadcrumb\n * :items=\"customBreadcrumbs\"\n * @select=\"handleSelect\"\n * />\n * ```\n *\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div\n class=\"c-breadcrumb flex-1 min-w-0\"\n :style=\"{\n '--c-breadcrumb-icon-size': `${iconSize}px`,\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\n }\"\n >\n <NBreadcrumb>\n <NBreadcrumbItem\n v-for=\"(item, index) in breadcrumbItems\"\n :key=\"index\"\n >\n <NDropdown\n v-if=\"item.children?.length\"\n :options=\"item.children\"\n @select=\"handleSelect\"\n >\n <div class=\"c-breadcrumb__trigger\">\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </div>\n </NDropdown>\n <span\n v-else\n class=\"c-breadcrumb__link\"\n @click=\"handleSelect(item.key)\"\n >\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </span>\n </NBreadcrumbItem>\n </NBreadcrumb>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useRoute } from 'vue-router'\n import { C_Icon } from '../C_Icon'\n import type { BreadcrumbItem } from '../_shared'\n\n defineOptions({ name: 'C_Breadcrumb' })\n\n const props = withDefaults(\n defineProps<{\n /**\n * 手动传入面包屑数据\n * 不传时自动从 `route.matched` 生成(零配置)\n */\n items?: BreadcrumbItem[]\n /** 是否显示图标 */\n showIcon?: boolean\n /** 图标大小 (px),默认 16 */\n iconSize?: number\n /**\n * 标签文本格式化函数(用于 i18n)\n * 仅在自动模式下生效\n */\n labelFormatter?: (label: string) => string\n }>(),\n {\n showIcon: true,\n iconSize: 16,\n }\n )\n\n const emit = defineEmits<{\n /** 面包屑项被选中(返回路径 key) */\n select: [path: string]\n }>()\n\n const route = useRoute()\n\n const formatLabel = (title: string): string =>\n props.labelFormatter ? props.labelFormatter(title) : title\n\n /** 从 route.matched 自动生成面包屑 */\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\n return route.matched\n .filter((record: any) => record.meta?.title)\n .map((record: any) => ({\n key: record.path,\n label: formatLabel((record.meta.title || '') as string),\n icon: record.meta.icon as string | undefined,\n children: record.children?.length\n ? record.children.map((child: any) => ({\n key: child.path,\n label: formatLabel((child.meta?.title || '') as string),\n ...(child.children?.length && {\n children: child.children.map((grandChild: any) => ({\n key: grandChild.path,\n label: formatLabel((grandChild.meta?.title || '') as string),\n })),\n }),\n }))\n : [],\n }))\n })\n\n const breadcrumbItems = computed<BreadcrumbItem[]>(\n () => props.items ?? autoBreadcrumb.value\n )\n\n const handleSelect = (key: string) => {\n emit('select', key)\n }\n</script>\n\n<style lang=\"scss\">\n .c-breadcrumb {\n // 暴露 CSS 变量,方便主项目覆盖\n --c-breadcrumb-icon-size: 16px;\n --c-breadcrumb-gap: 4px;\n --c-breadcrumb-font-size: inherit;\n\n display: flex;\n align-items: center;\n height: 100%;\n\n &__trigger,\n &__link {\n display: inline-flex;\n align-items: center;\n gap: var(--c-breadcrumb-gap);\n font-size: var(--c-breadcrumb-font-size);\n line-height: 1;\n cursor: pointer;\n }\n\n // 确保 C_Icon 在面包屑中尺寸一致\n .c-icon {\n flex-shrink: 0;\n }\n\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\n .n-breadcrumb-item {\n display: inline-flex !important;\n align-items: center;\n\n .n-breadcrumb-item__separator {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n margin-top: -4px;\n }\n }\n }\n</style>\n","<!--\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\n *\n * 支持两种模式:\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\n * 2. 手动模式 — 传入 `items` 完全自定义\n *\n * @example 自动模式(零配置)\n * ```vue\n * <C_Breadcrumb\n * :label-formatter=\"$t\"\n * @select=\"router.push\"\n * />\n * ```\n *\n * @example 手动模式\n * ```vue\n * <C_Breadcrumb\n * :items=\"customBreadcrumbs\"\n * @select=\"handleSelect\"\n * />\n * ```\n *\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div\n class=\"c-breadcrumb flex-1 min-w-0\"\n :style=\"{\n '--c-breadcrumb-icon-size': `${iconSize}px`,\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\n }\"\n >\n <NBreadcrumb>\n <NBreadcrumbItem\n v-for=\"(item, index) in breadcrumbItems\"\n :key=\"index\"\n >\n <NDropdown\n v-if=\"item.children?.length\"\n :options=\"item.children\"\n @select=\"handleSelect\"\n >\n <div class=\"c-breadcrumb__trigger\">\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </div>\n </NDropdown>\n <span\n v-else\n class=\"c-breadcrumb__link\"\n @click=\"handleSelect(item.key)\"\n >\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </span>\n </NBreadcrumbItem>\n </NBreadcrumb>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useRoute } from 'vue-router'\n import { C_Icon } from '../C_Icon'\n import type { BreadcrumbItem } from '../_shared'\n\n defineOptions({ name: 'C_Breadcrumb' })\n\n const props = withDefaults(\n defineProps<{\n /**\n * 手动传入面包屑数据\n * 不传时自动从 `route.matched` 生成(零配置)\n */\n items?: BreadcrumbItem[]\n /** 是否显示图标 */\n showIcon?: boolean\n /** 图标大小 (px),默认 16 */\n iconSize?: number\n /**\n * 标签文本格式化函数(用于 i18n)\n * 仅在自动模式下生效\n */\n labelFormatter?: (label: string) => string\n }>(),\n {\n showIcon: true,\n iconSize: 16,\n }\n )\n\n const emit = defineEmits<{\n /** 面包屑项被选中(返回路径 key) */\n select: [path: string]\n }>()\n\n const route = useRoute()\n\n const formatLabel = (title: string): string =>\n props.labelFormatter ? props.labelFormatter(title) : title\n\n /** 从 route.matched 自动生成面包屑 */\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\n return route.matched\n .filter((record: any) => record.meta?.title)\n .map((record: any) => ({\n key: record.path,\n label: formatLabel((record.meta.title || '') as string),\n icon: record.meta.icon as string | undefined,\n children: record.children?.length\n ? record.children.map((child: any) => ({\n key: child.path,\n label: formatLabel((child.meta?.title || '') as string),\n ...(child.children?.length && {\n children: child.children.map((grandChild: any) => ({\n key: grandChild.path,\n label: formatLabel((grandChild.meta?.title || '') as string),\n })),\n }),\n }))\n : [],\n }))\n })\n\n const breadcrumbItems = computed<BreadcrumbItem[]>(\n () => props.items ?? autoBreadcrumb.value\n )\n\n const handleSelect = (key: string) => {\n emit('select', key)\n }\n</script>\n\n<style lang=\"scss\">\n .c-breadcrumb {\n // 暴露 CSS 变量,方便主项目覆盖\n --c-breadcrumb-icon-size: 16px;\n --c-breadcrumb-gap: 4px;\n --c-breadcrumb-font-size: inherit;\n\n display: flex;\n align-items: center;\n height: 100%;\n\n &__trigger,\n &__link {\n display: inline-flex;\n align-items: center;\n gap: var(--c-breadcrumb-gap);\n font-size: var(--c-breadcrumb-font-size);\n line-height: 1;\n cursor: pointer;\n }\n\n // 确保 C_Icon 在面包屑中尺寸一致\n .c-icon {\n flex-shrink: 0;\n }\n\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\n .n-breadcrumb-item {\n display: inline-flex !important;\n align-items: center;\n\n .n-breadcrumb-item__separator {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n margin-top: -4px;\n }\n }\n }\n</style>\n"],"mappings":"6WE6EE,IAAM,EAAQ,EAuBR,EAAO,EAKP,GAAA,EAAA,EAAA,WAAiB,CAEjB,EAAe,GACnB,EAAM,eAAiB,EAAM,eAAe,EAAM,CAAG,EAGjD,GAAA,EAAA,EAAA,cACG,EAAM,QACV,OAAQ,GAAgB,EAAO,MAAM,MAAK,CAC1C,IAAK,IAAiB,CACrB,IAAK,EAAO,KACZ,MAAO,EAAa,EAAO,KAAK,OAAS,GAAc,CACvD,KAAM,EAAO,KAAK,KAClB,SAAU,EAAO,UAAU,OACvB,EAAO,SAAS,IAAK,IAAgB,CACnC,IAAK,EAAM,KACX,MAAO,EAAa,EAAM,MAAM,OAAS,GAAc,CACvD,GAAI,EAAM,UAAU,QAAU,CAC5B,SAAU,EAAM,SAAS,IAAK,IAAqB,CACjD,IAAK,EAAW,KAChB,MAAO,EAAa,EAAW,MAAM,OAAS,GAAc,CAC7D,EAAE,CACJ,CACF,EAAC,CACF,EAAE,CACP,EAAC,CACL,CAEK,GAAA,EAAA,EAAA,cACE,EAAM,OAAS,EAAe,MACtC,CAEM,EAAgB,GAAgB,CACpC,EAAK,SAAU,EAAG,uHAxEd,MAAA,CAvCJ,MAAM,8BACL,OAAA,EAAA,EAAA,gBAAK,+BAAyCA,EAAAA,SAAQ,4BAAqC,KAAK,IAAI,KAAK,MAAMA,EAAAA,SAAQ,EAAA,CAAA,EAAA,CAAA,0BAqC1G,EAAA,KAAA,2BA9B8B,GAAA,EAAA,EAAA,WAAA,GAAA,EAAA,EAAA,EAAA,oBA6BxB,EAAA,SAAA,MAAA,EAAA,EAAA,YA7BQ,EAAA,OAAhB,EAAM,yCA6BE,EAAA,CA5Bf,IAAK,EAAK,CAAA,2BAkBb,CAfU,EAAK,UAAU,SAAA,EAAA,EAAA,YAAA,EAAA,EAAA,EAAA,aAYX,EAAA,OAXT,QAAS,EAAK,SACd,SAAQ,8BASH,EAAA,EAAA,EAAA,oBAAA,MAPN,EAOM,CALIC,EAAAA,WAAAA,EAAAA,EAAAA,YAAAA,EAAAA,EAAAA,EAAAA,cAAAA,EAAAA,EAAAA,OAGN,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,6FACP,KAAA,EAAA,EAAA,iBACC,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,qEAcV,OAAA,OATL,MAAM,qBACL,QAAK,GAAE,EAAa,EAAK,IAAG,GAGrBC,EAAAA,WAAAA,EAAAA,EAAAA,YAAAA,EAAAA,EAAAA,EAAAA,cAAAA,EAAAA,EAAAA,OAGN,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,6FACP,KAAA,EAAA,EAAA,iBACC,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"C_Breadcrumb.js","names":["iconSize","showIcon"],"sources":["../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\r\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\r\n *\r\n * 支持两种模式:\r\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\r\n * 2. 手动模式 — 传入 `items` 完全自定义\r\n *\r\n * @example 自动模式(零配置)\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :label-formatter=\"$t\"\r\n * @select=\"router.push\"\r\n * />\r\n * ```\r\n *\r\n * @example 手动模式\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :items=\"customBreadcrumbs\"\r\n * @select=\"handleSelect\"\r\n * />\r\n * ```\r\n *\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-breadcrumb flex-1 min-w-0\"\r\n :style=\"{\r\n '--c-breadcrumb-icon-size': `${iconSize}px`,\r\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\r\n }\"\r\n >\r\n <NBreadcrumb>\r\n <NBreadcrumbItem\r\n v-for=\"(item, index) in breadcrumbItems\"\r\n :key=\"index\"\r\n >\r\n <NDropdown\r\n v-if=\"item.children?.length\"\r\n :options=\"item.children\"\r\n @select=\"handleSelect\"\r\n >\r\n <div class=\"c-breadcrumb__trigger\">\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </div>\r\n </NDropdown>\r\n <span\r\n v-else\r\n class=\"c-breadcrumb__link\"\r\n @click=\"handleSelect(item.key)\"\r\n >\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n </NBreadcrumbItem>\r\n </NBreadcrumb>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import { useRoute } from 'vue-router'\r\n import { C_Icon } from '../C_Icon'\r\n import type { BreadcrumbItem } from '../_shared'\r\n\r\n defineOptions({ name: 'C_Breadcrumb' })\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n /**\r\n * 手动传入面包屑数据\r\n * 不传时自动从 `route.matched` 生成(零配置)\r\n */\r\n items?: BreadcrumbItem[]\r\n /** 是否显示图标 */\r\n showIcon?: boolean\r\n /** 图标大小 (px),默认 16 */\r\n iconSize?: number\r\n /**\r\n * 标签文本格式化函数(用于 i18n)\r\n * 仅在自动模式下生效\r\n */\r\n labelFormatter?: (label: string) => string\r\n }>(),\r\n {\r\n showIcon: true,\r\n iconSize: 16,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n /** 面包屑项被选中(返回路径 key) */\r\n select: [path: string]\r\n }>()\r\n\r\n const route = useRoute()\r\n\r\n const formatLabel = (title: string): string =>\r\n props.labelFormatter ? props.labelFormatter(title) : title\r\n\r\n /** 从 route.matched 自动生成面包屑 */\r\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\r\n return route.matched\r\n .filter((record: any) => record.meta?.title)\r\n .map((record: any) => ({\r\n key: record.path,\r\n label: formatLabel((record.meta.title || '') as string),\r\n icon: record.meta.icon as string | undefined,\r\n children: record.children?.length\r\n ? record.children.map((child: any) => ({\r\n key: child.path,\r\n label: formatLabel((child.meta?.title || '') as string),\r\n ...(child.children?.length && {\r\n children: child.children.map((grandChild: any) => ({\r\n key: grandChild.path,\r\n label: formatLabel((grandChild.meta?.title || '') as string),\r\n })),\r\n }),\r\n }))\r\n : [],\r\n }))\r\n })\r\n\r\n const breadcrumbItems = computed<BreadcrumbItem[]>(\r\n () => props.items ?? autoBreadcrumb.value\r\n )\r\n\r\n const handleSelect = (key: string) => {\r\n emit('select', key)\r\n }\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n .c-breadcrumb {\r\n // 暴露 CSS 变量,方便主项目覆盖\r\n --c-breadcrumb-icon-size: 16px;\r\n --c-breadcrumb-gap: 4px;\r\n --c-breadcrumb-font-size: inherit;\r\n\r\n display: flex;\r\n align-items: center;\r\n height: 100%;\r\n\r\n &__trigger,\r\n &__link {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--c-breadcrumb-gap);\r\n font-size: var(--c-breadcrumb-font-size);\r\n line-height: 1;\r\n cursor: pointer;\r\n }\r\n\r\n // 确保 C_Icon 在面包屑中尺寸一致\r\n .c-icon {\r\n flex-shrink: 0;\r\n }\r\n\r\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\r\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\r\n .n-breadcrumb-item {\r\n display: inline-flex !important;\r\n align-items: center;\r\n\r\n .n-breadcrumb-item__separator {\r\n display: inline-flex;\r\n align-items: center;\r\n line-height: 1;\r\n margin-top: -4px;\r\n }\r\n }\r\n }\r\n</style>\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\r\n *\r\n * 支持两种模式:\r\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\r\n * 2. 手动模式 — 传入 `items` 完全自定义\r\n *\r\n * @example 自动模式(零配置)\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :label-formatter=\"$t\"\r\n * @select=\"router.push\"\r\n * />\r\n * ```\r\n *\r\n * @example 手动模式\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :items=\"customBreadcrumbs\"\r\n * @select=\"handleSelect\"\r\n * />\r\n * ```\r\n *\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-breadcrumb flex-1 min-w-0\"\r\n :style=\"{\r\n '--c-breadcrumb-icon-size': `${iconSize}px`,\r\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\r\n }\"\r\n >\r\n <NBreadcrumb>\r\n <NBreadcrumbItem\r\n v-for=\"(item, index) in breadcrumbItems\"\r\n :key=\"index\"\r\n >\r\n <NDropdown\r\n v-if=\"item.children?.length\"\r\n :options=\"item.children\"\r\n @select=\"handleSelect\"\r\n >\r\n <div class=\"c-breadcrumb__trigger\">\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </div>\r\n </NDropdown>\r\n <span\r\n v-else\r\n class=\"c-breadcrumb__link\"\r\n @click=\"handleSelect(item.key)\"\r\n >\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n </NBreadcrumbItem>\r\n </NBreadcrumb>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import { useRoute } from 'vue-router'\r\n import { C_Icon } from '../C_Icon'\r\n import type { BreadcrumbItem } from '../_shared'\r\n\r\n defineOptions({ name: 'C_Breadcrumb' })\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n /**\r\n * 手动传入面包屑数据\r\n * 不传时自动从 `route.matched` 生成(零配置)\r\n */\r\n items?: BreadcrumbItem[]\r\n /** 是否显示图标 */\r\n showIcon?: boolean\r\n /** 图标大小 (px),默认 16 */\r\n iconSize?: number\r\n /**\r\n * 标签文本格式化函数(用于 i18n)\r\n * 仅在自动模式下生效\r\n */\r\n labelFormatter?: (label: string) => string\r\n }>(),\r\n {\r\n showIcon: true,\r\n iconSize: 16,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n /** 面包屑项被选中(返回路径 key) */\r\n select: [path: string]\r\n }>()\r\n\r\n const route = useRoute()\r\n\r\n const formatLabel = (title: string): string =>\r\n props.labelFormatter ? props.labelFormatter(title) : title\r\n\r\n /** 从 route.matched 自动生成面包屑 */\r\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\r\n return route.matched\r\n .filter((record: any) => record.meta?.title)\r\n .map((record: any) => ({\r\n key: record.path,\r\n label: formatLabel((record.meta.title || '') as string),\r\n icon: record.meta.icon as string | undefined,\r\n children: record.children?.length\r\n ? record.children.map((child: any) => ({\r\n key: child.path,\r\n label: formatLabel((child.meta?.title || '') as string),\r\n ...(child.children?.length && {\r\n children: child.children.map((grandChild: any) => ({\r\n key: grandChild.path,\r\n label: formatLabel((grandChild.meta?.title || '') as string),\r\n })),\r\n }),\r\n }))\r\n : [],\r\n }))\r\n })\r\n\r\n const breadcrumbItems = computed<BreadcrumbItem[]>(\r\n () => props.items ?? autoBreadcrumb.value\r\n )\r\n\r\n const handleSelect = (key: string) => {\r\n emit('select', key)\r\n }\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n .c-breadcrumb {\r\n // 暴露 CSS 变量,方便主项目覆盖\r\n --c-breadcrumb-icon-size: 16px;\r\n --c-breadcrumb-gap: 4px;\r\n --c-breadcrumb-font-size: inherit;\r\n\r\n display: flex;\r\n align-items: center;\r\n height: 100%;\r\n\r\n &__trigger,\r\n &__link {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--c-breadcrumb-gap);\r\n font-size: var(--c-breadcrumb-font-size);\r\n line-height: 1;\r\n cursor: pointer;\r\n }\r\n\r\n // 确保 C_Icon 在面包屑中尺寸一致\r\n .c-icon {\r\n flex-shrink: 0;\r\n }\r\n\r\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\r\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\r\n .n-breadcrumb-item {\r\n display: inline-flex !important;\r\n align-items: center;\r\n\r\n .n-breadcrumb-item__separator {\r\n display: inline-flex;\r\n align-items: center;\r\n line-height: 1;\r\n margin-top: -4px;\r\n }\r\n }\r\n }\r\n</style>\r\n","<!--\r\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\r\n *\r\n * 支持两种模式:\r\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\r\n * 2. 手动模式 — 传入 `items` 完全自定义\r\n *\r\n * @example 自动模式(零配置)\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :label-formatter=\"$t\"\r\n * @select=\"router.push\"\r\n * />\r\n * ```\r\n *\r\n * @example 手动模式\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :items=\"customBreadcrumbs\"\r\n * @select=\"handleSelect\"\r\n * />\r\n * ```\r\n *\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-breadcrumb flex-1 min-w-0\"\r\n :style=\"{\r\n '--c-breadcrumb-icon-size': `${iconSize}px`,\r\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\r\n }\"\r\n >\r\n <NBreadcrumb>\r\n <NBreadcrumbItem\r\n v-for=\"(item, index) in breadcrumbItems\"\r\n :key=\"index\"\r\n >\r\n <NDropdown\r\n v-if=\"item.children?.length\"\r\n :options=\"item.children\"\r\n @select=\"handleSelect\"\r\n >\r\n <div class=\"c-breadcrumb__trigger\">\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </div>\r\n </NDropdown>\r\n <span\r\n v-else\r\n class=\"c-breadcrumb__link\"\r\n @click=\"handleSelect(item.key)\"\r\n >\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n </NBreadcrumbItem>\r\n </NBreadcrumb>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import { useRoute } from 'vue-router'\r\n import { C_Icon } from '../C_Icon'\r\n import type { BreadcrumbItem } from '../_shared'\r\n\r\n defineOptions({ name: 'C_Breadcrumb' })\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n /**\r\n * 手动传入面包屑数据\r\n * 不传时自动从 `route.matched` 生成(零配置)\r\n */\r\n items?: BreadcrumbItem[]\r\n /** 是否显示图标 */\r\n showIcon?: boolean\r\n /** 图标大小 (px),默认 16 */\r\n iconSize?: number\r\n /**\r\n * 标签文本格式化函数(用于 i18n)\r\n * 仅在自动模式下生效\r\n */\r\n labelFormatter?: (label: string) => string\r\n }>(),\r\n {\r\n showIcon: true,\r\n iconSize: 16,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n /** 面包屑项被选中(返回路径 key) */\r\n select: [path: string]\r\n }>()\r\n\r\n const route = useRoute()\r\n\r\n const formatLabel = (title: string): string =>\r\n props.labelFormatter ? props.labelFormatter(title) : title\r\n\r\n /** 从 route.matched 自动生成面包屑 */\r\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\r\n return route.matched\r\n .filter((record: any) => record.meta?.title)\r\n .map((record: any) => ({\r\n key: record.path,\r\n label: formatLabel((record.meta.title || '') as string),\r\n icon: record.meta.icon as string | undefined,\r\n children: record.children?.length\r\n ? record.children.map((child: any) => ({\r\n key: child.path,\r\n label: formatLabel((child.meta?.title || '') as string),\r\n ...(child.children?.length && {\r\n children: child.children.map((grandChild: any) => ({\r\n key: grandChild.path,\r\n label: formatLabel((grandChild.meta?.title || '') as string),\r\n })),\r\n }),\r\n }))\r\n : [],\r\n }))\r\n })\r\n\r\n const breadcrumbItems = computed<BreadcrumbItem[]>(\r\n () => props.items ?? autoBreadcrumb.value\r\n )\r\n\r\n const handleSelect = (key: string) => {\r\n emit('select', key)\r\n }\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n .c-breadcrumb {\r\n // 暴露 CSS 变量,方便主项目覆盖\r\n --c-breadcrumb-icon-size: 16px;\r\n --c-breadcrumb-gap: 4px;\r\n --c-breadcrumb-font-size: inherit;\r\n\r\n display: flex;\r\n align-items: center;\r\n height: 100%;\r\n\r\n &__trigger,\r\n &__link {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--c-breadcrumb-gap);\r\n font-size: var(--c-breadcrumb-font-size);\r\n line-height: 1;\r\n cursor: pointer;\r\n }\r\n\r\n // 确保 C_Icon 在面包屑中尺寸一致\r\n .c-icon {\r\n flex-shrink: 0;\r\n }\r\n\r\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\r\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\r\n .n-breadcrumb-item {\r\n display: inline-flex !important;\r\n align-items: center;\r\n\r\n .n-breadcrumb-item__separator {\r\n display: inline-flex;\r\n align-items: center;\r\n line-height: 1;\r\n margin-top: -4px;\r\n }\r\n }\r\n }\r\n</style>\r\n"],"mappings":"6WE6EE,IAAM,EAAQ,EAuBR,EAAO,EAKP,GAAA,EAAA,EAAA,WAAkB,CAElB,EAAe,GACnB,EAAM,eAAiB,EAAM,eAAe,EAAM,CAAG,EAGjD,GAAA,EAAA,EAAA,cACG,EAAM,QACV,OAAQ,GAAgB,EAAO,MAAM,MAAM,CAC3C,IAAK,IAAiB,CACrB,IAAK,EAAO,KACZ,MAAO,EAAa,EAAO,KAAK,OAAS,GAAc,CACvD,KAAM,EAAO,KAAK,KAClB,SAAU,EAAO,UAAU,OACvB,EAAO,SAAS,IAAK,IAAgB,CACnC,IAAK,EAAM,KACX,MAAO,EAAa,EAAM,MAAM,OAAS,GAAc,CACvD,GAAI,EAAM,UAAU,QAAU,CAC5B,SAAU,EAAM,SAAS,IAAK,IAAqB,CACjD,IAAK,EAAW,KAChB,MAAO,EAAa,EAAW,MAAM,OAAS,GAAc,CAC7D,EAAE,CACJ,CACF,EAAE,CACH,EAAE,CACP,EAAE,CACL,CAEI,GAAA,EAAA,EAAA,cACE,EAAM,OAAS,EAAe,MACrC,CAEK,EAAgB,GAAgB,CACpC,EAAK,SAAU,EAAI,uHAxEf,MAAA,CAvCJ,MAAM,8BACL,OAAA,EAAA,EAAA,gBAAK,+BAA0CA,EAAAA,SAAQ,4BAAsC,KAAK,IAAI,KAAK,MAAMA,EAAAA,SAAQ,EAAA,CAAA,EAAA,CAAA,0BAqC5G,EAAA,KAAA,2BA9B8B,GAAA,EAAA,EAAA,WAAA,GAAA,EAAA,EAAA,EAAA,oBA6BxB,EAAA,SAAA,MAAA,EAAA,EAAA,YA7BQ,EAAA,OAAhB,EAAM,yCA6BE,EAAA,CA5Bf,IAAK,EAAK,CAAA,2BAkBhB,CAfa,EAAK,UAAU,SAAA,EAAA,EAAA,YAAA,EAAA,EAAA,EAAA,aAYX,EAAA,OAXT,QAAS,EAAK,SACd,SAAQ,8BASH,EAAA,EAAA,EAAA,oBAAA,MAPN,EAOM,CALIC,EAAAA,WAAAA,EAAAA,EAAAA,YAAAA,EAAAA,EAAAA,EAAAA,cAAAA,EAAAA,EAAAA,OAGN,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,6FACP,KAAA,EAAA,EAAA,iBACC,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,qEAcV,OAAA,OATL,MAAM,qBACL,QAAK,GAAE,EAAa,EAAK,IAAG,GAGrBC,EAAAA,WAAAA,EAAAA,EAAAA,YAAAA,EAAAA,EAAAA,EAAAA,cAAAA,EAAAA,EAAAA,OAGN,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,6FACP,KAAA,EAAA,EAAA,iBACC,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Breadcrumb2.js","names":["iconSize","showIcon"],"sources":["../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\n *\n * 支持两种模式:\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\n * 2. 手动模式 — 传入 `items` 完全自定义\n *\n * @example 自动模式(零配置)\n * ```vue\n * <C_Breadcrumb\n * :label-formatter=\"$t\"\n * @select=\"router.push\"\n * />\n * ```\n *\n * @example 手动模式\n * ```vue\n * <C_Breadcrumb\n * :items=\"customBreadcrumbs\"\n * @select=\"handleSelect\"\n * />\n * ```\n *\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div\n class=\"c-breadcrumb flex-1 min-w-0\"\n :style=\"{\n '--c-breadcrumb-icon-size': `${iconSize}px`,\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\n }\"\n >\n <NBreadcrumb>\n <NBreadcrumbItem\n v-for=\"(item, index) in breadcrumbItems\"\n :key=\"index\"\n >\n <NDropdown\n v-if=\"item.children?.length\"\n :options=\"item.children\"\n @select=\"handleSelect\"\n >\n <div class=\"c-breadcrumb__trigger\">\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </div>\n </NDropdown>\n <span\n v-else\n class=\"c-breadcrumb__link\"\n @click=\"handleSelect(item.key)\"\n >\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </span>\n </NBreadcrumbItem>\n </NBreadcrumb>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useRoute } from 'vue-router'\n import { C_Icon } from '../C_Icon'\n import type { BreadcrumbItem } from '../_shared'\n\n defineOptions({ name: 'C_Breadcrumb' })\n\n const props = withDefaults(\n defineProps<{\n /**\n * 手动传入面包屑数据\n * 不传时自动从 `route.matched` 生成(零配置)\n */\n items?: BreadcrumbItem[]\n /** 是否显示图标 */\n showIcon?: boolean\n /** 图标大小 (px),默认 16 */\n iconSize?: number\n /**\n * 标签文本格式化函数(用于 i18n)\n * 仅在自动模式下生效\n */\n labelFormatter?: (label: string) => string\n }>(),\n {\n showIcon: true,\n iconSize: 16,\n }\n )\n\n const emit = defineEmits<{\n /** 面包屑项被选中(返回路径 key) */\n select: [path: string]\n }>()\n\n const route = useRoute()\n\n const formatLabel = (title: string): string =>\n props.labelFormatter ? props.labelFormatter(title) : title\n\n /** 从 route.matched 自动生成面包屑 */\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\n return route.matched\n .filter((record: any) => record.meta?.title)\n .map((record: any) => ({\n key: record.path,\n label: formatLabel((record.meta.title || '') as string),\n icon: record.meta.icon as string | undefined,\n children: record.children?.length\n ? record.children.map((child: any) => ({\n key: child.path,\n label: formatLabel((child.meta?.title || '') as string),\n ...(child.children?.length && {\n children: child.children.map((grandChild: any) => ({\n key: grandChild.path,\n label: formatLabel((grandChild.meta?.title || '') as string),\n })),\n }),\n }))\n : [],\n }))\n })\n\n const breadcrumbItems = computed<BreadcrumbItem[]>(\n () => props.items ?? autoBreadcrumb.value\n )\n\n const handleSelect = (key: string) => {\n emit('select', key)\n }\n</script>\n\n<style lang=\"scss\">\n .c-breadcrumb {\n // 暴露 CSS 变量,方便主项目覆盖\n --c-breadcrumb-icon-size: 16px;\n --c-breadcrumb-gap: 4px;\n --c-breadcrumb-font-size: inherit;\n\n display: flex;\n align-items: center;\n height: 100%;\n\n &__trigger,\n &__link {\n display: inline-flex;\n align-items: center;\n gap: var(--c-breadcrumb-gap);\n font-size: var(--c-breadcrumb-font-size);\n line-height: 1;\n cursor: pointer;\n }\n\n // 确保 C_Icon 在面包屑中尺寸一致\n .c-icon {\n flex-shrink: 0;\n }\n\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\n .n-breadcrumb-item {\n display: inline-flex !important;\n align-items: center;\n\n .n-breadcrumb-item__separator {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n margin-top: -4px;\n }\n }\n }\n</style>\n","/* unplugin-vue-components disabled */<!--\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\n *\n * 支持两种模式:\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\n * 2. 手动模式 — 传入 `items` 完全自定义\n *\n * @example 自动模式(零配置)\n * ```vue\n * <C_Breadcrumb\n * :label-formatter=\"$t\"\n * @select=\"router.push\"\n * />\n * ```\n *\n * @example 手动模式\n * ```vue\n * <C_Breadcrumb\n * :items=\"customBreadcrumbs\"\n * @select=\"handleSelect\"\n * />\n * ```\n *\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div\n class=\"c-breadcrumb flex-1 min-w-0\"\n :style=\"{\n '--c-breadcrumb-icon-size': `${iconSize}px`,\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\n }\"\n >\n <NBreadcrumb>\n <NBreadcrumbItem\n v-for=\"(item, index) in breadcrumbItems\"\n :key=\"index\"\n >\n <NDropdown\n v-if=\"item.children?.length\"\n :options=\"item.children\"\n @select=\"handleSelect\"\n >\n <div class=\"c-breadcrumb__trigger\">\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </div>\n </NDropdown>\n <span\n v-else\n class=\"c-breadcrumb__link\"\n @click=\"handleSelect(item.key)\"\n >\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </span>\n </NBreadcrumbItem>\n </NBreadcrumb>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useRoute } from 'vue-router'\n import { C_Icon } from '../C_Icon'\n import type { BreadcrumbItem } from '../_shared'\n\n defineOptions({ name: 'C_Breadcrumb' })\n\n const props = withDefaults(\n defineProps<{\n /**\n * 手动传入面包屑数据\n * 不传时自动从 `route.matched` 生成(零配置)\n */\n items?: BreadcrumbItem[]\n /** 是否显示图标 */\n showIcon?: boolean\n /** 图标大小 (px),默认 16 */\n iconSize?: number\n /**\n * 标签文本格式化函数(用于 i18n)\n * 仅在自动模式下生效\n */\n labelFormatter?: (label: string) => string\n }>(),\n {\n showIcon: true,\n iconSize: 16,\n }\n )\n\n const emit = defineEmits<{\n /** 面包屑项被选中(返回路径 key) */\n select: [path: string]\n }>()\n\n const route = useRoute()\n\n const formatLabel = (title: string): string =>\n props.labelFormatter ? props.labelFormatter(title) : title\n\n /** 从 route.matched 自动生成面包屑 */\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\n return route.matched\n .filter((record: any) => record.meta?.title)\n .map((record: any) => ({\n key: record.path,\n label: formatLabel((record.meta.title || '') as string),\n icon: record.meta.icon as string | undefined,\n children: record.children?.length\n ? record.children.map((child: any) => ({\n key: child.path,\n label: formatLabel((child.meta?.title || '') as string),\n ...(child.children?.length && {\n children: child.children.map((grandChild: any) => ({\n key: grandChild.path,\n label: formatLabel((grandChild.meta?.title || '') as string),\n })),\n }),\n }))\n : [],\n }))\n })\n\n const breadcrumbItems = computed<BreadcrumbItem[]>(\n () => props.items ?? autoBreadcrumb.value\n )\n\n const handleSelect = (key: string) => {\n emit('select', key)\n }\n</script>\n\n<style lang=\"scss\">\n .c-breadcrumb {\n // 暴露 CSS 变量,方便主项目覆盖\n --c-breadcrumb-icon-size: 16px;\n --c-breadcrumb-gap: 4px;\n --c-breadcrumb-font-size: inherit;\n\n display: flex;\n align-items: center;\n height: 100%;\n\n &__trigger,\n &__link {\n display: inline-flex;\n align-items: center;\n gap: var(--c-breadcrumb-gap);\n font-size: var(--c-breadcrumb-font-size);\n line-height: 1;\n cursor: pointer;\n }\n\n // 确保 C_Icon 在面包屑中尺寸一致\n .c-icon {\n flex-shrink: 0;\n }\n\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\n .n-breadcrumb-item {\n display: inline-flex !important;\n align-items: center;\n\n .n-breadcrumb-item__separator {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n margin-top: -4px;\n }\n }\n }\n</style>\n","<!--\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\n *\n * 支持两种模式:\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\n * 2. 手动模式 — 传入 `items` 完全自定义\n *\n * @example 自动模式(零配置)\n * ```vue\n * <C_Breadcrumb\n * :label-formatter=\"$t\"\n * @select=\"router.push\"\n * />\n * ```\n *\n * @example 手动模式\n * ```vue\n * <C_Breadcrumb\n * :items=\"customBreadcrumbs\"\n * @select=\"handleSelect\"\n * />\n * ```\n *\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\n-->\n<template>\n <div\n class=\"c-breadcrumb flex-1 min-w-0\"\n :style=\"{\n '--c-breadcrumb-icon-size': `${iconSize}px`,\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\n }\"\n >\n <NBreadcrumb>\n <NBreadcrumbItem\n v-for=\"(item, index) in breadcrumbItems\"\n :key=\"index\"\n >\n <NDropdown\n v-if=\"item.children?.length\"\n :options=\"item.children\"\n @select=\"handleSelect\"\n >\n <div class=\"c-breadcrumb__trigger\">\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </div>\n </NDropdown>\n <span\n v-else\n class=\"c-breadcrumb__link\"\n @click=\"handleSelect(item.key)\"\n >\n <C_Icon\n v-if=\"showIcon\"\n :name=\"item.icon\"\n :size=\"iconSize\"\n />\n {{ item.label }}\n </span>\n </NBreadcrumbItem>\n </NBreadcrumb>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useRoute } from 'vue-router'\n import { C_Icon } from '../C_Icon'\n import type { BreadcrumbItem } from '../_shared'\n\n defineOptions({ name: 'C_Breadcrumb' })\n\n const props = withDefaults(\n defineProps<{\n /**\n * 手动传入面包屑数据\n * 不传时自动从 `route.matched` 生成(零配置)\n */\n items?: BreadcrumbItem[]\n /** 是否显示图标 */\n showIcon?: boolean\n /** 图标大小 (px),默认 16 */\n iconSize?: number\n /**\n * 标签文本格式化函数(用于 i18n)\n * 仅在自动模式下生效\n */\n labelFormatter?: (label: string) => string\n }>(),\n {\n showIcon: true,\n iconSize: 16,\n }\n )\n\n const emit = defineEmits<{\n /** 面包屑项被选中(返回路径 key) */\n select: [path: string]\n }>()\n\n const route = useRoute()\n\n const formatLabel = (title: string): string =>\n props.labelFormatter ? props.labelFormatter(title) : title\n\n /** 从 route.matched 自动生成面包屑 */\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\n return route.matched\n .filter((record: any) => record.meta?.title)\n .map((record: any) => ({\n key: record.path,\n label: formatLabel((record.meta.title || '') as string),\n icon: record.meta.icon as string | undefined,\n children: record.children?.length\n ? record.children.map((child: any) => ({\n key: child.path,\n label: formatLabel((child.meta?.title || '') as string),\n ...(child.children?.length && {\n children: child.children.map((grandChild: any) => ({\n key: grandChild.path,\n label: formatLabel((grandChild.meta?.title || '') as string),\n })),\n }),\n }))\n : [],\n }))\n })\n\n const breadcrumbItems = computed<BreadcrumbItem[]>(\n () => props.items ?? autoBreadcrumb.value\n )\n\n const handleSelect = (key: string) => {\n emit('select', key)\n }\n</script>\n\n<style lang=\"scss\">\n .c-breadcrumb {\n // 暴露 CSS 变量,方便主项目覆盖\n --c-breadcrumb-icon-size: 16px;\n --c-breadcrumb-gap: 4px;\n --c-breadcrumb-font-size: inherit;\n\n display: flex;\n align-items: center;\n height: 100%;\n\n &__trigger,\n &__link {\n display: inline-flex;\n align-items: center;\n gap: var(--c-breadcrumb-gap);\n font-size: var(--c-breadcrumb-font-size);\n line-height: 1;\n cursor: pointer;\n }\n\n // 确保 C_Icon 在面包屑中尺寸一致\n .c-icon {\n flex-shrink: 0;\n }\n\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\n .n-breadcrumb-item {\n display: inline-flex !important;\n align-items: center;\n\n .n-breadcrumb-item__separator {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n margin-top: -4px;\n }\n }\n }\n</style>\n"],"mappings":"opBE6EE,IAAM,EAAQ,EAuBR,EAAO,EAKP,EAAQ,GAAS,CAEjB,EAAe,GACnB,EAAM,eAAiB,EAAM,eAAe,EAAM,CAAG,EAGjD,EAAiB,MACd,EAAM,QACV,OAAQ,GAAgB,EAAO,MAAM,MAAK,CAC1C,IAAK,IAAiB,CACrB,IAAK,EAAO,KACZ,MAAO,EAAa,EAAO,KAAK,OAAS,GAAc,CACvD,KAAM,EAAO,KAAK,KAClB,SAAU,EAAO,UAAU,OACvB,EAAO,SAAS,IAAK,IAAgB,CACnC,IAAK,EAAM,KACX,MAAO,EAAa,EAAM,MAAM,OAAS,GAAc,CACvD,GAAI,EAAM,UAAU,QAAU,CAC5B,SAAU,EAAM,SAAS,IAAK,IAAqB,CACjD,IAAK,EAAW,KAChB,MAAO,EAAa,EAAW,MAAM,OAAS,GAAc,CAC7D,EAAE,CACJ,CACF,EAAC,CACF,EAAE,CACP,EAAC,CACL,CAEK,EAAkB,MAChB,EAAM,OAAS,EAAe,MACtC,CAEM,EAAgB,GAAgB,CACpC,EAAK,SAAU,EAAG,2CAhHpB,EAwCM,MAAA,CAvCJ,MAAM,8BACL,MAAK,EAAA,+BAAyCA,EAAAA,SAAQ,4BAAqC,KAAK,IAAI,KAAK,MAAMA,EAAAA,SAAQ,EAAA,CAAA,EAAA,CAAA,QAKxH,EAgCc,EAAA,KAAA,eA9B8B,EAAA,EAAA,GAAA,CAD1C,EA8BkB,EAAA,KAAA,EA7BQ,EAAA,OAAhB,EAAM,SADhB,EA8BkB,EAAA,CA5Bf,IAAK,EAAK,CAAA,eAkBb,CAfU,EAAK,UAAU,QAAA,GAAA,CADvB,EAaY,EAAA,OAXT,QAAS,EAAK,SACd,SAAQ,kBASH,CAPN,EAOM,MAPN,EAOM,CALIC,EAAAA,UAAAA,GAAAA,CADR,EAIE,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,kDACP,IACF,EAAG,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,8BAGjB,EAWO,OAAA,OATL,MAAM,qBACL,QAAK,GAAE,EAAa,EAAK,IAAG,GAGrBC,EAAAA,UAAAA,GAAAA,CADR,EAIE,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,kDACP,IACF,EAAG,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"C_Breadcrumb2.js","names":["iconSize","showIcon"],"sources":["../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue","../src/components/C_Breadcrumb/index.vue"],"sourcesContent":["/* unplugin-vue-components disabled */<!--\r\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\r\n *\r\n * 支持两种模式:\r\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\r\n * 2. 手动模式 — 传入 `items` 完全自定义\r\n *\r\n * @example 自动模式(零配置)\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :label-formatter=\"$t\"\r\n * @select=\"router.push\"\r\n * />\r\n * ```\r\n *\r\n * @example 手动模式\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :items=\"customBreadcrumbs\"\r\n * @select=\"handleSelect\"\r\n * />\r\n * ```\r\n *\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-breadcrumb flex-1 min-w-0\"\r\n :style=\"{\r\n '--c-breadcrumb-icon-size': `${iconSize}px`,\r\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\r\n }\"\r\n >\r\n <NBreadcrumb>\r\n <NBreadcrumbItem\r\n v-for=\"(item, index) in breadcrumbItems\"\r\n :key=\"index\"\r\n >\r\n <NDropdown\r\n v-if=\"item.children?.length\"\r\n :options=\"item.children\"\r\n @select=\"handleSelect\"\r\n >\r\n <div class=\"c-breadcrumb__trigger\">\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </div>\r\n </NDropdown>\r\n <span\r\n v-else\r\n class=\"c-breadcrumb__link\"\r\n @click=\"handleSelect(item.key)\"\r\n >\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n </NBreadcrumbItem>\r\n </NBreadcrumb>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import { useRoute } from 'vue-router'\r\n import { C_Icon } from '../C_Icon'\r\n import type { BreadcrumbItem } from '../_shared'\r\n\r\n defineOptions({ name: 'C_Breadcrumb' })\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n /**\r\n * 手动传入面包屑数据\r\n * 不传时自动从 `route.matched` 生成(零配置)\r\n */\r\n items?: BreadcrumbItem[]\r\n /** 是否显示图标 */\r\n showIcon?: boolean\r\n /** 图标大小 (px),默认 16 */\r\n iconSize?: number\r\n /**\r\n * 标签文本格式化函数(用于 i18n)\r\n * 仅在自动模式下生效\r\n */\r\n labelFormatter?: (label: string) => string\r\n }>(),\r\n {\r\n showIcon: true,\r\n iconSize: 16,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n /** 面包屑项被选中(返回路径 key) */\r\n select: [path: string]\r\n }>()\r\n\r\n const route = useRoute()\r\n\r\n const formatLabel = (title: string): string =>\r\n props.labelFormatter ? props.labelFormatter(title) : title\r\n\r\n /** 从 route.matched 自动生成面包屑 */\r\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\r\n return route.matched\r\n .filter((record: any) => record.meta?.title)\r\n .map((record: any) => ({\r\n key: record.path,\r\n label: formatLabel((record.meta.title || '') as string),\r\n icon: record.meta.icon as string | undefined,\r\n children: record.children?.length\r\n ? record.children.map((child: any) => ({\r\n key: child.path,\r\n label: formatLabel((child.meta?.title || '') as string),\r\n ...(child.children?.length && {\r\n children: child.children.map((grandChild: any) => ({\r\n key: grandChild.path,\r\n label: formatLabel((grandChild.meta?.title || '') as string),\r\n })),\r\n }),\r\n }))\r\n : [],\r\n }))\r\n })\r\n\r\n const breadcrumbItems = computed<BreadcrumbItem[]>(\r\n () => props.items ?? autoBreadcrumb.value\r\n )\r\n\r\n const handleSelect = (key: string) => {\r\n emit('select', key)\r\n }\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n .c-breadcrumb {\r\n // 暴露 CSS 变量,方便主项目覆盖\r\n --c-breadcrumb-icon-size: 16px;\r\n --c-breadcrumb-gap: 4px;\r\n --c-breadcrumb-font-size: inherit;\r\n\r\n display: flex;\r\n align-items: center;\r\n height: 100%;\r\n\r\n &__trigger,\r\n &__link {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--c-breadcrumb-gap);\r\n font-size: var(--c-breadcrumb-font-size);\r\n line-height: 1;\r\n cursor: pointer;\r\n }\r\n\r\n // 确保 C_Icon 在面包屑中尺寸一致\r\n .c-icon {\r\n flex-shrink: 0;\r\n }\r\n\r\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\r\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\r\n .n-breadcrumb-item {\r\n display: inline-flex !important;\r\n align-items: center;\r\n\r\n .n-breadcrumb-item__separator {\r\n display: inline-flex;\r\n align-items: center;\r\n line-height: 1;\r\n margin-top: -4px;\r\n }\r\n }\r\n }\r\n</style>\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\r\n *\r\n * 支持两种模式:\r\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\r\n * 2. 手动模式 — 传入 `items` 完全自定义\r\n *\r\n * @example 自动模式(零配置)\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :label-formatter=\"$t\"\r\n * @select=\"router.push\"\r\n * />\r\n * ```\r\n *\r\n * @example 手动模式\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :items=\"customBreadcrumbs\"\r\n * @select=\"handleSelect\"\r\n * />\r\n * ```\r\n *\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-breadcrumb flex-1 min-w-0\"\r\n :style=\"{\r\n '--c-breadcrumb-icon-size': `${iconSize}px`,\r\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\r\n }\"\r\n >\r\n <NBreadcrumb>\r\n <NBreadcrumbItem\r\n v-for=\"(item, index) in breadcrumbItems\"\r\n :key=\"index\"\r\n >\r\n <NDropdown\r\n v-if=\"item.children?.length\"\r\n :options=\"item.children\"\r\n @select=\"handleSelect\"\r\n >\r\n <div class=\"c-breadcrumb__trigger\">\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </div>\r\n </NDropdown>\r\n <span\r\n v-else\r\n class=\"c-breadcrumb__link\"\r\n @click=\"handleSelect(item.key)\"\r\n >\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n </NBreadcrumbItem>\r\n </NBreadcrumb>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import { useRoute } from 'vue-router'\r\n import { C_Icon } from '../C_Icon'\r\n import type { BreadcrumbItem } from '../_shared'\r\n\r\n defineOptions({ name: 'C_Breadcrumb' })\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n /**\r\n * 手动传入面包屑数据\r\n * 不传时自动从 `route.matched` 生成(零配置)\r\n */\r\n items?: BreadcrumbItem[]\r\n /** 是否显示图标 */\r\n showIcon?: boolean\r\n /** 图标大小 (px),默认 16 */\r\n iconSize?: number\r\n /**\r\n * 标签文本格式化函数(用于 i18n)\r\n * 仅在自动模式下生效\r\n */\r\n labelFormatter?: (label: string) => string\r\n }>(),\r\n {\r\n showIcon: true,\r\n iconSize: 16,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n /** 面包屑项被选中(返回路径 key) */\r\n select: [path: string]\r\n }>()\r\n\r\n const route = useRoute()\r\n\r\n const formatLabel = (title: string): string =>\r\n props.labelFormatter ? props.labelFormatter(title) : title\r\n\r\n /** 从 route.matched 自动生成面包屑 */\r\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\r\n return route.matched\r\n .filter((record: any) => record.meta?.title)\r\n .map((record: any) => ({\r\n key: record.path,\r\n label: formatLabel((record.meta.title || '') as string),\r\n icon: record.meta.icon as string | undefined,\r\n children: record.children?.length\r\n ? record.children.map((child: any) => ({\r\n key: child.path,\r\n label: formatLabel((child.meta?.title || '') as string),\r\n ...(child.children?.length && {\r\n children: child.children.map((grandChild: any) => ({\r\n key: grandChild.path,\r\n label: formatLabel((grandChild.meta?.title || '') as string),\r\n })),\r\n }),\r\n }))\r\n : [],\r\n }))\r\n })\r\n\r\n const breadcrumbItems = computed<BreadcrumbItem[]>(\r\n () => props.items ?? autoBreadcrumb.value\r\n )\r\n\r\n const handleSelect = (key: string) => {\r\n emit('select', key)\r\n }\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n .c-breadcrumb {\r\n // 暴露 CSS 变量,方便主项目覆盖\r\n --c-breadcrumb-icon-size: 16px;\r\n --c-breadcrumb-gap: 4px;\r\n --c-breadcrumb-font-size: inherit;\r\n\r\n display: flex;\r\n align-items: center;\r\n height: 100%;\r\n\r\n &__trigger,\r\n &__link {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--c-breadcrumb-gap);\r\n font-size: var(--c-breadcrumb-font-size);\r\n line-height: 1;\r\n cursor: pointer;\r\n }\r\n\r\n // 确保 C_Icon 在面包屑中尺寸一致\r\n .c-icon {\r\n flex-shrink: 0;\r\n }\r\n\r\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\r\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\r\n .n-breadcrumb-item {\r\n display: inline-flex !important;\r\n align-items: center;\r\n\r\n .n-breadcrumb-item__separator {\r\n display: inline-flex;\r\n align-items: center;\r\n line-height: 1;\r\n margin-top: -4px;\r\n }\r\n }\r\n }\r\n</style>\r\n","<!--\r\n * @Description: 通用面包屑组件 — 基于 NBreadcrumb 的路由面包屑导航\r\n *\r\n * 支持两种模式:\r\n * 1. 自动模式(默认)— 从 `route.matched` 自动生成面包屑\r\n * 2. 手动模式 — 传入 `items` 完全自定义\r\n *\r\n * @example 自动模式(零配置)\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :label-formatter=\"$t\"\r\n * @select=\"router.push\"\r\n * />\r\n * ```\r\n *\r\n * @example 手动模式\r\n * ```vue\r\n * <C_Breadcrumb\r\n * :items=\"customBreadcrumbs\"\r\n * @select=\"handleSelect\"\r\n * />\r\n * ```\r\n *\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n-->\r\n<template>\r\n <div\r\n class=\"c-breadcrumb flex-1 min-w-0\"\r\n :style=\"{\r\n '--c-breadcrumb-icon-size': `${iconSize}px`,\r\n '--c-breadcrumb-gap': `${Math.max(Math.round(iconSize / 4), 2)}px`,\r\n }\"\r\n >\r\n <NBreadcrumb>\r\n <NBreadcrumbItem\r\n v-for=\"(item, index) in breadcrumbItems\"\r\n :key=\"index\"\r\n >\r\n <NDropdown\r\n v-if=\"item.children?.length\"\r\n :options=\"item.children\"\r\n @select=\"handleSelect\"\r\n >\r\n <div class=\"c-breadcrumb__trigger\">\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </div>\r\n </NDropdown>\r\n <span\r\n v-else\r\n class=\"c-breadcrumb__link\"\r\n @click=\"handleSelect(item.key)\"\r\n >\r\n <C_Icon\r\n v-if=\"showIcon\"\r\n :name=\"item.icon\"\r\n :size=\"iconSize\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n </NBreadcrumbItem>\r\n </NBreadcrumb>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed } from 'vue'\r\n import { useRoute } from 'vue-router'\r\n import { C_Icon } from '../C_Icon'\r\n import type { BreadcrumbItem } from '../_shared'\r\n\r\n defineOptions({ name: 'C_Breadcrumb' })\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n /**\r\n * 手动传入面包屑数据\r\n * 不传时自动从 `route.matched` 生成(零配置)\r\n */\r\n items?: BreadcrumbItem[]\r\n /** 是否显示图标 */\r\n showIcon?: boolean\r\n /** 图标大小 (px),默认 16 */\r\n iconSize?: number\r\n /**\r\n * 标签文本格式化函数(用于 i18n)\r\n * 仅在自动模式下生效\r\n */\r\n labelFormatter?: (label: string) => string\r\n }>(),\r\n {\r\n showIcon: true,\r\n iconSize: 16,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n /** 面包屑项被选中(返回路径 key) */\r\n select: [path: string]\r\n }>()\r\n\r\n const route = useRoute()\r\n\r\n const formatLabel = (title: string): string =>\r\n props.labelFormatter ? props.labelFormatter(title) : title\r\n\r\n /** 从 route.matched 自动生成面包屑 */\r\n const autoBreadcrumb = computed<BreadcrumbItem[]>(() => {\r\n return route.matched\r\n .filter((record: any) => record.meta?.title)\r\n .map((record: any) => ({\r\n key: record.path,\r\n label: formatLabel((record.meta.title || '') as string),\r\n icon: record.meta.icon as string | undefined,\r\n children: record.children?.length\r\n ? record.children.map((child: any) => ({\r\n key: child.path,\r\n label: formatLabel((child.meta?.title || '') as string),\r\n ...(child.children?.length && {\r\n children: child.children.map((grandChild: any) => ({\r\n key: grandChild.path,\r\n label: formatLabel((grandChild.meta?.title || '') as string),\r\n })),\r\n }),\r\n }))\r\n : [],\r\n }))\r\n })\r\n\r\n const breadcrumbItems = computed<BreadcrumbItem[]>(\r\n () => props.items ?? autoBreadcrumb.value\r\n )\r\n\r\n const handleSelect = (key: string) => {\r\n emit('select', key)\r\n }\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n .c-breadcrumb {\r\n // 暴露 CSS 变量,方便主项目覆盖\r\n --c-breadcrumb-icon-size: 16px;\r\n --c-breadcrumb-gap: 4px;\r\n --c-breadcrumb-font-size: inherit;\r\n\r\n display: flex;\r\n align-items: center;\r\n height: 100%;\r\n\r\n &__trigger,\r\n &__link {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--c-breadcrumb-gap);\r\n font-size: var(--c-breadcrumb-font-size);\r\n line-height: 1;\r\n cursor: pointer;\r\n }\r\n\r\n // 确保 C_Icon 在面包屑中尺寸一致\r\n .c-icon {\r\n flex-shrink: 0;\r\n }\r\n\r\n // 修复分隔符 \"/\" 与文本/图标垂直居中对齐\r\n // 原因:Naive UI 分隔符默认 line-height (~1.4) 导致 \"/\" 基线偏低\r\n .n-breadcrumb-item {\r\n display: inline-flex !important;\r\n align-items: center;\r\n\r\n .n-breadcrumb-item__separator {\r\n display: inline-flex;\r\n align-items: center;\r\n line-height: 1;\r\n margin-top: -4px;\r\n }\r\n }\r\n }\r\n</style>\r\n"],"mappings":"opBE6EE,IAAM,EAAQ,EAuBR,EAAO,EAKP,EAAQ,GAAU,CAElB,EAAe,GACnB,EAAM,eAAiB,EAAM,eAAe,EAAM,CAAG,EAGjD,EAAiB,MACd,EAAM,QACV,OAAQ,GAAgB,EAAO,MAAM,MAAM,CAC3C,IAAK,IAAiB,CACrB,IAAK,EAAO,KACZ,MAAO,EAAa,EAAO,KAAK,OAAS,GAAc,CACvD,KAAM,EAAO,KAAK,KAClB,SAAU,EAAO,UAAU,OACvB,EAAO,SAAS,IAAK,IAAgB,CACnC,IAAK,EAAM,KACX,MAAO,EAAa,EAAM,MAAM,OAAS,GAAc,CACvD,GAAI,EAAM,UAAU,QAAU,CAC5B,SAAU,EAAM,SAAS,IAAK,IAAqB,CACjD,IAAK,EAAW,KAChB,MAAO,EAAa,EAAW,MAAM,OAAS,GAAc,CAC7D,EAAE,CACJ,CACF,EAAE,CACH,EAAE,CACP,EAAE,CACL,CAEI,EAAkB,MAChB,EAAM,OAAS,EAAe,MACrC,CAEK,EAAgB,GAAgB,CACpC,EAAK,SAAU,EAAI,2CAhHrB,EAwCM,MAAA,CAvCJ,MAAM,8BACL,MAAK,EAAA,+BAA0CA,EAAAA,SAAQ,4BAAsC,KAAK,IAAI,KAAK,MAAMA,EAAAA,SAAQ,EAAA,CAAA,EAAA,CAAA,QAK1H,EAgCc,EAAA,KAAA,eA9B8B,EAAA,EAAA,GAAA,CAD1C,EA8BkB,EAAA,KAAA,EA7BQ,EAAA,OAAhB,EAAM,SADhB,EA8BkB,EAAA,CA5Bf,IAAK,EAAK,CAAA,eAkBhB,CAfa,EAAK,UAAU,QAAA,GAAA,CADvB,EAaY,EAAA,OAXT,QAAS,EAAK,SACd,SAAQ,kBASH,CAPN,EAOM,MAPN,EAOM,CALIC,EAAAA,UAAAA,GAAAA,CADR,EAIE,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,kDACP,IACF,EAAG,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,8BAGjB,EAWO,OAAA,OATL,MAAM,qBACL,QAAK,GAAE,EAAa,EAAK,IAAG,GAGrBC,EAAAA,UAAAA,GAAAA,CADR,EAIE,EAAA,EAAA,CAAA,OAFC,KAAM,EAAK,KACX,KAAMD,EAAAA,kDACP,IACF,EAAG,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Captcha-
|
|
1
|
+
{"version":3,"file":"C_Captcha-CZmAETly.css","names":[],"sources":["../src/components/C_Captcha/index.vue?vue&type=style&index=0&scoped=74f1f0d1&lang.scss"],"sourcesContent":["/* unplugin-vue-components disabled */.c-captcha-modern[data-v-74f1f0d1] {\n width: 100%;\n font-family: inherit;\n}\n.captcha-trigger[data-v-74f1f0d1] {\n width: 100%;\n max-width: 280px;\n margin: 0 auto;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.captcha-trigger[data-v-74f1f0d1]:hover:not(.disabled) {\n transform: translateY(-1px);\n}\n.captcha-trigger.disabled[data-v-74f1f0d1] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.captcha-content[data-v-74f1f0d1] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n flex: 1;\n}\n.captcha-icon[data-v-74f1f0d1] {\n font-size: 18px;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.captcha-text[data-v-74f1f0d1] {\n color: rgba(255, 255, 255, 0.8);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.3px;\n text-align: center;\n white-space: nowrap;\n}\n.refresh-button[data-v-74f1f0d1] {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.3s ease;\n color: rgba(255, 255, 255, 0.6);\n font-size: 14px;\n flex-shrink: 0;\n}\n.refresh-button[data-v-74f1f0d1]:hover {\n color: rgba(255, 255, 255, 0.9);\n transform: translateY(-50%) rotate(180deg);\n}\n.success-icon[data-v-74f1f0d1],\n.success-text[data-v-74f1f0d1] {\n color: #43c23a;\n}\n.error-icon[data-v-74f1f0d1],\n.error-text[data-v-74f1f0d1] {\n color: #f56c6c;\n}\n@keyframes shake-74f1f0d1 {\n0%, 100% {\n transform: translateX(0);\n}\n25% {\n transform: translateX(-4px);\n}\n75% {\n transform: translateX(4px);\n}\n}\n@media (max-width: 768px) {\n.captcha-trigger[data-v-74f1f0d1] {\n max-width: 240px;\n padding: 10px 14px;\n}\n.captcha-icon[data-v-74f1f0d1] {\n font-size: 16px;\n width: 18px;\n height: 18px;\n}\n.captcha-text[data-v-74f1f0d1] {\n font-size: 13px;\n}\n.refresh-button[data-v-74f1f0d1] {\n width: 24px;\n height: 24px;\n font-size: 12px;\n right: 10px;\n}\n}"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"C_Captcha-
|
|
1
|
+
{"version":3,"file":"C_Captcha-Ccq3DMrR.css","names":[],"sources":["../src/components/C_Captcha/index.vue?vue&type=style&index=0&scoped=74f1f0d1&lang.scss"],"sourcesContent":["/* unplugin-vue-components disabled */.c-captcha-modern[data-v-74f1f0d1] {\n width: 100%;\n font-family: inherit;\n}\n.captcha-trigger[data-v-74f1f0d1] {\n width: 100%;\n max-width: 280px;\n margin: 0 auto;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.captcha-trigger[data-v-74f1f0d1]:hover:not(.disabled) {\n transform: translateY(-1px);\n}\n.captcha-trigger.disabled[data-v-74f1f0d1] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.captcha-content[data-v-74f1f0d1] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n flex: 1;\n}\n.captcha-icon[data-v-74f1f0d1] {\n font-size: 18px;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.captcha-text[data-v-74f1f0d1] {\n color: rgba(255, 255, 255, 0.8);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.3px;\n text-align: center;\n white-space: nowrap;\n}\n.refresh-button[data-v-74f1f0d1] {\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.3s ease;\n color: rgba(255, 255, 255, 0.6);\n font-size: 14px;\n flex-shrink: 0;\n}\n.refresh-button[data-v-74f1f0d1]:hover {\n color: rgba(255, 255, 255, 0.9);\n transform: translateY(-50%) rotate(180deg);\n}\n.success-icon[data-v-74f1f0d1],\n.success-text[data-v-74f1f0d1] {\n color: #43c23a;\n}\n.error-icon[data-v-74f1f0d1],\n.error-text[data-v-74f1f0d1] {\n color: #f56c6c;\n}\n@keyframes shake-74f1f0d1 {\n0%, 100% {\n transform: translateX(0);\n}\n25% {\n transform: translateX(-4px);\n}\n75% {\n transform: translateX(4px);\n}\n}\n@media (max-width: 768px) {\n.captcha-trigger[data-v-74f1f0d1] {\n max-width: 240px;\n padding: 10px 14px;\n}\n.captcha-icon[data-v-74f1f0d1] {\n font-size: 16px;\n width: 18px;\n height: 18px;\n}\n.captcha-text[data-v-74f1f0d1] {\n font-size: 13px;\n}\n.refresh-button[data-v-74f1f0d1] {\n width: 24px;\n height: 24px;\n font-size: 12px;\n right: 10px;\n}\n}"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}
|