foucui 1.0.1 → 1.0.2

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.
Files changed (234) hide show
  1. package/dist/components/QiuCanvasKit/QiuCanvasEditor.vue.d.ts +3 -1
  2. package/dist/components/QiuCanvasKit/components/DataModulesPanel.vue.d.ts +1 -0
  3. package/dist/components/QiuTable/index.vue.d.ts +12 -12
  4. package/dist/foucui.css +1 -1
  5. package/dist/foucui.js +7476 -7373
  6. package/dist/foucui.umd.cjs +19 -19
  7. package/package.json +23 -13
  8. package/components/QiuAffix/index.vue +0 -186
  9. package/components/QiuAlert/index.vue +0 -208
  10. package/components/QiuAnchor/context.ts +0 -18
  11. package/components/QiuAnchor/index.vue +0 -180
  12. package/components/QiuAnchorLink/index.vue +0 -67
  13. package/components/QiuApp/index.vue +0 -9
  14. package/components/QiuAutocomplete/index.vue +0 -408
  15. package/components/QiuAvatar/index.vue +0 -140
  16. package/components/QiuBacktop/index.vue +0 -121
  17. package/components/QiuBadge/api/index.ts +0 -389
  18. package/components/QiuBadge/components/BadgeImagePickerDialog.vue +0 -243
  19. package/components/QiuBadge/components/BadgeLibraryManagerDialog.vue +0 -30
  20. package/components/QiuBadge/components/BadgeLibraryPanel.vue +0 -182
  21. package/components/QiuBadge/composables/useTableHostHeight.ts +0 -53
  22. package/components/QiuBadge/index.ts +0 -18
  23. package/components/QiuBadge/shared/BadgeTemplateRenderer.vue +0 -32
  24. package/components/QiuBadge/shared/assetUrl.ts +0 -26
  25. package/components/QiuBadge/shared/badgeTemplate.ts +0 -309
  26. package/components/QiuBadge/utils/chinaAreaData.ts +0 -44
  27. package/components/QiuBadge/utils/hostRegion.ts +0 -22
  28. package/components/QiuBadge/utils/pca-code.json +0 -1
  29. package/components/QiuBadge/utils/pdfFromElement.ts +0 -348
  30. package/components/QiuBadge/views/BadgeLibraryView.vue +0 -32
  31. package/components/QiuBadge/views/BadgeManageView.vue +0 -1364
  32. package/components/QiuBadge/views/BadgeTemplateEditorView.vue +0 -10
  33. package/components/QiuBadge/views/BadgeTemplateListView.vue +0 -229
  34. package/components/QiuBadge/views/DeskLabelTemplateListView.vue +0 -227
  35. package/components/QiuBadge/views/DeskLabelView.vue +0 -683
  36. package/components/QiuBadgeDot/index.vue +0 -87
  37. package/components/QiuButton/index.vue +0 -247
  38. package/components/QiuButtonGroup/index.vue +0 -63
  39. package/components/QiuCanvasKit/QiuCanvasEditor.vue +0 -5503
  40. package/components/QiuCanvasKit/QiuCanvasRenderer.vue +0 -348
  41. package/components/QiuCanvasKit/assetUrl.ts +0 -11
  42. package/components/QiuCanvasKit/components/DataModulesPanel.vue +0 -352
  43. package/components/QiuCanvasKit/export/html.ts +0 -132
  44. package/components/QiuCanvasKit/export/pdf.ts +0 -48
  45. package/components/QiuCanvasKit/export/png.ts +0 -50
  46. package/components/QiuCanvasKit/index.ts +0 -20
  47. package/components/QiuCanvasKit/modules/badgeCompat.ts +0 -84
  48. package/components/QiuCanvasKit/modules/dataRegistry.ts +0 -207
  49. package/components/QiuCanvasKit/modules/merge.ts +0 -71
  50. package/components/QiuCanvasKit/presets/badge.ts +0 -67
  51. package/components/QiuCanvasKit/presets/banner.ts +0 -79
  52. package/components/QiuCanvasKit/types.ts +0 -138
  53. package/components/QiuCard/index.vue +0 -104
  54. package/components/QiuCarousel/context.ts +0 -16
  55. package/components/QiuCarousel/index.vue +0 -343
  56. package/components/QiuCarouselItem/index.vue +0 -47
  57. package/components/QiuCascader/index.vue +0 -879
  58. package/components/QiuCascader/types.ts +0 -48
  59. package/components/QiuCheckbox/QiuCheckboxGroup.vue +0 -78
  60. package/components/QiuCheckbox/index.vue +0 -231
  61. package/components/QiuCheckbox/types.ts +0 -8
  62. package/components/QiuCode/index.vue +0 -64
  63. package/components/QiuCol/col.scss +0 -55
  64. package/components/QiuCol/index.vue +0 -64
  65. package/components/QiuCollapse/context.ts +0 -10
  66. package/components/QiuCollapse/index.vue +0 -70
  67. package/components/QiuCollapseItem/index.vue +0 -167
  68. package/components/QiuColorField/index.vue +0 -296
  69. package/components/QiuColorPicker/README.md +0 -118
  70. package/components/QiuColorPicker/index.vue +0 -60
  71. package/components/QiuColorfulCard/index.vue +0 -101
  72. package/components/QiuCombobox/index.vue +0 -277
  73. package/components/QiuConfigProvider/index.vue +0 -31
  74. package/components/QiuContextMenu/index.vue +0 -209
  75. package/components/QiuDate/index.vue +0 -1134
  76. package/components/QiuDescriptions/context.ts +0 -20
  77. package/components/QiuDescriptions/index.vue +0 -115
  78. package/components/QiuDescriptionsItem/index.vue +0 -103
  79. package/components/QiuDialog/index.vue +0 -828
  80. package/components/QiuDigitalCard/index.vue +0 -159
  81. package/components/QiuDivider/index.vue +0 -185
  82. package/components/QiuDot/index.vue +0 -83
  83. package/components/QiuDrawer/index.vue +0 -350
  84. package/components/QiuDropdown/QiuDropdownItem.vue +0 -74
  85. package/components/QiuDropdown/QiuDropdownMenu.vue +0 -22
  86. package/components/QiuDropdown/context.ts +0 -9
  87. package/components/QiuDropdown/index.vue +0 -189
  88. package/components/QiuEmpty/index.vue +0 -73
  89. package/components/QiuForm/index.vue +0 -172
  90. package/components/QiuForm/types.ts +0 -39
  91. package/components/QiuFormItem/index.vue +0 -276
  92. package/components/QiuFullscreen/index.vue +0 -11
  93. package/components/QiuGrid/index.vue +0 -408
  94. package/components/QiuHoverCard/index.vue +0 -192
  95. package/components/QiuIcon/index.vue +0 -117
  96. package/components/QiuIconPicker/iconify.libraries.ts +0 -182
  97. package/components/QiuIconPicker/icons.catalog.ts +0 -3072
  98. package/components/QiuIconPicker/index.vue +0 -488
  99. package/components/QiuImage/index.vue +0 -177
  100. package/components/QiuInput/index.vue +0 -328
  101. package/components/QiuInputNumber/index.vue +0 -295
  102. package/components/QiuInputOtp/index.vue +0 -190
  103. package/components/QiuKbd/index.vue +0 -57
  104. package/components/QiuLayoutContainer/index.vue +0 -50
  105. package/components/QiuLinkPreview/index.vue +0 -224
  106. package/components/QiuLoading/index.ts +0 -176
  107. package/components/QiuLoading/spinner.vue +0 -820
  108. package/components/QiuLoading/types.ts +0 -44
  109. package/components/QiuMention/index.vue +0 -299
  110. package/components/QiuMenu/QiuMenuRoot.vue +0 -241
  111. package/components/QiuMenu/components/QiuMenuItem.vue +0 -340
  112. package/components/QiuMenu/components/QiuSubMenu.vue +0 -504
  113. package/components/QiuMenu/context.ts +0 -21
  114. package/components/QiuMenu/index.vue +0 -43
  115. package/components/QiuMenuNav/QiuMenuNavItem.vue +0 -100
  116. package/components/QiuMenuNav/QiuMenuNavSub.vue +0 -120
  117. package/components/QiuMenuNav/context.ts +0 -14
  118. package/components/QiuMenuNav/index.vue +0 -148
  119. package/components/QiuMsg/QiuMsgItem.vue +0 -180
  120. package/components/QiuMsg/index.ts +0 -158
  121. package/components/QiuMsg/types.ts +0 -23
  122. package/components/QiuMsgBox/index.ts +0 -147
  123. package/components/QiuNotification/QiuNotificationItem.vue +0 -168
  124. package/components/QiuNotification/index.ts +0 -155
  125. package/components/QiuNotification/types.ts +0 -14
  126. package/components/QiuPage/index.vue +0 -12
  127. package/components/QiuPageHeader/index.vue +0 -115
  128. package/components/QiuPageMain/index.vue +0 -78
  129. package/components/QiuPagination/index.vue +0 -421
  130. package/components/QiuPasswordStrength/index.vue +0 -101
  131. package/components/QiuPopconfirm/index.vue +0 -196
  132. package/components/QiuPopover/index.vue +0 -277
  133. package/components/QiuProgress/index.vue +0 -235
  134. package/components/QiuQrcode/index.vue +0 -302
  135. package/components/QiuQueryForm/components/QiuQueryFormBottomPanel.vue +0 -13
  136. package/components/QiuQueryForm/components/QiuQueryFormLeftPanel.vue +0 -37
  137. package/components/QiuQueryForm/components/QiuQueryFormRightPanel.vue +0 -37
  138. package/components/QiuQueryForm/components/QiuQueryFormTopPanel.vue +0 -13
  139. package/components/QiuQueryForm/index.vue +0 -117
  140. package/components/QiuRadio/QiuRadioGroup.vue +0 -75
  141. package/components/QiuRadio/index.vue +0 -191
  142. package/components/QiuRadio/types.ts +0 -9
  143. package/components/QiuRate/index.vue +0 -184
  144. package/components/QiuRefresh/index.vue +0 -32
  145. package/components/QiuResult/index.vue +0 -103
  146. package/components/QiuRow/index.vue +0 -60
  147. package/components/QiuRow/types.ts +0 -5
  148. package/components/QiuScrollbar/index.vue +0 -107
  149. package/components/QiuSearchBar/index.vue +0 -154
  150. package/components/QiuSegmented/index.vue +0 -120
  151. package/components/QiuSelect/QiuOption.vue +0 -93
  152. package/components/QiuSelect/index.vue +0 -452
  153. package/components/QiuSelect/types.ts +0 -15
  154. package/components/QiuSkeleton/index.vue +0 -78
  155. package/components/QiuSlider/index.vue +0 -266
  156. package/components/QiuSpace/index.vue +0 -95
  157. package/components/QiuSparkline/index.vue +0 -92
  158. package/components/QiuStatistic/index.vue +0 -4
  159. package/components/QiuStatistics/index.vue +0 -123
  160. package/components/QiuStep/index.vue +0 -220
  161. package/components/QiuSteps/context.ts +0 -25
  162. package/components/QiuSteps/index.vue +0 -84
  163. package/components/QiuSwitch/index.vue +0 -145
  164. package/components/QiuTabBar/index.vue +0 -218
  165. package/components/QiuTabBar/types.ts +0 -19
  166. package/components/QiuTabPane/index.vue +0 -82
  167. package/components/QiuTable/columns.ts +0 -16
  168. package/components/QiuTable/export.ts +0 -102
  169. package/components/QiuTable/index.ts +0 -24
  170. package/components/QiuTable/index.vue +0 -3503
  171. package/components/QiuTable/registry.ts +0 -75
  172. package/components/QiuTable/styles/table.scss +0 -1230
  173. package/components/QiuTable/types.ts +0 -413
  174. package/components/QiuTable/useArea.ts +0 -202
  175. package/components/QiuTable/useColumns.ts +0 -325
  176. package/components/QiuTable/useEdit.ts +0 -136
  177. package/components/QiuTable/useExtras.ts +0 -115
  178. package/components/QiuTable/useHistory.ts +0 -77
  179. package/components/QiuTable/useMerge.ts +0 -105
  180. package/components/QiuTable/useResize.ts +0 -86
  181. package/components/QiuTable/useScrollSync.ts +0 -152
  182. package/components/QiuTable/useVirtual.ts +0 -97
  183. package/components/QiuTable/utils.ts +0 -165
  184. package/components/QiuTableColumn/index.vue +0 -101
  185. package/components/QiuTag/index.vue +0 -143
  186. package/components/QiuText/index.vue +0 -99
  187. package/components/QiuTime/index.vue +0 -548
  188. package/components/QiuTimeAgo/index.vue +0 -103
  189. package/components/QiuTimeline/index.vue +0 -54
  190. package/components/QiuTimelineItem/index.vue +0 -140
  191. package/components/QiuTips/index.vue +0 -323
  192. package/components/QiuTooltip/index.vue +0 -237
  193. package/components/QiuTransfer/index.vue +0 -277
  194. package/components/QiuTree/QiuTreeNode.vue +0 -146
  195. package/components/QiuTree/index.vue +0 -143
  196. package/components/QiuTree/types.ts +0 -30
  197. package/components/QiuTreeSelect/index.vue +0 -259
  198. package/components/QiuTrend/index.vue +0 -92
  199. package/components/QiuUpload/index.vue +0 -628
  200. package/components/QiuUploadCrop/index.vue +0 -1267
  201. package/components/QiuWatermark/index.vue +0 -121
  202. package/components/useBodyScrollLock.ts +0 -28
  203. package/dist/components/QiuBadge/utils/pca-code.json.d.ts +0 -3
  204. package/plugins/qiu.ts +0 -83
  205. package/plugins/shortcuts.ts +0 -69
  206. package/src/bridge/@/api/media.ts +0 -8
  207. package/src/bridge/@/api/notice.ts +0 -5
  208. package/src/bridge/@/config/index.ts +0 -38
  209. package/src/bridge/@/config/media.config.ts +0 -37
  210. package/src/bridge/@/config/security.config.ts +0 -8
  211. package/src/bridge/@/i18n/index.ts +0 -6
  212. package/src/bridge/@/store/modules/bing.ts +0 -9
  213. package/src/bridge/@/store/modules/errorLog.ts +0 -9
  214. package/src/bridge/@/store/modules/media.ts +0 -10
  215. package/src/bridge/@/store/modules/routes.ts +0 -10
  216. package/src/bridge/@/store/modules/settings.ts +0 -9
  217. package/src/bridge/@/store/modules/tabs.ts +0 -9
  218. package/src/bridge/@/store/modules/user.ts +0 -9
  219. package/src/bridge/@/utils/convertToCamelCase.ts +0 -11
  220. package/src/bridge/@/utils/index.ts +0 -9
  221. package/src/bridge/@/utils/pageTitle.ts +0 -4
  222. package/src/bridge/@/utils/routes.ts +0 -14
  223. package/src/bridge/@/utils/validate.ts +0 -17
  224. package/src/bridge/@qiu/plugins/shortcuts.ts +0 -3
  225. package/src/i18n.ts +0 -8
  226. package/src/icons/qiu-logo.svg +0 -1
  227. package/styles/dark.scss +0 -194
  228. package/styles/normalize.css +0 -349
  229. package/styles/plain.scss +0 -423
  230. package/styles/qiu-tokens.scss +0 -40
  231. package/styles/qiu.scss +0 -1149
  232. package/styles/technology.scss +0 -452
  233. package/styles/var.scss +0 -382
  234. package/styles/variables.scss +0 -77
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foucui",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "FouCui Vue3 组件库(原 qiuui-vue / qiuye,含 QiuCanvasKit 画布套件)",
5
5
  "type": "module",
6
6
  "main": "./dist/foucui.umd.cjs",
@@ -15,21 +15,13 @@
15
15
  "./dist/foucui.css": "./dist/foucui.css",
16
16
  "./dist/qiuye.css": "./dist/foucui.css",
17
17
  "./dist/qiuui-vue.css": "./dist/foucui.css",
18
- "./styles/*": "./styles/*",
19
- "./components/*": "./components/*",
20
- "./plugins/*": "./plugins/*"
18
+ "./package.json": "./package.json"
21
19
  },
22
20
  "files": [
23
- "dist",
24
- "styles",
25
- "components",
26
- "plugins",
27
- "src"
21
+ "dist"
28
22
  ],
29
23
  "sideEffects": [
30
- "**/*.scss",
31
- "**/*.css",
32
- "virtual:svg-icons-register"
24
+ "**/*.css"
33
25
  ],
34
26
  "scripts": {
35
27
  "build": "vite build",
@@ -41,6 +33,19 @@
41
33
  "vue-router": ">=4.0.0"
42
34
  },
43
35
  "dependencies": {
36
+ "@iconify-json/ant-design": "^1.2.5",
37
+ "@iconify-json/bi": "^1.2.2",
38
+ "@iconify-json/carbon": "^1.2.8",
39
+ "@iconify-json/ep": "^1.2.2",
40
+ "@iconify-json/flagpack": "^1.2.1",
41
+ "@iconify-json/icon-park": "^1.2.2",
42
+ "@iconify-json/icon-park-outline": "^1.2.2",
43
+ "@iconify-json/logos": "^1.2.4",
44
+ "@iconify-json/lucide": "^1.2.45",
45
+ "@iconify-json/mdi": "^1.2.3",
46
+ "@iconify-json/ph": "^1.2.2",
47
+ "@iconify-json/ri": "^1.2.5",
48
+ "@iconify-json/tabler": "^1.2.17",
44
49
  "@iconify/vue": "^4.1.2",
45
50
  "@vueuse/head": "^2.0.0",
46
51
  "axios": "^1.6.0",
@@ -71,6 +76,7 @@
71
76
  "vue": "^3.4.0",
72
77
  "vue-router": "^4.3.0"
73
78
  },
79
+ "author": "qiuye <yjk150@qq.com>",
74
80
  "license": "MIT",
75
81
  "keywords": [
76
82
  "vue3",
@@ -79,5 +85,9 @@
79
85
  "qiuui",
80
86
  "canvas",
81
87
  "badge"
82
- ]
88
+ ],
89
+ "publishConfig": {
90
+ "access": "public",
91
+ "registry": "https://registry.npmjs.org/"
92
+ }
83
93
  }
@@ -1,186 +0,0 @@
1
- <template>
2
- <div ref="rootRef" class="qiu-affix">
3
- <div
4
- v-if="fixed && !useSticky"
5
- class="qiu-affix__placeholder"
6
- :style="{ height: `${placeholderHeight}px` }"
7
- />
8
- <div
9
- ref="affixRef"
10
- class="qiu-affix__content"
11
- :class="{ 'is-fixed': fixed && !useSticky, 'is-sticky': useSticky }"
12
- :style="contentStyle"
13
- >
14
- <slot />
15
- </div>
16
- </div>
17
- </template>
18
-
19
- <script lang="ts" setup>
20
- defineOptions({ name: 'QiuAffix' })
21
-
22
- const props = withDefaults(
23
- defineProps<{
24
- offset?: number
25
- position?: 'top' | 'bottom'
26
- zIndex?: number
27
- /** 滚动容器选择器;指定后优先用 sticky(适合 overflow 容器) */
28
- target?: string
29
- }>(),
30
- {
31
- offset: 0,
32
- position: 'top',
33
- zIndex: 100,
34
- target: '',
35
- }
36
- )
37
-
38
- const emit = defineEmits<{
39
- change: [fixed: boolean]
40
- scroll: [payload: { scrollTop: number; fixed: boolean }]
41
- }>()
42
-
43
- const rootRef = ref<HTMLElement | null>(null)
44
- const affixRef = ref<HTMLElement | null>(null)
45
- const fixed = ref(false)
46
- const placeholderHeight = ref(0)
47
-
48
- /** 有 target 时用 sticky,天然适配 overflow 滚动容器 */
49
- const useSticky = computed(() => !!props.target)
50
-
51
- const getScrollContainer = (): HTMLElement | Window => {
52
- if (!props.target) return window
53
- const el = document.querySelector(props.target)
54
- return (el as HTMLElement) || window
55
- }
56
-
57
- const update = () => {
58
- if (useSticky.value) return
59
-
60
- const root = rootRef.value
61
- const affix = affixRef.value
62
- if (!root || !affix) return
63
-
64
- const container = getScrollContainer()
65
- const rootRect = root.getBoundingClientRect()
66
- placeholderHeight.value = affix.offsetHeight
67
-
68
- let next = false
69
- if (props.position === 'top') {
70
- // 仅判断是否滚过阈值;滚回时自动解除(勿再加与之矛盾的 bottom 条件)
71
- if (container === window) {
72
- next = rootRect.top <= props.offset
73
- } else {
74
- const cTop = (container as HTMLElement).getBoundingClientRect().top
75
- next = rootRect.top <= cTop + props.offset
76
- }
77
- } else if (container === window) {
78
- next = rootRect.bottom >= window.innerHeight - props.offset
79
- } else {
80
- const cBottom = (container as HTMLElement).getBoundingClientRect().bottom
81
- next = rootRect.bottom >= cBottom - props.offset
82
- }
83
-
84
- if (next !== fixed.value) {
85
- fixed.value = next
86
- emit('change', next)
87
- }
88
-
89
- const scrollTop =
90
- container === window
91
- ? window.scrollY || document.documentElement.scrollTop
92
- : (container as HTMLElement).scrollTop
93
- emit('scroll', { scrollTop, fixed: fixed.value })
94
- }
95
-
96
- const contentStyle = computed(() => {
97
- if (useSticky.value) {
98
- return {
99
- position: 'sticky',
100
- zIndex: String(props.zIndex),
101
- ...(props.position === 'top'
102
- ? { top: `${props.offset}px` }
103
- : { bottom: `${props.offset}px` }),
104
- } as Record<string, string>
105
- }
106
-
107
- if (!fixed.value) return undefined
108
-
109
- const container = getScrollContainer()
110
- const style: Record<string, string> = {
111
- position: 'fixed',
112
- zIndex: String(props.zIndex),
113
- width: `${rootRef.value?.offsetWidth ?? 0}px`,
114
- }
115
-
116
- if (props.position === 'top') {
117
- const top =
118
- container === window
119
- ? props.offset
120
- : (container as HTMLElement).getBoundingClientRect().top + props.offset
121
- style.top = `${top}px`
122
- } else {
123
- const bottom =
124
- container === window
125
- ? props.offset
126
- : window.innerHeight -
127
- (container as HTMLElement).getBoundingClientRect().bottom +
128
- props.offset
129
- style.bottom = `${bottom}px`
130
- }
131
-
132
- if (container !== window) {
133
- const rect = (container as HTMLElement).getBoundingClientRect()
134
- style.left = `${rect.left}px`
135
- style.width = `${rect.width}px`
136
- } else if (rootRef.value) {
137
- style.left = `${rootRef.value.getBoundingClientRect().left}px`
138
- }
139
-
140
- return style
141
- })
142
-
143
- let containerEl: HTMLElement | Window = window
144
-
145
- const onScroll = () => update()
146
- const onResize = () => update()
147
-
148
- const bind = () => {
149
- containerEl.removeEventListener('scroll', onScroll)
150
- window.removeEventListener('resize', onResize)
151
- if (useSticky.value) return
152
- containerEl = getScrollContainer()
153
- containerEl.addEventListener('scroll', onScroll, { passive: true })
154
- window.addEventListener('resize', onResize, { passive: true })
155
- update()
156
- }
157
-
158
- onMounted(() => {
159
- nextTick(bind)
160
- })
161
-
162
- onBeforeUnmount(() => {
163
- containerEl.removeEventListener('scroll', onScroll)
164
- window.removeEventListener('resize', onResize)
165
- })
166
-
167
- watch(
168
- () => [props.target, props.offset, props.position],
169
- () => nextTick(bind)
170
- )
171
-
172
- defineExpose({ update })
173
- </script>
174
-
175
- <style lang="scss" scoped>
176
- .qiu-affix {
177
- &__content {
178
- box-sizing: border-box;
179
-
180
- &.is-fixed,
181
- &.is-sticky {
182
- z-index: 10;
183
- }
184
- }
185
- }
186
- </style>
@@ -1,208 +0,0 @@
1
- <template>
2
- <div
3
- v-show="visible"
4
- class="qiu-alert"
5
- :class="[
6
- `qiu-alert--${normalizedType}`,
7
- `qiu-alert--${effect}`,
8
- { 'is-center': center },
9
- ]"
10
- role="alert"
11
- v-bind="$attrs"
12
- >
13
- <qiu-icon v-if="showIcon" class="qiu-alert__icon" :icon="typeIcon" />
14
- <div class="qiu-alert__content">
15
- <div v-if="title || $slots.title" class="qiu-alert__title">
16
- <slot name="title">{{ title }}</slot>
17
- </div>
18
- <div v-if="$slots.default || description" class="qiu-alert__description">
19
- <slot>{{ description }}</slot>
20
- </div>
21
- </div>
22
- <button
23
- v-if="closable"
24
- type="button"
25
- class="qiu-alert__close"
26
- :aria-label="closeText || 'Close'"
27
- @click="handleClose"
28
- >
29
- <span v-if="closeText">{{ closeText }}</span>
30
- <qiu-icon v-else icon="close-line" />
31
- </button>
32
- </div>
33
- </template>
34
-
35
- <script lang="ts" setup>
36
- defineOptions({
37
- name: 'QiuAlert',
38
- })
39
-
40
- const props = defineProps({
41
- title: {
42
- type: String,
43
- default: '',
44
- },
45
- description: {
46
- type: String,
47
- default: '',
48
- },
49
- type: {
50
- type: String as () => 'success' | 'warning' | 'info' | 'error' | 'danger',
51
- default: 'info',
52
- },
53
- closable: {
54
- type: Boolean,
55
- default: false,
56
- },
57
- closeText: {
58
- type: String,
59
- default: '',
60
- },
61
- showIcon: {
62
- type: Boolean,
63
- default: false,
64
- },
65
- center: {
66
- type: Boolean,
67
- default: false,
68
- },
69
- effect: {
70
- type: String as () => 'light' | 'dark',
71
- default: 'light',
72
- },
73
- })
74
-
75
- const emit = defineEmits<{
76
- close: []
77
- }>()
78
-
79
- const visible = ref(true)
80
-
81
- const normalizedType = computed(() => (props.type === 'danger' ? 'error' : props.type))
82
-
83
- const typeIcon = computed(() => {
84
- const map: Record<string, string> = {
85
- success: 'checkbox-circle-line',
86
- warning: 'error-warning-line',
87
- info: 'information-line',
88
- error: 'close-circle-line',
89
- }
90
- return map[normalizedType.value] || map.info
91
- })
92
-
93
- const handleClose = () => {
94
- visible.value = false
95
- emit('close')
96
- }
97
- </script>
98
-
99
- <style lang="scss" scoped>
100
- .qiu-alert {
101
- display: flex;
102
- gap: 8px;
103
- align-items: flex-start;
104
- width: 100%;
105
- padding: 8px 16px;
106
- margin: 0;
107
- overflow: hidden;
108
- border-radius: var(--qiu-border-radius-base, 4px);
109
- box-sizing: border-box;
110
- transition: opacity 0.2s ease;
111
-
112
- &.is-center {
113
- justify-content: center;
114
- text-align: center;
115
-
116
- .qiu-alert__content {
117
- flex: none;
118
- }
119
- }
120
-
121
- &--light {
122
- &.qiu-alert--success {
123
- color: var(--qiu-color-success);
124
- background-color: var(--qiu-color-success-light-9, #f0f9eb);
125
- }
126
-
127
- &.qiu-alert--warning {
128
- color: var(--qiu-color-warning);
129
- background-color: var(--qiu-color-warning-light-9, #fdf6ec);
130
- }
131
-
132
- &.qiu-alert--info {
133
- color: var(--qiu-color-info);
134
- background-color: var(--qiu-color-info-light-9, #f4f4f5);
135
- }
136
-
137
- &.qiu-alert--error {
138
- color: var(--qiu-color-error);
139
- background-color: var(--qiu-color-error-light-9, #fef0f0);
140
- }
141
- }
142
-
143
- &--dark {
144
- &.qiu-alert--success {
145
- color: #fff;
146
- background-color: var(--qiu-color-success);
147
- }
148
-
149
- &.qiu-alert--warning {
150
- color: #fff;
151
- background-color: var(--qiu-color-warning);
152
- }
153
-
154
- &.qiu-alert--info {
155
- color: #fff;
156
- background-color: var(--qiu-color-info);
157
- }
158
-
159
- &.qiu-alert--error {
160
- color: #fff;
161
- background-color: var(--qiu-color-error);
162
- }
163
- }
164
- }
165
-
166
- .qiu-alert__icon {
167
- flex-shrink: 0;
168
- margin-top: 2px;
169
- font-size: 16px;
170
- }
171
-
172
- .qiu-alert__content {
173
- flex: 1;
174
- min-width: 0;
175
- }
176
-
177
- .qiu-alert__title {
178
- font-size: 14px;
179
- font-weight: 700;
180
- line-height: 1.4;
181
- }
182
-
183
- .qiu-alert__description {
184
- margin: 4px 0 0;
185
- font-size: 13px;
186
- line-height: 1.6;
187
- }
188
-
189
- .qiu-alert__close {
190
- display: inline-flex;
191
- flex-shrink: 0;
192
- align-items: center;
193
- justify-content: center;
194
- padding: 0;
195
- margin: 0;
196
- font-size: 12px;
197
- color: inherit;
198
- cursor: pointer;
199
- background: transparent;
200
- border: none;
201
- opacity: 0.7;
202
- transition: opacity 0.2s ease;
203
-
204
- &:hover {
205
- opacity: 1;
206
- }
207
- }
208
- </style>
@@ -1,18 +0,0 @@
1
- import type { InjectionKey, Ref } from 'vue'
2
-
3
- export interface QiuAnchorLinkRecord {
4
- href: string
5
- title: string
6
- el: HTMLElement | null
7
- }
8
-
9
- export interface QiuAnchorContext {
10
- offset: Ref<number>
11
- bound: Ref<string>
12
- activeLink: Ref<string>
13
- registerLink: (link: QiuAnchorLinkRecord) => void
14
- unregisterLink: (href: string) => void
15
- scrollToLink: (href: string) => void
16
- }
17
-
18
- export const QIU_ANCHOR_KEY: InjectionKey<QiuAnchorContext> = Symbol('QiuAnchor')
@@ -1,180 +0,0 @@
1
- <template>
2
- <div class="qiu-anchor">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script lang="ts" setup>
8
- import type { QiuAnchorContext, QiuAnchorLinkRecord } from './context'
9
- import { QIU_ANCHOR_KEY } from './context'
10
-
11
- defineOptions({ name: 'QiuAnchor' })
12
-
13
- const props = withDefaults(
14
- defineProps<{
15
- offset?: number
16
- /** 滚动容器选择器 */
17
- bound?: string
18
- }>(),
19
- {
20
- offset: 0,
21
- bound: '',
22
- }
23
- )
24
-
25
- const links = ref<QiuAnchorLinkRecord[]>([])
26
- const activeLink = ref('')
27
-
28
- const isScrollable = (el: HTMLElement) => {
29
- const style = window.getComputedStyle(el)
30
- return /(auto|scroll)/.test(style.overflow + style.overflowY + style.overflowX)
31
- }
32
-
33
- const findScrollContainer = (el: Element): HTMLElement | Window => {
34
- let node: HTMLElement | null = el.parentElement
35
- while (node) {
36
- if (isScrollable(node)) return node
37
- node = node.parentElement
38
- }
39
- return window
40
- }
41
-
42
- const getScrollContainer = (target?: Element): HTMLElement | Window => {
43
- if (props.bound) {
44
- const el = document.querySelector(props.bound)
45
- return (el as HTMLElement) || window
46
- }
47
- if (target) return findScrollContainer(target)
48
- return window
49
- }
50
-
51
- const getScrollTop = (container: HTMLElement | Window) => {
52
- if (container === window) return window.scrollY || document.documentElement.scrollTop
53
- return (container as HTMLElement).scrollTop
54
- }
55
-
56
- const scrollToLink = (href: string) => {
57
- const id = href.replace(/^#/, '')
58
- const target = document.getElementById(id)
59
- if (!target) return
60
-
61
- const container = getScrollContainer(target)
62
- if (container === window) {
63
- const top = target.getBoundingClientRect().top + getScrollTop(window) - props.offset
64
- window.scrollTo({ top, behavior: 'smooth' })
65
- } else {
66
- const c = container as HTMLElement
67
- const cRect = c.getBoundingClientRect()
68
- const tRect = target.getBoundingClientRect()
69
- const top = tRect.top - cRect.top + c.scrollTop - props.offset
70
- c.scrollTo({ top, behavior: 'smooth' })
71
- }
72
- activeLink.value = href
73
- }
74
-
75
- const registerLink = (link: QiuAnchorLinkRecord) => {
76
- const idx = links.value.findIndex((l) => l.href === link.href)
77
- if (idx >= 0) links.value[idx] = link
78
- else links.value.push(link)
79
- links.value.sort((a, b) => {
80
- const elA = document.querySelector(a.href)
81
- const elB = document.querySelector(b.href)
82
- if (!elA || !elB) return 0
83
- return elA.getBoundingClientRect().top - elB.getBoundingClientRect().top
84
- })
85
- }
86
-
87
- const unregisterLink = (href: string) => {
88
- links.value = links.value.filter((l) => l.href !== href)
89
- }
90
-
91
- const resolveContainer = (): HTMLElement | Window => {
92
- if (props.bound) {
93
- const el = document.querySelector(props.bound)
94
- return (el as HTMLElement) || window
95
- }
96
- // 未指定 bound 时自动探测:以第一个锚点目标元素的可滚动祖先作为滚动容器
97
- for (const link of links.value) {
98
- const el = document.querySelector(link.href)
99
- if (el) return findScrollContainer(el)
100
- }
101
- return window
102
- }
103
-
104
- const updateActive = () => {
105
- const container = resolveContainer()
106
- const scrollTop = getScrollTop(container)
107
- const containerTop =
108
- container === window ? 0 : (container as HTMLElement).getBoundingClientRect().top
109
-
110
- let current = ''
111
- for (const link of links.value) {
112
- const id = link.href.replace(/^#/, '')
113
- const el = document.getElementById(id)
114
- if (!el) continue
115
- const top =
116
- container === window
117
- ? el.getBoundingClientRect().top + scrollTop
118
- : el.getBoundingClientRect().top - containerTop + scrollTop
119
- if (top - props.offset <= scrollTop + 1) current = link.href
120
- }
121
- if (current) activeLink.value = current
122
- }
123
-
124
- provide<QiuAnchorContext>(QIU_ANCHOR_KEY, {
125
- offset: toRef(props, 'offset'),
126
- bound: toRef(props, 'bound'),
127
- activeLink,
128
- registerLink,
129
- unregisterLink,
130
- scrollToLink,
131
- })
132
-
133
- let containerEl: HTMLElement | Window = window
134
-
135
- const onScroll = () => updateActive()
136
-
137
- const rebindScrollContainer = () => {
138
- const next = resolveContainer()
139
- if (next !== containerEl) {
140
- containerEl.removeEventListener('scroll', onScroll)
141
- containerEl = next
142
- containerEl.addEventListener('scroll', onScroll, { passive: true })
143
- }
144
- }
145
-
146
- onMounted(() => {
147
- containerEl = resolveContainer()
148
- containerEl.addEventListener('scroll', onScroll, { passive: true })
149
- updateActive()
150
- })
151
-
152
- onBeforeUnmount(() => {
153
- containerEl.removeEventListener('scroll', onScroll)
154
- })
155
-
156
- watch(
157
- () => props.bound,
158
- () => {
159
- rebindScrollContainer()
160
- updateActive()
161
- }
162
- )
163
-
164
- // 锚点链接注册完成后,若之前未探测到滚动容器则重新探测并切换事件监听
165
- watch(
166
- () => links.value.map((l) => l.href).join(','),
167
- () => {
168
- rebindScrollContainer()
169
- updateActive()
170
- },
171
- { flush: 'post' }
172
- )
173
- </script>
174
-
175
- <style lang="scss" scoped>
176
- .qiu-anchor {
177
- font-size: var(--qiu-font-size, 14px);
178
- line-height: 1.5;
179
- }
180
- </style>