@tnotesjs/core 0.1.21 → 0.1.22

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 (47) hide show
  1. package/dist/{chunk-4MO7F7Q4.js → chunk-BSTQOJVE.js} +1 -1
  2. package/dist/{chunk-SQVHJR2Z.js → chunk-O4DCXHOV.js} +0 -3
  3. package/dist/cli/index.js +2 -2
  4. package/dist/index.js +1 -1
  5. package/dist/vitepress/config/index.js +2 -2
  6. package/package.json +3 -4
  7. package/types/config.ts +0 -1
  8. package/vitepress/components/CodeBlockFullscreen/CodeBlockFullscreen.vue +2 -2
  9. package/vitepress/components/CodeBlockFullscreen/index.ts +1 -5
  10. package/vitepress/components/Discussions/Discussions.vue +37 -4
  11. package/vitepress/components/EnWordList/EnWordList.vue +135 -15
  12. package/vitepress/components/EnWordList/RightClickMenu.vue +33 -10
  13. package/vitepress/components/Footprints/Footprints.vue +105 -10
  14. package/vitepress/components/Layout/AboutModal.vue +242 -16
  15. package/vitepress/components/Layout/AboutPanel.vue +258 -44
  16. package/vitepress/components/Layout/ContentCollapse.vue +1 -14
  17. package/vitepress/components/Layout/DocBeforeControls.vue +221 -19
  18. package/vitepress/components/Layout/ImagePreview.vue +212 -9
  19. package/vitepress/components/Layout/Layout.vue +133 -10
  20. package/vitepress/components/Layout/NavBarSettingsTrigger.vue +0 -2
  21. package/vitepress/components/Layout/SidebarNavBefore.vue +0 -1
  22. package/vitepress/components/Layout/SidebarResizeHandle.vue +2 -10
  23. package/vitepress/components/Layout/ToggleFullContent.vue +14 -2
  24. package/vitepress/components/Layout/ToggleSidebar.vue +14 -3
  25. package/vitepress/components/LoadingPage/LoadingPage.vue +1 -6
  26. package/vitepress/components/MarkMap/MarkMap.vue +162 -3
  27. package/vitepress/components/Mermaid/Mermaid.vue +300 -22
  28. package/vitepress/components/NotesTable/NotesTable.vue +86 -10
  29. package/vitepress/components/Settings/Settings.vue +434 -57
  30. package/vitepress/components/Settings/SettingsDialog.vue +1 -11
  31. package/vitepress/components/SidebarCard/MindMapView.vue +28 -28
  32. package/vitepress/components/SidebarCard/SidebarCard.vue +3 -4
  33. package/vitepress/components/Tooltip/Tooltip.vue +28 -28
  34. package/vitepress/configs/markdown.config.ts +3 -2
  35. package/vitepress/components/Discussions/Discussions.module.scss +0 -32
  36. package/vitepress/components/EnWordList/EnWordList.module.scss +0 -124
  37. package/vitepress/components/EnWordList/RightClickMenu.module.scss +0 -22
  38. package/vitepress/components/Footprints/Footprints.module.scss +0 -93
  39. package/vitepress/components/Layout/AboutModal.module.scss +0 -233
  40. package/vitepress/components/Layout/ImagePreview.module.scss +0 -201
  41. package/vitepress/components/Layout/Layout.module.scss +0 -661
  42. package/vitepress/components/Layout/ToggleFullContent.module.scss +0 -11
  43. package/vitepress/components/Layout/ToggleSidebar.module.scss +0 -11
  44. package/vitepress/components/MarkMap/MarkMap.module.scss +0 -159
  45. package/vitepress/components/Mermaid/Mermaid.module.scss +0 -275
  46. package/vitepress/components/NotesTable/NotesTable.module.scss +0 -77
  47. package/vitepress/components/Settings/Settings.module.scss +0 -375
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ConfigManager,
3
3
  getConfigManager
4
- } from "./chunk-SQVHJR2Z.js";
4
+ } from "./chunk-O4DCXHOV.js";
5
5
 
6
6
  // utils/errorHandler.ts
7
7
  var TNotesError = class _TNotesError extends Error {
@@ -57,21 +57,18 @@ function getDefaultConfig(repoName) {
57
57
  // 社交链接
58
58
  socialLinks: [
59
59
  {
60
- ariaLabel: "Tdahuyou \u8BED\u96C0\u4E3B\u9875\u94FE\u63A5",
61
60
  link: "https://www.yuque.com/tdahuyou",
62
61
  icon: {
63
62
  svg: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M17.28 2.955c2.97.203 3.756 2.342 3.84 2.597l1.297.096c.13 0 .169.18.054.236c-1.323.716-1.727 2.17-1.49 3.118c.09.358.254.69.412 1.02c.307.642.651 1.418.707 2.981c.117 3.24-2.51 6.175-5.789 6.593c1.17-1.187 1.815-2.444 2.12-3.375c.606-1.846.508-3.316.055-4.44a4.46 4.46 0 0 0-1.782-2.141c-1.683-1.02-3.22-1.09-4.444-.762c.465-.594.876-1.201 1.2-1.864c.584-1.65-.102-2.848-.704-3.519c-.192-.246-.061-.655.305-.655c1.41 0 2.813.02 4.22.115M3.32 19.107c1.924-2.202 4.712-5.394 7.162-8.15c.559-.63 2.769-2.338 5.748-.533c.878.532 2.43 2.165 1.332 5.51c-.803 2.446-4.408 7.796-15.76 5.844c-.227-.039-.511-.354-.218-.687z"/></svg>'
64
63
  }
65
64
  },
66
65
  {
67
- ariaLabel: "Tdahuyou B \u7AD9\u4E3B\u9875\u94FE\u63A5",
68
66
  link: "https://space.bilibili.com/407241004",
69
67
  icon: {
70
68
  svg: '<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024"><g fill="currentColor"><path d="M310.134 596.45c-7.999-4.463-16.498-8.43-24.997-11.9a274 274 0 0 0-26.996-7.438c-2.5-.992-2.5.991-2.5 1.487c0 7.934.5 18.843 1.5 27.768c1 7.438 2 15.372 4 22.81c0 .496 0 .991.5 1.487c.999.992 1.999 1.488 2.999.496c7.999-4.463 15.998-8.43 22.997-13.388c7.499-5.454 15.498-11.9 21.997-18.347c1.5-1.487 0-2.479.5-2.975m323.96-11.9a274 274 0 0 0-26.997-7.438c-2.5-.992-2.5.991-2.5 1.487c0 7.934.5 18.843 1.5 27.768c1 7.438 2 15.372 4 22.81c0 .496 0 .991.5 1.487c1 .992 2 1.488 3 .496c7.999-4.463 15.998-8.43 22.997-13.388c7.499-5.454 15.498-11.9 21.997-18.347c2-1.487.5-2.479.5-2.975c-7.5-4.463-16.498-8.43-24.997-11.9"/><path d="M741.496 112H283c-94.501 0-171 76.5-171 171.5v458c.5 94 77 170.5 170.999 170.5h457.997c94.5 0 171.002-76.5 171.002-170.5v-458c.497-95-76.002-171.5-170.502-171.5m95 343.5h15.5v48h-15.5zm-95.5-1.5l2 43l-13.5 1.5l-5-44.5zm-23.5 0l4 45.5l-14.5 1.5l-6.5-47.5h17zm-230.498 1.5h15v48h-15zm-96-1.5l2 43l-13.5 1.5l-5-44.5zm-23.5 0l4 45.5l-14.5 2l-6-47.5zm-3.5 149C343.498 668.5 216 662.5 204.5 660.5C195.5 499 181.5 464 170 385l54.5-22.5c1 71.5 9 185 9 185s108.5-15.5 132 47c.5 3 0 6-1.5 8.5m20.5 35.5l-23.5-124h35.5l13 123zm44.5-8l-27-235l33.5-1.5l21 236H429zm34-175h17.5v48H467zm41 190h-26.5l-9.5-126h36zm209.998-43C693.496 668 565.997 662 554.497 660c-9-161-23-196-34.5-275l54.5-22.5c1 71.5 9 185 9 185s108.5-15.5 132 46.5c.5 3 0 6-1.5 8.5m19.5 36l-23-124h35.5l13 123zm45.5-8l-27.5-235l33.5-1.5l21 236h-27zm33.5-175h17.5v48h-13zm41 190h-26.5l-9.5-126h36z"/></g></svg>'
71
69
  }
72
70
  },
73
71
  {
74
- ariaLabel: `${name} github \u4ED3\u5E93\u94FE\u63A5`,
75
72
  link: `https://github.com/tnotesjs/${name}`,
76
73
  icon: "github"
77
74
  }
package/dist/cli/index.js CHANGED
@@ -22,10 +22,10 @@ import {
22
22
  parseArgs,
23
23
  parseReadmeCompletedNotes,
24
24
  runCommand
25
- } from "../chunk-4MO7F7Q4.js";
25
+ } from "../chunk-BSTQOJVE.js";
26
26
  import {
27
27
  ConfigManager
28
- } from "../chunk-SQVHJR2Z.js";
28
+ } from "../chunk-O4DCXHOV.js";
29
29
 
30
30
  // commands/update/UpdateCommand.ts
31
31
  import { existsSync, readFileSync, writeFileSync } from "fs";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ConfigManager,
3
3
  getConfigManager
4
- } from "./chunk-SQVHJR2Z.js";
4
+ } from "./chunk-O4DCXHOV.js";
5
5
  export {
6
6
  ConfigManager,
7
7
  getConfigManager
@@ -7,8 +7,8 @@ import {
7
7
  UpdateNoteConfigCommand,
8
8
  generateAnchor,
9
9
  logger
10
- } from "../../chunk-4MO7F7Q4.js";
11
- import "../../chunk-SQVHJR2Z.js";
10
+ } from "../../chunk-BSTQOJVE.js";
11
+ import "../../chunk-O4DCXHOV.js";
12
12
 
13
13
  // vitepress/config/index.ts
14
14
  import fs2 from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tnotesjs/core",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "TNotes 知识库核心框架 —— 基于 VitePress 的笔记管理系统",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.17.1",
@@ -62,14 +62,13 @@
62
62
  "@eslint/js": "^9.39.4",
63
63
  "@types/markdown-it": "^14.1.2",
64
64
  "@types/node": "^24.6.2",
65
- "@typescript-eslint/parser": "^8.59.0",
66
65
  "eslint": "^9.39.4",
67
66
  "eslint-plugin-import": "^2.32.0",
68
67
  "eslint-plugin-vue": "^10.9.0",
69
- "globals": "^17.5.0",
68
+ "globals": "^17.6.0",
70
69
  "tsup": "^8.5.1",
71
70
  "typescript": "^5.9.3",
72
- "typescript-eslint": "^8.59.0",
71
+ "typescript-eslint": "^8.59.1",
73
72
  "vue-eslint-parser": "^10.4.0",
74
73
  "vue-tsc": "^3.2.7"
75
74
  },
package/types/config.ts CHANGED
@@ -33,7 +33,6 @@ export interface IconConfig {
33
33
  * 社交链接类型
34
34
  */
35
35
  export interface SocialLink {
36
- ariaLabel?: string
37
36
  icon: string | IconConfig
38
37
  link: string
39
38
  }
@@ -17,7 +17,7 @@
17
17
  <div class="code-fullscreen-actions">
18
18
  <!-- 旋转按钮(仅移动端) -->
19
19
  <button
20
- class="action-btn rotate-btn mobile-only"
20
+ class="action-btn mobile-only"
21
21
  @click="toggleOrientation"
22
22
  :title="isLandscape ? '切换为竖屏' : '切换为横屏'"
23
23
  >
@@ -25,7 +25,7 @@
25
25
  </button>
26
26
  <!-- 复制按钮 -->
27
27
  <button
28
- class="action-btn copy-btn"
28
+ class="action-btn"
29
29
  @click="copyCode"
30
30
  :title="copied ? '已复制' : '复制代码'"
31
31
  >
@@ -7,7 +7,7 @@ type CopyState = 'idle' | 'copied' | 'failed'
7
7
 
8
8
  const CODE_BLOCK_SELECTOR = 'div[class*="language-"]'
9
9
  const CODE_ACTIONS_CLASS = 'tn-code-actions'
10
- const COPY_RESET_DELAY = 2000
10
+ const COPY_RESET_DELAY = 1000
11
11
 
12
12
  export function useCodeBlockFullscreen() {
13
13
  let fullscreenApp: any = null
@@ -28,7 +28,6 @@ export function useCodeBlockFullscreen() {
28
28
 
29
29
  const actions = document.createElement('div')
30
30
  actions.className = CODE_ACTIONS_CLASS
31
- actions.setAttribute('aria-label', '代码块操作')
32
31
 
33
32
  const fullscreenButton = createActionButton({
34
33
  className: 'tn-code-action-fullscreen',
@@ -65,7 +64,6 @@ export function useCodeBlockFullscreen() {
65
64
  button.className = `tn-code-action ${options.className}`
66
65
  button.type = 'button'
67
66
  button.title = options.title
68
- button.setAttribute('aria-label', options.title)
69
67
  button.innerHTML = `<img src="${options.icon}" alt="${options.alt}" />`
70
68
 
71
69
  return button
@@ -98,7 +96,6 @@ export function useCodeBlockFullscreen() {
98
96
  button.parentElement.dataset.copyState = state
99
97
  }
100
98
  button.title = getCopyTitle(state)
101
- button.setAttribute('aria-label', getCopyTitle(state))
102
99
 
103
100
  const icon = button.querySelector('img')
104
101
  if (icon) {
@@ -112,7 +109,6 @@ export function useCodeBlockFullscreen() {
112
109
  button.parentElement.dataset.copyState = 'idle'
113
110
  }
114
111
  button.title = getCopyTitle('idle')
115
- button.setAttribute('aria-label', getCopyTitle('idle'))
116
112
  icon?.setAttribute('src', icon__clipboard)
117
113
  icon?.setAttribute('alt', '复制')
118
114
  copyResetTimers.delete(button)
@@ -193,15 +193,15 @@ watch(isDark, (newVal) => {
193
193
  </script>
194
194
 
195
195
  <template>
196
- <h2 :class="$style.h2">
196
+ <h2 class="h2">
197
197
  <Tooltip text="在 GitHub 上发表评论(支持上传图片)">
198
198
  <a
199
199
  :href="githubDiscussionsUrl"
200
200
  target="_blank"
201
201
  rel="noopener noreferrer"
202
- :class="$style.discussionsLink"
202
+ class="discussionsLink"
203
203
  >
204
- <img :src="icon__github" alt="" :class="$style.githubIcon" />
204
+ <img :src="icon__github" alt="" class="githubIcon" />
205
205
  Discussions
206
206
  </a>
207
207
  </Tooltip>
@@ -209,4 +209,37 @@ watch(isDark, (newVal) => {
209
209
  <div id="giscus-comments"></div>
210
210
  </template>
211
211
 
212
- <style module src="./Discussions.module.scss"></style>
212
+ <style scoped lang="scss">
213
+ /* #region:same as vitepress theme */
214
+ .h2 {
215
+ margin: 48px 0 16px;
216
+ border-top: 1px solid var(--vp-c-divider);
217
+ padding-top: 24px;
218
+ letter-spacing: -0.02em;
219
+ line-height: 32px;
220
+ font-size: 1.2rem;
221
+ text-align: center;
222
+ }
223
+
224
+ /* #endregion:same as vitepress theme */
225
+
226
+ .discussionsLink {
227
+ display: inline-flex;
228
+ align-items: center;
229
+ gap: 0.5em;
230
+ color: var(--vp-c-brand-1);
231
+ text-decoration: none;
232
+ opacity: 0.9;
233
+ transition: opacity 0.25s;
234
+
235
+ &:hover {
236
+ opacity: 0.5;
237
+ }
238
+ }
239
+
240
+ .githubIcon {
241
+ width: 1em;
242
+ height: 1em;
243
+ flex-shrink: 0;
244
+ }
245
+ </style>
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
2
  import { marked } from 'marked'
3
- import { computed, ref, onMounted, onUnmounted, nextTick } from 'vue'
3
+ import { computed, ref, onMounted, onUnmounted, nextTick } from 'vue'
4
4
 
5
5
  import {
6
6
  EN_WORDS_REPO_BASE_URL,
@@ -448,17 +448,16 @@ onUnmounted(() => {
448
448
  </script>
449
449
 
450
450
  <template>
451
- <div :class="$style.enWordList">
451
+ <div class="enWordList">
452
452
  <ol>
453
453
  <li
454
454
  v-for="(word, index) in sortedWords"
455
455
  :key="word"
456
456
  :class="{
457
- [$style.pronounced]:
458
- isPronouncingAll && currentPronounceAllIndex === index + 1,
457
+ pronounced: isPronouncingAll && currentPronounceAllIndex === index + 1,
459
458
  }"
460
459
  >
461
- <span :class="$style.index">{{ index + 1 }}.</span>
460
+ <span class="index">{{ index + 1 }}.</span>
462
461
  <input
463
462
  type="checkbox"
464
463
  :id="word"
@@ -471,8 +470,8 @@ onUnmounted(() => {
471
470
  word.toLowerCase().replaceAll(/\s/g, '_')
472
471
  )}.md`"
473
472
  :class="{
474
- [$style.lineThrough]: checkedStates[word],
475
- [$style.textRed]: failedWords[word],
473
+ lineThrough: checkedStates[word],
474
+ textRed: failedWords[word],
476
475
  }"
477
476
  @mouseenter="(e) => isAutoShowCard && showWordCard(e, word)"
478
477
  @mouseleave="handleMouseLeave"
@@ -486,18 +485,18 @@ onUnmounted(() => {
486
485
  </ol>
487
486
 
488
487
  <div
489
- :class="$style.wordCard"
488
+ class="wordCard"
490
489
  :style="{ left: cardX + 'px', top: cardY + 'px' }"
491
490
  v-if="showCard"
492
491
  >
493
- <div :class="$style.wordCardContent" v-html="cardContent"></div>
492
+ <div class="wordCardContent" v-html="cardContent"></div>
494
493
  </div>
495
494
 
496
495
  <!-- pinned cards -->
497
496
  <div
498
497
  v-for="card in pinnedCards"
499
498
  :key="card.id"
500
- :class="$style.wordCard"
499
+ class="wordCard"
501
500
  :style="{
502
501
  left: card.x + 'px',
503
502
  top: card.y + 'px',
@@ -508,14 +507,14 @@ onUnmounted(() => {
508
507
  @mousedown="(e) => startDrag(card, e)"
509
508
  @click="bringToFront(card)"
510
509
  >
511
- <div :class="$style.wordCardContentWrapper">
512
- <div :class="$style.wordCardContent" v-html="card.content"></div>
510
+ <div class="wordCardContentWrapper">
511
+ <div class="wordCardContent" v-html="card.content"></div>
513
512
  </div>
514
- <button :class="$style.closeBtn" @click.stop="removeCard(card.id)">
513
+ <button class="closeBtn" @click.stop="removeCard(card.id)">
515
514
 
516
515
  </button>
517
516
  <div
518
- :class="$style.resizeHandle"
517
+ class="resizeHandle"
519
518
  @mousedown.stop="startResize(card, $event)"
520
519
  ></div>
521
520
  </div>
@@ -541,4 +540,125 @@ onUnmounted(() => {
541
540
  />
542
541
  </template>
543
542
 
544
- <style module src="./EnWordList.module.scss"></style>
543
+ <style scoped lang="scss">
544
+ /* EnWordList 组件样式 */
545
+
546
+ .enWordList {
547
+ // Checkbox 样式
548
+ input[type='checkbox'] {
549
+ margin: 8px;
550
+ transform: scale(1.3);
551
+ cursor: pointer;
552
+ }
553
+
554
+ // 链接样式
555
+ a {
556
+ text-decoration: none;
557
+ color: #4fc3f7;
558
+
559
+ &:hover {
560
+ text-decoration: underline !important;
561
+ }
562
+
563
+ &.lineThrough {
564
+ color: #999;
565
+ text-decoration: line-through;
566
+ }
567
+
568
+ &.textRed {
569
+ color: #f40 !important;
570
+ }
571
+ }
572
+
573
+ // 单词列表样式
574
+ ol {
575
+ list-style-type: decimal;
576
+ padding-left: 20px;
577
+
578
+ li {
579
+ display: flex;
580
+ align-items: center;
581
+ margin-bottom: 8px;
582
+ transition: all 0.3s ease;
583
+
584
+ &.pronounced {
585
+ background-color: rgba(255, 255, 0, 0.1);
586
+ }
587
+ }
588
+ }
589
+
590
+ // 序号样式
591
+ .index {
592
+ margin-right: 10px;
593
+ color: #aaa;
594
+ }
595
+ }
596
+
597
+ // 单词卡片样式(🌑 暗色悬浮卡片)
598
+ .wordCard {
599
+ position: fixed;
600
+ z-index: 9999;
601
+ background: #1e1e1e;
602
+ border: 1px solid #333;
603
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
604
+ padding: 12px 16px;
605
+ max-width: 600px;
606
+ min-width: 200px;
607
+ min-height: 100px;
608
+ font-size: 14px;
609
+ line-height: 1.4;
610
+ border-radius: 8px;
611
+ color: #eee;
612
+ pointer-events: auto;
613
+ font-family: sans-serif;
614
+ cursor: move;
615
+
616
+ // 关闭按钮
617
+ .closeBtn {
618
+ position: absolute;
619
+ right: 5px;
620
+ top: 5px;
621
+ background: none;
622
+ border: none;
623
+ font-size: 16px;
624
+ cursor: pointer;
625
+ color: #ccc;
626
+
627
+ &:hover {
628
+ color: white;
629
+ }
630
+ }
631
+ }
632
+
633
+ // 卡片内容包裹器
634
+ .wordCardContentWrapper {
635
+ width: 100%;
636
+ height: 100%;
637
+ overflow: auto;
638
+ }
639
+
640
+ // 卡片内容样式
641
+ .wordCardContent {
642
+ :deep(ul) {
643
+ margin: 0.5rem 0;
644
+ padding-left: 1rem;
645
+ }
646
+ }
647
+
648
+ // 调整大小手柄
649
+ .resizeHandle {
650
+ position: absolute;
651
+ right: 0;
652
+ bottom: 0;
653
+ width: 12px;
654
+ height: 12px;
655
+ background-color: #666;
656
+ cursor: nwse-resize;
657
+ z-index: 2;
658
+ border-radius: 50%;
659
+
660
+ &:hover {
661
+ background-color: #aaa;
662
+ }
663
+ }
664
+ </style>
@@ -1,33 +1,33 @@
1
1
  <template>
2
2
  <div
3
3
  v-if="show"
4
- :class="$style.rightClickMenu"
4
+ class="rightClickMenu"
5
5
  :style="{ left: x + 'px', top: y + 'px' }"
6
6
  >
7
- <div :class="$style.menuItem" @click="handlePin">📌 Pin</div>
8
- <div :class="$style.menuItem" @click="(e) => handlePronounce(e, 'en-GB')">
7
+ <div class="menuItem" @click="handlePin">📌 Pin</div>
8
+ <div class="menuItem" @click="(e) => handlePronounce(e, 'en-GB')">
9
9
  📢 Pronounce(英)
10
10
  </div>
11
- <div :class="$style.menuItem" @click="(e) => handlePronounce(e, 'en-US')">
11
+ <div class="menuItem" @click="(e) => handlePronounce(e, 'en-US')">
12
12
  📢 Pronounce(美)
13
13
  </div>
14
14
  <div
15
- :class="$style.menuItem"
15
+ class="menuItem"
16
16
  @click="(e) => handlePronounceAll(e, 'en-GB')"
17
17
  >
18
18
  📢 Pronounce All(英)
19
19
  </div>
20
20
  <div
21
- :class="$style.menuItem"
21
+ class="menuItem"
22
22
  @click="(e) => handlePronounceAll(e, 'en-US')"
23
23
  >
24
24
  📢 Pronounce All(美)
25
25
  </div>
26
- <div :class="$style.menuItem" @click="handleAutoShowCard">
26
+ <div class="menuItem" @click="handleAutoShowCard">
27
27
  🔍 Auto Show Card({{ isAutoShowCard ? '关' : '开' }})
28
28
  </div>
29
- <div :class="$style.menuItem" @click="handleCheckAll">✅ Check All</div>
30
- <div :class="$style.menuItem" @click="handleReset">❌ Reset</div>
29
+ <div class="menuItem" @click="handleCheckAll">✅ Check All</div>
30
+ <div class="menuItem" @click="handleReset">❌ Reset</div>
31
31
  </div>
32
32
  </template>
33
33
 
@@ -63,4 +63,27 @@ const handleReset = () => {
63
63
  }
64
64
  </script>
65
65
 
66
- <style module src="./RightClickMenu.module.scss"></style>
66
+ <style scoped lang="scss">
67
+ // RightClickMenu 组件样式
68
+
69
+ .rightClickMenu {
70
+ position: fixed;
71
+ z-index: 99999;
72
+ background: #2c2c2c;
73
+ border: 1px solid #444;
74
+ border-radius: 6px;
75
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
76
+ font-size: 13px;
77
+ color: #eee;
78
+ cursor: pointer;
79
+ user-select: none;
80
+ }
81
+
82
+ .menuItem {
83
+ padding: 8px 16px;
84
+
85
+ &:hover {
86
+ background-color: #444;
87
+ }
88
+ }
89
+ </style>
@@ -331,23 +331,24 @@ const formattedTime = computed(() => {
331
331
  </script>
332
332
 
333
333
  <template>
334
- <div :class="$style.textContainer">
334
+ <div class="textContainer">
335
335
  <div
336
- :class="[$style.textContent, { [$style.collapsed]: isCollapsed }]"
336
+ class="textContent"
337
+ :class="{ collapsed: isCollapsed }"
337
338
  ref="textContainer"
338
339
  >
339
340
  <slot name="text-area"></slot>
340
341
  </div>
341
342
  <button
342
343
  v-if="isExpandable"
343
- :class="$style.toggleButton"
344
+ class="toggleButton"
344
345
  @click="toggleCollapse"
345
346
  >
346
347
  {{ isCollapsed ? '全文' : '收起' }}
347
348
  </button>
348
349
  </div>
349
350
 
350
- <div :class="$style.imageContainer" ref="imageContainer">
351
+ <div class="imageContainer" ref="imageContainer">
351
352
  <slot
352
353
  name="image-list"
353
354
  :openModal="openModal"
@@ -356,22 +357,116 @@ const formattedTime = computed(() => {
356
357
  :isModalVisible="isModalVisible"
357
358
  ></slot>
358
359
  </div>
359
- <div :class="$style.modal" v-show="isModalVisible" @click.self="closeModal">
360
- <span :class="$style.close" @click="closeModal">&times;</span>
360
+ <div class="modal" v-show="isModalVisible" @click.self="closeModal">
361
+ <span class="close" @click="closeModal">&times;</span>
361
362
  <img
362
- :class="[$style.modalContent, `__dynamic__modal-content-${instanceId}`]"
363
+ :class="['modalContent', `__dynamic__modal-content-${instanceId}`]"
363
364
  :src="currentImage"
364
365
  alt="Preview"
365
366
  @mousedown="handleMouseDown"
366
367
  />
367
368
  </div>
368
369
 
369
- <div :class="$style.timeContainer">
370
+ <div class="timeContainer">
370
371
  <p>{{ formattedTime }}</p>
371
372
  </div>
372
- <div :class="$style.otherInfoContainer">
373
+ <div class="otherInfoContainer">
373
374
  <slot name="other-info"></slot>
374
375
  </div>
375
376
  </template>
376
377
 
377
- <style module src="./Footprints.module.scss"></style>
378
+ <style scoped lang="scss">
379
+ // Footprints 组件样式
380
+
381
+ // 其他信息容器和时间容器
382
+ .otherInfoContainer,
383
+ .timeContainer {
384
+ font-size: 0.8rem;
385
+ color: gray;
386
+ }
387
+
388
+ // 文本容器
389
+ .textContainer {
390
+ position: relative;
391
+ margin-bottom: 1rem;
392
+ }
393
+
394
+ // 文本内容
395
+ .textContent {
396
+ overflow: hidden;
397
+ transition: max-height 0.3s ease;
398
+
399
+ // 折叠状态:隐藏从第三个开始的所有一级子元素
400
+ &.collapsed > :nth-child(n + 3) {
401
+ display: none;
402
+ }
403
+ }
404
+
405
+ // 切换按钮
406
+ .toggleButton {
407
+ display: block;
408
+ margin-top: 0.5rem;
409
+ background-color: transparent;
410
+ color: #007bff;
411
+ border: none;
412
+ cursor: pointer;
413
+ text-align: left;
414
+ font-size: 1rem;
415
+
416
+ &:hover {
417
+ text-decoration: underline;
418
+ }
419
+ }
420
+
421
+ // 图片容器
422
+ .imageContainer {
423
+ display: flex;
424
+ width: 100%;
425
+ flex-wrap: wrap;
426
+
427
+ img {
428
+ width: calc(33.33% - 10px);
429
+ aspect-ratio: 1; // 设置宽高比为 1:1
430
+ object-fit: cover;
431
+ cursor: pointer;
432
+ margin: 0.3rem;
433
+ }
434
+ }
435
+
436
+ // 模态框
437
+ .modal {
438
+ display: flex;
439
+ position: fixed;
440
+ z-index: 1000;
441
+ left: 0;
442
+ top: 0;
443
+ width: 100%;
444
+ height: 100%;
445
+ overflow: auto;
446
+ background-color: rgba(0, 0, 0, 1);
447
+ align-items: center;
448
+ justify-content: center;
449
+ }
450
+
451
+ // 模态框内容(图片)
452
+ .modalContent {
453
+ position: absolute;
454
+ top: 50%;
455
+ left: 50%;
456
+ transform: translate(-50%, -50%);
457
+ max-width: 90%;
458
+ max-height: 90%;
459
+ cursor: grab;
460
+ }
461
+
462
+ // 关闭按钮
463
+ .close {
464
+ position: absolute;
465
+ top: 20px;
466
+ right: 30px;
467
+ color: white;
468
+ font-size: 30px;
469
+ font-weight: bold;
470
+ cursor: pointer;
471
+ }
472
+ </style>