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
@@ -1,44 +0,0 @@
1
- export type QiuLoadingEffect =
2
- | 'spinner'
3
- | 'dual-ring'
4
- | 'crescent'
5
- | 'gradient'
6
- | 'dash'
7
- | 'dots'
8
- | 'wave'
9
- | 'bounce'
10
- | 'bars'
11
- | 'bricks'
12
- | 'square'
13
- | 'flip'
14
- | 'pulse'
15
- | 'ripple'
16
- | 'orbit'
17
- | 'radar'
18
- | 'spiral'
19
- | 'infinity'
20
- | 'hourglass'
21
- | 'skeleton'
22
-
23
- export const QIU_LOADING_EFFECTS: QiuLoadingEffect[] = [
24
- 'spinner',
25
- 'dual-ring',
26
- 'crescent',
27
- 'gradient',
28
- 'dash',
29
- 'dots',
30
- 'wave',
31
- 'bounce',
32
- 'bars',
33
- 'bricks',
34
- 'square',
35
- 'flip',
36
- 'pulse',
37
- 'ripple',
38
- 'orbit',
39
- 'radar',
40
- 'spiral',
41
- 'infinity',
42
- 'hourglass',
43
- 'skeleton',
44
- ]
@@ -1,299 +0,0 @@
1
- <template>
2
- <div class="qiu-mention" :class="[`qiu-mention--${size}`, { 'is-disabled': disabled }]">
3
- <textarea
4
- v-if="type === 'textarea'"
5
- ref="inputRef"
6
- class="qiu-mention__input"
7
- :value="modelValue"
8
- :rows="rows"
9
- :placeholder="placeholder"
10
- :disabled="disabled"
11
- @input="onInput"
12
- @keydown="onKeydown"
13
- @keyup="onKeyup"
14
- />
15
- <input
16
- v-else
17
- ref="inputRef"
18
- class="qiu-mention__input"
19
- :value="modelValue"
20
- :placeholder="placeholder"
21
- :disabled="disabled"
22
- @input="onInput"
23
- @keydown="onKeydown"
24
- @keyup="onKeyup"
25
- />
26
-
27
- <Teleport to="body">
28
- <div
29
- v-if="open"
30
- ref="panelRef"
31
- class="qiu-mention__panel"
32
- :style="panelStyle"
33
- >
34
- <ul class="qiu-mention__list">
35
- <li
36
- v-for="(opt, i) in filtered"
37
- :key="opt.value"
38
- class="qiu-mention__option"
39
- :class="{ 'is-active': i === activeIndex }"
40
- @mousedown.prevent="select(opt)"
41
- @mouseenter="activeIndex = i"
42
- >
43
- <span v-if="opt.avatar" class="qiu-mention__avatar">{{ opt.avatar }}</span>
44
- <span class="qiu-mention__label">{{ opt.label }}</span>
45
- </li>
46
- </ul>
47
- </div>
48
- </Teleport>
49
- </div>
50
- </template>
51
-
52
- <script lang="ts" setup>
53
- import { computed, nextTick, ref, watch } from 'vue'
54
-
55
- defineOptions({ name: 'QiuMention' })
56
-
57
- interface MentionOption {
58
- label: string
59
- value: string | number
60
- avatar?: string
61
- }
62
-
63
- const props = withDefaults(
64
- defineProps<{
65
- modelValue?: string
66
- options?: MentionOption[]
67
- triggerChar?: string
68
- placeholder?: string
69
- size?: 'small' | 'default' | 'large'
70
- disabled?: boolean
71
- type?: 'text' | 'textarea'
72
- rows?: number
73
- }>(),
74
- {
75
- modelValue: '',
76
- options: () => [],
77
- triggerChar: '@',
78
- placeholder: '输入 @ 提及他人',
79
- size: 'default',
80
- disabled: false,
81
- type: 'text',
82
- rows: 3,
83
- }
84
- )
85
-
86
- const emit = defineEmits<{
87
- 'update:modelValue': [string]
88
- select: [MentionOption]
89
- }>()
90
-
91
- const inputRef = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)
92
- const panelRef = ref<HTMLElement | null>(null)
93
- const open = ref(false)
94
- const activeIndex = ref(0)
95
- const keyword = ref('')
96
- const panelStyle = ref<Record<string, string>>({})
97
-
98
- const filtered = computed(() => {
99
- const q = keyword.value.toLowerCase()
100
- return props.options.filter((o) => o.label.toLowerCase().includes(q))
101
- })
102
-
103
- const onInput = (e: Event) => {
104
- const val = (e.target as HTMLInputElement).value
105
- emit('update:modelValue', val)
106
- detectKeyword(val, (e.target as HTMLInputElement).selectionStart ?? val.length)
107
- }
108
-
109
- const detectKeyword = (val: string, caret: number) => {
110
- const sub = val.slice(0, caret)
111
- const idx = sub.lastIndexOf(props.triggerChar)
112
- if (idx === -1) {
113
- open.value = false
114
- return
115
- }
116
- const seg = sub.slice(idx + 1)
117
- // 关键词不得包含空格
118
- if (/\s/.test(seg)) {
119
- open.value = false
120
- return
121
- }
122
- keyword.value = seg
123
- activeIndex.value = 0
124
- openPanel()
125
- }
126
-
127
- const openPanel = async () => {
128
- open.value = true
129
- await nextTick()
130
- updatePosition()
131
- }
132
-
133
- const updatePosition = () => {
134
- const input = inputRef.value
135
- const panel = panelRef.value
136
- if (!input || !panel) return
137
- const rect = input.getBoundingClientRect()
138
- const panelRect = panel.getBoundingClientRect()
139
- const gap = 4
140
- let top = rect.bottom + gap
141
- if (top + panelRect.height > window.innerHeight - 4) top = rect.top - panelRect.height - gap
142
- let left = Math.min(Math.max(4, rect.left), window.innerWidth - panelRect.width - 4)
143
- top = Math.max(4, top)
144
- panelStyle.value = {
145
- position: 'fixed',
146
- top: `${top}px`,
147
- left: `${left}px`,
148
- width: `${Math.max(rect.width, 180)}px`,
149
- zIndex: '2100',
150
- }
151
- }
152
-
153
- const insertMention = (opt: MentionOption) => {
154
- const input = inputRef.value
155
- if (!input) return
156
- const val = props.modelValue
157
- const caret = input.selectionStart ?? val.length
158
- const sub = val.slice(0, caret)
159
- const idx = sub.lastIndexOf(props.triggerChar)
160
- const before = val.slice(0, idx)
161
- const after = val.slice(caret)
162
- const insert = `${props.triggerChar}${opt.label} `
163
- const next = before + insert + after
164
- emit('update:modelValue', next)
165
- emit('select', opt)
166
- open.value = false
167
- nextTick(() => {
168
- const pos = (before + insert).length
169
- input.focus()
170
- input.setSelectionRange(pos, pos)
171
- })
172
- }
173
-
174
- const select = (opt: MentionOption) => insertMention(opt)
175
-
176
- const onKeydown = (e: KeyboardEvent) => {
177
- if (!open.value) return
178
- if (e.key === 'ArrowDown') {
179
- e.preventDefault()
180
- if (activeIndex.value < filtered.value.length - 1) activeIndex.value++
181
- } else if (e.key === 'ArrowUp') {
182
- e.preventDefault()
183
- if (activeIndex.value > 0) activeIndex.value--
184
- } else if (e.key === 'Enter') {
185
- e.preventDefault()
186
- const opt = filtered.value[activeIndex.value]
187
- if (opt) insertMention(opt)
188
- } else if (e.key === 'Escape') {
189
- open.value = false
190
- }
191
- }
192
-
193
- const onKeyup = (e: KeyboardEvent) => {
194
- if (['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) {
195
- const input = e.target as HTMLInputElement
196
- detectKeyword(input.value, input.selectionStart ?? 0)
197
- }
198
- }
199
-
200
- const onDocClick = (e: MouseEvent) => {
201
- if (!open.value) return
202
- if (panelRef.value?.contains(e.target as Node)) return
203
- open.value = false
204
- }
205
-
206
- watch(open, (v) => {
207
- if (v) document.addEventListener('mousedown', onDocClick, true)
208
- else document.removeEventListener('mousedown', onDocClick, true)
209
- })
210
-
211
- onBeforeUnmount(() => document.removeEventListener('mousedown', onDocClick, true))
212
- </script>
213
-
214
- <style lang="scss" scoped>
215
- .qiu-mention {
216
- display: inline-flex;
217
- width: 100%;
218
- max-width: 100%;
219
- vertical-align: middle;
220
-
221
- &.is-disabled {
222
- opacity: 0.6;
223
- pointer-events: none;
224
- }
225
- }
226
-
227
- .qiu-mention__input {
228
- box-sizing: border-box;
229
- width: 100%;
230
- padding: 6px 10px;
231
- font-size: 14px;
232
- font-family: inherit;
233
- line-height: 1.5;
234
- color: var(--qiu-text-color-primary, #303133);
235
- background: var(--qiu-bg-color, #fff);
236
- border: 1px solid var(--qiu-border-color, #dcdfe6);
237
- border-radius: var(--qiu-border-radius-base, 4px);
238
- outline: none;
239
- resize: vertical;
240
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
241
-
242
- &:focus {
243
- border-color: var(--qiu-color-primary, #409eff);
244
- box-shadow: 0 0 0 1px color-mix(in srgb, var(--qiu-color-primary, #409eff) 25%, transparent);
245
- }
246
-
247
- &::placeholder {
248
- color: var(--qiu-text-color-placeholder, #a8abb2);
249
- }
250
- }
251
-
252
- .qiu-mention__panel {
253
- box-sizing: border-box;
254
- max-height: 220px;
255
- overflow-y: auto;
256
- background: var(--qiu-bg-color-overlay, #fff);
257
- border: 1px solid var(--qiu-border-color-light, #e4e7ed);
258
- border-radius: var(--qiu-border-radius-base, 4px);
259
- box-shadow: var(--qiu-box-shadow-light, 0 4px 12px rgba(0, 0, 0, 0.1));
260
- }
261
-
262
- .qiu-mention__list {
263
- margin: 0;
264
- padding: 4px;
265
- list-style: none;
266
- }
267
-
268
- .qiu-mention__option {
269
- display: flex;
270
- align-items: center;
271
- gap: 8px;
272
- padding: 7px 10px;
273
- font-size: 14px;
274
- color: var(--qiu-text-color-regular, #606266);
275
- cursor: pointer;
276
- border-radius: 4px;
277
-
278
- &:hover,
279
- &.is-active {
280
- color: var(--qiu-color-primary, #409eff);
281
- background: var(--qiu-color-primary-light-9, #ecf5ff);
282
- }
283
- }
284
-
285
- .qiu-mention__avatar {
286
- display: inline-flex;
287
- align-items: center;
288
- justify-content: center;
289
- width: 22px;
290
- height: 22px;
291
- font-size: 12px;
292
- color: #fff;
293
- background: var(--qiu-color-primary, #409eff);
294
- border-radius: 50%;
295
- }
296
-
297
- .qiu-mention--small .qiu-mention__input { padding: 4px 8px; font-size: 13px; }
298
- .qiu-mention--large .qiu-mention__input { padding: 8px 12px; font-size: 15px; }
299
- </style>
@@ -1,241 +0,0 @@
1
- <template>
2
- <nav
3
- class="qiu-route-menu"
4
- :class="[
5
- `qiu-route-menu--${mode}`,
6
- {
7
- 'is-collapse': collapse,
8
- },
9
- ]"
10
- role="menu"
11
- >
12
- <ul class="qiu-route-menu__list">
13
- <slot />
14
- </ul>
15
- </nav>
16
- </template>
17
-
18
- <script lang="ts" setup>
19
- import type { QiuRouteMenuContext } from './context'
20
- import { QIU_ROUTE_MENU_KEY } from './context'
21
-
22
- defineOptions({ name: 'QiuMenuRoot' })
23
-
24
- const props = withDefaults(
25
- defineProps<{
26
- mode?: 'vertical' | 'horizontal'
27
- defaultActive?: string
28
- collapse?: boolean
29
- uniqueOpened?: boolean
30
- defaultOpeneds?: string[]
31
- menuTrigger?: 'click' | 'hover'
32
- }>(),
33
- {
34
- mode: 'vertical',
35
- defaultActive: '',
36
- collapse: false,
37
- uniqueOpened: false,
38
- defaultOpeneds: () => [],
39
- menuTrigger: 'click',
40
- }
41
- )
42
-
43
- const activeIndex = ref(props.defaultActive)
44
- const openSubs = ref<Set<string>>(new Set())
45
-
46
- watch(
47
- () => props.defaultActive,
48
- (val) => {
49
- if (val) activeIndex.value = val
50
- }
51
- )
52
-
53
- watch(
54
- () => [...props.defaultOpeneds],
55
- (paths) => {
56
- paths.forEach((path) => openSub(path))
57
- },
58
- { immediate: true }
59
- )
60
-
61
- const modeRef = computed(() => props.mode)
62
- const collapseRef = computed(() => props.collapse)
63
- const uniqueOpenedRef = computed(() => props.uniqueOpened)
64
- const menuTriggerRef = computed(() => props.menuTrigger)
65
- const activeIndexRef = computed(() => activeIndex.value)
66
-
67
- const isSubOpen = (index: string) => openSubs.value.has(index)
68
-
69
- const openSub = (index: string) => {
70
- // 收起/横向弹出:级联展开,仅保留祖先链 + 当前项(关闭同级其它分支)
71
- if (props.collapse || props.mode === 'horizontal') {
72
- const next = new Set<string>()
73
- for (const p of openSubs.value) {
74
- if (index === p || index.startsWith(`${p}/`)) next.add(p)
75
- }
76
- next.add(index)
77
- openSubs.value = next
78
- return
79
- }
80
- const next = new Set<string>()
81
- // 手风琴:仅垂直非折叠,保留当前项及其祖先链,关闭同级其它分支
82
- if (props.uniqueOpened && props.mode === 'vertical') {
83
- for (const p of openSubs.value) {
84
- if (index === p || index.startsWith(`${p}/`)) next.add(p)
85
- }
86
- } else {
87
- for (const p of openSubs.value) next.add(p)
88
- }
89
- next.add(index)
90
- openSubs.value = next
91
- }
92
-
93
- const closeSub = (index: string) => {
94
- const next = new Set<string>()
95
- for (const p of openSubs.value) {
96
- // 关闭自身及所有子孙(path 前缀)
97
- if (p === index || p.startsWith(`${index}/`)) continue
98
- next.add(p)
99
- }
100
- openSubs.value = next
101
- }
102
-
103
- const closeAll = () => {
104
- openSubs.value = new Set()
105
- }
106
-
107
- let flyoutLeaveTimer: ReturnType<typeof setTimeout> | null = null
108
-
109
- const isFlyoutHovering = () =>
110
- Boolean(
111
- document.querySelector('.qiu-menu-flyout-panel:hover') ||
112
- document.querySelector('.qiu-route-menu-sub.is-popup > .qiu-route-menu-sub__title:hover') ||
113
- document.querySelector('.qiu-route-menu.is-collapse .qiu-route-menu-sub__title:hover') ||
114
- document.querySelector('.qiu-route-menu--horizontal .qiu-route-menu-sub__title:hover') ||
115
- document.querySelector('.qiu-route-menu-item__tip:hover')
116
- )
117
-
118
- const enterFlyout = (index: string) => {
119
- if (flyoutLeaveTimer) {
120
- clearTimeout(flyoutLeaveTimer)
121
- flyoutLeaveTimer = null
122
- }
123
- openSub(index)
124
- }
125
-
126
- const leaveFlyout = () => {
127
- if (flyoutLeaveTimer) clearTimeout(flyoutLeaveTimer)
128
- // 横向向下展开时鼠标需穿过空隙,延迟略加长
129
- const delay = props.mode === 'horizontal' ? 280 : 160
130
- flyoutLeaveTimer = setTimeout(() => {
131
- if (isFlyoutHovering()) {
132
- flyoutLeaveTimer = null
133
- return
134
- }
135
- if (props.collapse || props.mode === 'horizontal') closeAll()
136
- flyoutLeaveTimer = null
137
- }, delay)
138
- }
139
-
140
- const toggleSub = (index: string) => {
141
- if (isSubOpen(index)) closeSub(index)
142
- else openSub(index)
143
- }
144
-
145
- const selectItem = (index: string) => {
146
- activeIndex.value = index
147
- }
148
-
149
- const isActive = (index: string) => {
150
- const active = activeIndex.value
151
- return active === index || active.startsWith(`${index}/`)
152
- }
153
-
154
- onBeforeUnmount(() => {
155
- if (flyoutLeaveTimer) clearTimeout(flyoutLeaveTimer)
156
- })
157
-
158
- provide<QiuRouteMenuContext>(QIU_ROUTE_MENU_KEY, {
159
- mode: modeRef as Ref<'vertical' | 'horizontal'>,
160
- collapse: collapseRef as Ref<boolean>,
161
- activeIndex: activeIndexRef as Ref<string>,
162
- uniqueOpened: uniqueOpenedRef as Ref<boolean>,
163
- menuTrigger: menuTriggerRef as Ref<'click' | 'hover'>,
164
- isSubOpen,
165
- toggleSub,
166
- openSub,
167
- closeSub,
168
- enterFlyout,
169
- leaveFlyout,
170
- selectItem,
171
- isActive,
172
- })
173
-
174
- defineExpose({
175
- open: openSub,
176
- close: closeSub,
177
- closeAll,
178
- })
179
- </script>
180
-
181
- <style lang="scss" scoped>
182
- .qiu-route-menu {
183
- width: 100%;
184
- background: var(--qiu-menu-background-color);
185
- border: 0;
186
-
187
- &__list {
188
- padding: 0;
189
- margin: 0;
190
- list-style: none;
191
- }
192
-
193
- &--horizontal {
194
- .qiu-route-menu__list {
195
- display: flex;
196
- flex-wrap: wrap;
197
- align-items: center;
198
- }
199
-
200
- /* 横向顶栏:避免 icon 容器裁切字形 */
201
- :deep(.qiu-route-menu-item__icon-wrap),
202
- :deep(.qiu-route-menu-sub__icon-wrap) {
203
- overflow: visible;
204
- }
205
-
206
- :deep(.qiu-route-menu-item__inner),
207
- :deep(.qiu-route-menu-sub__title) {
208
- overflow: visible;
209
- }
210
- }
211
-
212
- &.is-collapse {
213
- /* 收起:只留图标;文字/角标进右侧 tips,勿藏图标 wrap */
214
- :deep(.qiu-route-menu-item__text),
215
- :deep(.qiu-route-menu-item__badge),
216
- :deep(.qiu-route-menu-sub__text),
217
- :deep(.qiu-route-menu-sub__badge),
218
- :deep(.qiu-route-menu-sub__arrow),
219
- :deep(.qiu-route-menu-sub__more) {
220
- display: none !important;
221
- }
222
-
223
- :deep(.qiu-route-menu-item__inner),
224
- :deep(.qiu-route-menu-sub__title) {
225
- justify-content: center;
226
- padding: 0;
227
- }
228
-
229
- :deep(.qiu-route-menu-item__icon-wrap),
230
- :deep(.qiu-route-menu-sub__icon-wrap) {
231
- display: inline-flex !important;
232
- }
233
-
234
- :deep(.qiu-route-menu-item__tip) {
235
- /* tip 挂在侧栏外,保证不被 overflow 裁切 */
236
- position: fixed;
237
- /* left/top 由 JS 更稳,这里用 absolute 相对 li;侧栏需 overflow visible */
238
- }
239
- }
240
- }
241
- </style>