@tnotesjs/core 0.1.15 → 0.1.17

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 (117) hide show
  1. package/README.md +87 -87
  2. package/dist/{chunk-FVKQPBPP.js → chunk-4MO7F7Q4.js} +2005 -1769
  3. package/dist/cli/index.js +1 -1
  4. package/dist/vitepress/config/index.js +212 -4
  5. package/package.json +1 -1
  6. package/types/config.ts +61 -61
  7. package/types/index.ts +11 -11
  8. package/types/note.ts +33 -33
  9. package/vitepress/assets/icons/icon__check.svg +3 -3
  10. package/vitepress/assets/icons/icon__clipboard.svg +7 -7
  11. package/vitepress/assets/icons/icon__close.svg +1 -1
  12. package/vitepress/assets/icons/icon__collapse.svg +1 -1
  13. package/vitepress/assets/icons/icon__confirm.svg +1 -1
  14. package/vitepress/assets/icons/icon__copy.svg +4 -4
  15. package/vitepress/assets/icons/icon__focus.svg +1 -1
  16. package/vitepress/assets/icons/icon__fold.svg +3 -3
  17. package/vitepress/assets/icons/icon__folder.svg +1 -1
  18. package/vitepress/assets/icons/icon__fullscreen.svg +1 -1
  19. package/vitepress/assets/icons/icon__fullscreen_exit.svg +1 -1
  20. package/vitepress/assets/icons/icon__github.svg +3 -3
  21. package/vitepress/assets/icons/icon__mindmap.svg +1 -1
  22. package/vitepress/assets/icons/icon__next.svg +1 -1
  23. package/vitepress/assets/icons/icon__number_gray.svg +1 -1
  24. package/vitepress/assets/icons/icon__number_purple.svg +1 -1
  25. package/vitepress/assets/icons/icon__prev.svg +1 -1
  26. package/vitepress/assets/icons/icon__restore.svg +1 -1
  27. package/vitepress/assets/icons/icon__rotate.svg +4 -4
  28. package/vitepress/assets/icons/icon__search.svg +1 -1
  29. package/vitepress/assets/icons/icon__sidebar_collapsed.svg +1 -1
  30. package/vitepress/assets/icons/icon__sidebar_opened.svg +1 -1
  31. package/vitepress/assets/icons/icon__totop.svg +5 -5
  32. package/vitepress/assets/icons/icon__vscode.svg +5 -5
  33. package/vitepress/assets/icons/icon__zoom_fit.svg +1 -1
  34. package/vitepress/assets/icons/icon__zoom_in.svg +1 -1
  35. package/vitepress/assets/icons/icon__zoom_out.svg +1 -1
  36. package/vitepress/assets/icons/icon__zoom_reset.svg +1 -1
  37. package/vitepress/assets/icons/index.ts +39 -39
  38. package/vitepress/components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue +20 -20
  39. package/vitepress/components/CodeBlockFullscreen/CodeBlockFullscreen.vue +373 -373
  40. package/vitepress/components/CodeBlockFullscreen/index.ts +115 -115
  41. package/vitepress/components/CodeBlockFullscreen/styles.css +64 -64
  42. package/vitepress/components/Discussions/Discussions.module.scss +32 -32
  43. package/vitepress/components/Discussions/Discussions.vue +211 -211
  44. package/vitepress/components/EnWordList/EnWordList.module.scss +124 -124
  45. package/vitepress/components/EnWordList/EnWordList.vue +543 -543
  46. package/vitepress/components/EnWordList/RightClickMenu.module.scss +22 -22
  47. package/vitepress/components/EnWordList/RightClickMenu.vue +66 -66
  48. package/vitepress/components/Footprints/Footprints.module.scss +93 -93
  49. package/vitepress/components/Footprints/Footprints.vue +377 -377
  50. package/vitepress/components/Layout/AboutModal.module.scss +233 -233
  51. package/vitepress/components/Layout/AboutModal.vue +105 -105
  52. package/vitepress/components/Layout/AboutPanel.vue +270 -270
  53. package/vitepress/components/Layout/ContentCollapse.vue +603 -603
  54. package/vitepress/components/Layout/CustomSidebar.vue +817 -608
  55. package/vitepress/components/Layout/DocBeforeControls.vue +149 -149
  56. package/vitepress/components/Layout/DocFooter.vue +233 -233
  57. package/vitepress/components/Layout/ImagePreview.module.scss +201 -201
  58. package/vitepress/components/Layout/ImagePreview.vue +281 -281
  59. package/vitepress/components/Layout/Layout.module.scss +661 -661
  60. package/vitepress/components/Layout/Layout.vue +621 -559
  61. package/vitepress/components/Layout/NoteStatus.vue +140 -140
  62. package/vitepress/components/Layout/SidebarItems.vue +1083 -268
  63. package/vitepress/components/Layout/SidebarNavBefore.vue +171 -108
  64. package/vitepress/components/Layout/SidebarResizeHandle.vue +319 -0
  65. package/vitepress/components/Layout/Swiper.vue +167 -167
  66. package/vitepress/components/Layout/ToggleFullContent.module.scss +11 -11
  67. package/vitepress/components/Layout/ToggleFullContent.vue +35 -35
  68. package/vitepress/components/Layout/ToggleSidebar.module.scss +11 -11
  69. package/vitepress/components/Layout/ToggleSidebar.vue +26 -36
  70. package/vitepress/components/Layout/composables/useCollapseControl.ts +88 -88
  71. package/vitepress/components/Layout/composables/useNoteConfig.ts +119 -119
  72. package/vitepress/components/Layout/composables/useNoteSave.ts +178 -178
  73. package/vitepress/components/Layout/composables/useNoteValidation.ts +85 -85
  74. package/vitepress/components/Layout/composables/useRedirect.ts +113 -113
  75. package/vitepress/components/Layout/composables/useSidebarLayout.ts +122 -0
  76. package/vitepress/components/Layout/composables/useVSCodeIntegration.ts +85 -85
  77. package/vitepress/components/Layout/homeReadme.data.ts +124 -124
  78. package/vitepress/components/MarkMap/MarkMap.module.scss +159 -159
  79. package/vitepress/components/MarkMap/MarkMap.vue +405 -405
  80. package/vitepress/components/Mermaid/Mermaid.module.scss +275 -275
  81. package/vitepress/components/Mermaid/Mermaid.vue +365 -365
  82. package/vitepress/components/NotesTable/NotesTable.module.scss +77 -77
  83. package/vitepress/components/NotesTable/NotesTable.vue +98 -98
  84. package/vitepress/components/NotesTable/README.md +67 -67
  85. package/vitepress/components/Settings/Settings.module.scss +375 -433
  86. package/vitepress/components/Settings/Settings.vue +333 -306
  87. package/vitepress/components/SidebarCard/MindMapView.vue +484 -484
  88. package/vitepress/components/SidebarCard/NotesTrendChart.vue +108 -108
  89. package/vitepress/components/SidebarCard/SidebarCard.vue +946 -946
  90. package/vitepress/components/Tooltip/Tooltip.vue +70 -70
  91. package/vitepress/components/constants.ts +109 -91
  92. package/vitepress/components/notesConfig.data.ts +73 -73
  93. package/vitepress/components/sidebar.data.ts +59 -59
  94. package/vitepress/components/tnotes-config.data.ts +21 -21
  95. package/vitepress/components/utils.ts +26 -26
  96. package/vitepress/config/index.ts +169 -167
  97. package/vitepress/configs/constants.ts +26 -26
  98. package/vitepress/configs/head.config.ts +25 -25
  99. package/vitepress/configs/index.ts +9 -9
  100. package/vitepress/configs/markdown-it.d.ts +23 -23
  101. package/vitepress/configs/markdown.config.ts +366 -366
  102. package/vitepress/configs/theme.config.ts +108 -108
  103. package/vitepress/plugins/buildProgressPlugin.ts +434 -434
  104. package/vitepress/plugins/getNoteByConfigIdPlugin.ts +107 -107
  105. package/vitepress/plugins/renameNotePlugin.ts +68 -68
  106. package/vitepress/plugins/sidebarStructurePlugin.ts +260 -0
  107. package/vitepress/plugins/updateConfigPlugin.ts +63 -63
  108. package/vitepress/theme/index.ts +137 -137
  109. package/vitepress/theme/styles/base.scss +51 -50
  110. package/vitepress/theme/styles/components/404.scss +31 -31
  111. package/vitepress/theme/styles/components/collapse.scss +185 -175
  112. package/vitepress/theme/styles/components/markmap.scss +101 -101
  113. package/vitepress/theme/styles/components/swiper.scss +255 -255
  114. package/vitepress/theme/styles/index.scss +25 -25
  115. package/vitepress/theme/styles/layout.scss +78 -62
  116. package/vitepress/theme/styles/utilities.scss +39 -39
  117. package/vitepress/theme/styles/vitepress-override.scss +25 -25
@@ -1,108 +1,171 @@
1
- <template>
2
- <div class="sidebar-toggle-wrapper">
3
- <div class="group group-left">
4
- <!-- 展开/折叠全部按钮 -->
5
- <button
6
- class="toggle-btn"
7
- @click="$emit('toggle-expand')"
8
- :title="isExpanded ? '全部折叠' : '全部展开'"
9
- >
10
- <img :src="icon__fold" class="toggle-icon" alt="切换展开折叠" />
11
- </button>
12
- <span class="group-label">目录</span>
13
- </div>
14
-
15
- <div class="group group-right">
16
- <!-- 聚焦到当前笔记按钮 -->
17
- <button
18
- class="toggle-btn"
19
- @click="$emit('focus-current')"
20
- title="聚焦到当前笔记(点击切换多个位置)"
21
- >
22
- <img :src="icon__focus" class="toggle-icon" alt="聚焦当前笔记" />
23
- </button>
24
-
25
- <!-- 笔记编号显示切换按钮 -->
26
- <button
27
- class="toggle-btn"
28
- @click="$emit('toggle-note-id')"
29
- :title="showNoteId ? '隐藏笔记编号' : '显示笔记编号'"
30
- >
31
- <img
32
- :src="showNoteId ? icon__number_purple : icon__number_gray"
33
- class="toggle-icon"
34
- alt="切换笔记编号"
35
- />
36
- </button>
37
- </div>
38
- </div>
39
- </template>
40
-
41
- <script setup lang="ts">
42
- import { icon__fold, icon__number_purple, icon__number_gray, icon__focus } from '../../assets/icons'
43
-
44
- defineProps<{
45
- isExpanded: boolean
46
- showNoteId: boolean
47
- }>()
48
-
49
- defineEmits<{
50
- 'toggle-expand': []
51
- 'toggle-note-id': []
52
- 'focus-current': []
53
- }>()
54
- </script>
55
-
56
- <style scoped>
57
- .sidebar-toggle-wrapper {
58
- display: flex;
59
- align-items: center;
60
- justify-content: space-between;
61
- padding: 12px 8px 16px;
62
- border-bottom: 1px solid var(--vp-c-divider);
63
- margin-bottom: 16px;
64
- }
65
-
66
- .group {
67
- display: flex;
68
- align-items: center;
69
- gap: 4px;
70
- }
71
-
72
- .group-label {
73
- font-size: 13px;
74
- color: var(--vp-c-text-2);
75
- user-select: none;
76
- }
77
-
78
- .toggle-btn {
79
- display: inline-flex;
80
- align-items: center;
81
- justify-content: center;
82
- padding: 8px;
83
- cursor: pointer;
84
- background: transparent;
85
- border: none;
86
- border-radius: 6px;
87
- transition: all 0.2s ease;
88
- }
89
-
90
- .toggle-btn:hover {
91
- background: var(--vp-c-bg-soft);
92
- }
93
-
94
- .toggle-btn:active .toggle-icon {
95
- transform: scale(0.95);
96
- }
97
-
98
- .toggle-icon {
99
- width: 20px;
100
- height: 20px;
101
- display: block;
102
- transition: transform 0.2s ease;
103
- }
104
-
105
- .toggle-btn:hover .toggle-icon {
106
- transform: scale(1.1);
107
- }
108
- </style>
1
+ <template>
2
+ <div class="sidebar-toggle-wrapper">
3
+ <div class="toolbar-row">
4
+ <div class="group group-left">
5
+ <!-- 展开/折叠全部按钮 -->
6
+ <button
7
+ class="toggle-btn"
8
+ @click="$emit('toggle-expand')"
9
+ :title="isExpanded ? '全部折叠' : '全部展开'"
10
+ >
11
+ <img :src="icon__fold" class="toggle-icon" alt="切换展开折叠" />
12
+ </button>
13
+ <a
14
+ :class="[
15
+ 'group-label',
16
+ 'group-label-link',
17
+ { 'is-active': isCatalogActive },
18
+ ]"
19
+ :href="catalogLink"
20
+ :aria-current="isCatalogActive ? 'page' : undefined"
21
+ >
22
+ 目录
23
+ </a>
24
+ </div>
25
+
26
+ <div class="group group-right">
27
+ <!-- 聚焦到当前笔记按钮 -->
28
+ <button
29
+ class="toggle-btn"
30
+ @click="$emit('focus-current')"
31
+ title="聚焦到当前笔记(点击切换多个位置)"
32
+ >
33
+ <img :src="icon__focus" class="toggle-icon" alt="聚焦当前笔记" />
34
+ </button>
35
+
36
+ <!-- 笔记编号显示切换按钮 -->
37
+ <button
38
+ class="toggle-btn"
39
+ @click="$emit('toggle-note-id')"
40
+ :title="showNoteId ? '隐藏笔记编号' : '显示笔记编号'"
41
+ >
42
+ <img
43
+ :src="showNoteId ? icon__number_purple : icon__number_gray"
44
+ class="toggle-icon"
45
+ alt="切换笔记编号"
46
+ />
47
+ </button>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </template>
52
+
53
+ <script setup lang="ts">
54
+ import { useData, useRoute } from 'vitepress'
55
+ import { computed } from 'vue'
56
+
57
+ import {
58
+ icon__fold,
59
+ icon__number_purple,
60
+ icon__number_gray,
61
+ icon__focus,
62
+ } from '../../assets/icons'
63
+
64
+ defineProps<{
65
+ isExpanded: boolean
66
+ showNoteId: boolean
67
+ }>()
68
+
69
+ defineEmits<{
70
+ 'toggle-expand': []
71
+ 'toggle-note-id': []
72
+ 'focus-current': []
73
+ }>()
74
+
75
+ const { site } = useData()
76
+ const route = useRoute()
77
+
78
+ const base = computed(() => site.value.base || '/')
79
+ const catalogLink = computed(() => `${base.value}README`)
80
+ const catalogPath = computed(() => normalizeRoutePath(catalogLink.value))
81
+ const isCatalogActive = computed(() => {
82
+ const currentPath = normalizeRoutePath(route.path)
83
+
84
+ return currentPath === catalogPath.value || currentPath === '/README'
85
+ })
86
+
87
+ function normalizeRoutePath(path: string): string {
88
+ const normalizedPath = path.split(/[?#]/)[0].replace(/\.html$/, '')
89
+
90
+ return normalizedPath.length > 1
91
+ ? normalizedPath.replace(/\/$/, '')
92
+ : normalizedPath
93
+ }
94
+ </script>
95
+
96
+ <style scoped>
97
+ .sidebar-toggle-wrapper {
98
+ position: sticky;
99
+ top: 0;
100
+ z-index: 2;
101
+ display: flex;
102
+ flex-direction: column;
103
+ gap: 8px;
104
+ padding: 10px 8px 12px;
105
+ /* border-bottom: 1px solid var(--vp-c-divider); */
106
+ margin-bottom: 10px;
107
+ background: var(--vp-sidebar-bg-color, var(--vp-c-bg));
108
+ }
109
+
110
+ .toolbar-row {
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: space-between;
114
+ gap: 8px;
115
+ }
116
+
117
+ .group {
118
+ display: flex;
119
+ align-items: center;
120
+ gap: 4px;
121
+ }
122
+
123
+ .group-label {
124
+ font-size: 13px;
125
+ color: var(--vp-c-text-2);
126
+ text-decoration: none;
127
+ user-select: none;
128
+ }
129
+
130
+ .group-label-link:hover {
131
+ color: var(--vp-c-brand-1);
132
+ }
133
+
134
+ .group-label-link.is-active {
135
+ color: var(--vp-c-brand-1);
136
+ font-weight: 600;
137
+ }
138
+
139
+ .toggle-btn {
140
+ display: inline-flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ width: 30px;
144
+ height: 30px;
145
+ padding: 0;
146
+ cursor: pointer;
147
+ background: transparent;
148
+ border: none;
149
+ border-radius: 6px;
150
+ transition: all 0.2s ease;
151
+ }
152
+
153
+ .toggle-btn:hover {
154
+ background: var(--vp-c-bg-soft);
155
+ }
156
+
157
+ .toggle-btn:active .toggle-icon {
158
+ transform: scale(0.95);
159
+ }
160
+
161
+ .toggle-icon {
162
+ width: 18px;
163
+ height: 18px;
164
+ display: block;
165
+ transition: transform 0.2s ease;
166
+ }
167
+
168
+ .toggle-btn:hover .toggle-icon {
169
+ transform: scale(1.1);
170
+ }
171
+ </style>
@@ -0,0 +1,319 @@
1
+ <template>
2
+ <div
3
+ class="sidebar-resize-handle"
4
+ :class="{
5
+ 'is-hidden': hidden,
6
+ 'is-dragging': isDragging,
7
+ 'is-fullscreen': isContentFullscreen,
8
+ }"
9
+ >
10
+ <div
11
+ v-if="!hidden"
12
+ class="resize-hotspot"
13
+ :aria-label="`拖动调整侧边栏宽度,当前 ${width}px`"
14
+ role="separator"
15
+ aria-orientation="vertical"
16
+ :aria-valuemin="minWidth"
17
+ :aria-valuemax="maxWidth"
18
+ :aria-valuenow="width"
19
+ @mousedown.prevent="startResize"
20
+ ></div>
21
+
22
+ <div v-if="!hidden" class="resize-indicator" aria-hidden="true"></div>
23
+
24
+ <button
25
+ class="sidebar-edge-toggle"
26
+ type="button"
27
+ :aria-label="toggleTitle"
28
+ :aria-pressed="hidden"
29
+ @click.stop="toggleSidebar"
30
+ >
31
+ <img :src="toggleIcon" alt="" />
32
+ <span class="sidebar-edge-tooltip" role="tooltip">
33
+ <span>{{ toggleActionText }}</span>
34
+ <kbd>{{ shortcutText }}</kbd>
35
+ </span>
36
+ </button>
37
+ </div>
38
+ </template>
39
+
40
+ <script setup lang="ts">
41
+ import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
42
+
43
+ import { icon__next, icon__prev } from '../../assets/icons'
44
+ import { useSidebarLayout } from './composables/useSidebarLayout'
45
+
46
+ const {
47
+ hidden,
48
+ width,
49
+ minWidth,
50
+ maxWidth,
51
+ initSidebarLayout,
52
+ toggleSidebar,
53
+ setSidebarWidth,
54
+ saveSidebarWidth,
55
+ } = useSidebarLayout()
56
+
57
+ const isDragging = ref(false)
58
+ const isContentFullscreen = ref(false)
59
+ const shortcutText = ref('Ctrl + Alt + ,')
60
+ let fullscreenObserver: MutationObserver | null = null
61
+
62
+ const toggleIcon = computed(() => (hidden.value ? icon__next : icon__prev))
63
+ const toggleActionText = computed(() =>
64
+ hidden.value ? '展开侧边栏' : '收起侧边栏',
65
+ )
66
+ const toggleTitle = computed(
67
+ () => `${toggleActionText.value}\n${shortcutText.value}`,
68
+ )
69
+
70
+ onMounted(() => {
71
+ initSidebarLayout()
72
+ shortcutText.value = getShortcutText()
73
+ updateContentFullscreen()
74
+ fullscreenObserver = new MutationObserver(updateContentFullscreen)
75
+ fullscreenObserver.observe(document.documentElement, {
76
+ attributes: true,
77
+ attributeFilter: ['class'],
78
+ })
79
+ window.addEventListener('keydown', handleShortcut)
80
+ })
81
+
82
+ onBeforeUnmount(() => {
83
+ window.removeEventListener('keydown', handleShortcut)
84
+ fullscreenObserver?.disconnect()
85
+ fullscreenObserver = null
86
+ stopResize()
87
+ })
88
+
89
+ function startResize(event: MouseEvent) {
90
+ if (hidden.value || event.button !== 0) return
91
+
92
+ isDragging.value = true
93
+ document.body.classList.add('is-sidebar-resizing')
94
+ window.addEventListener('mousemove', resize)
95
+ window.addEventListener('mouseup', stopResize)
96
+ setSidebarWidth(event.clientX)
97
+ }
98
+
99
+ function resize(event: MouseEvent) {
100
+ if (!isDragging.value) return
101
+
102
+ setSidebarWidth(event.clientX)
103
+ }
104
+
105
+ function stopResize() {
106
+ if (!isDragging.value) return
107
+
108
+ isDragging.value = false
109
+ document.body.classList.remove('is-sidebar-resizing')
110
+ window.removeEventListener('mousemove', resize)
111
+ window.removeEventListener('mouseup', stopResize)
112
+ saveSidebarWidth()
113
+ }
114
+
115
+ function handleShortcut(event: KeyboardEvent) {
116
+ if (!isToggleShortcut(event) || isEditableTarget(event.target)) return
117
+
118
+ event.preventDefault()
119
+ toggleSidebar()
120
+ }
121
+
122
+ function updateContentFullscreen() {
123
+ isContentFullscreen.value =
124
+ document.documentElement.classList.contains('content-fullscreen')
125
+ }
126
+
127
+ function isToggleShortcut(event: KeyboardEvent): boolean {
128
+ return (
129
+ (event.ctrlKey || event.metaKey) && event.altKey && event.code === 'Comma'
130
+ )
131
+ }
132
+
133
+ function getShortcutText(): string {
134
+ return isMacPlatform() ? 'Cmd + Option + ,' : 'Ctrl + Alt + ,'
135
+ }
136
+
137
+ function isMacPlatform(): boolean {
138
+ if (typeof navigator === 'undefined') return false
139
+
140
+ return /Mac|iPhone|iPad|iPod/i.test(navigator.platform)
141
+ }
142
+
143
+ function isEditableTarget(target: EventTarget | null): boolean {
144
+ if (!(target instanceof HTMLElement)) return false
145
+
146
+ const tagName = target.tagName.toLowerCase()
147
+ if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
148
+ return true
149
+ }
150
+
151
+ return target.isContentEditable || !!target.closest('[contenteditable="true"]')
152
+ }
153
+ </script>
154
+
155
+ <style scoped>
156
+ .sidebar-resize-handle {
157
+ position: fixed;
158
+ top: 0;
159
+ bottom: 0;
160
+ left: calc(var(--tn-sidebar-width, 260px) - 5px);
161
+ z-index: 30;
162
+ width: 10px;
163
+ cursor: col-resize;
164
+ }
165
+
166
+ .sidebar-resize-handle::before {
167
+ position: absolute;
168
+ top: var(--vp-nav-height);
169
+ bottom: 0;
170
+ left: 4px;
171
+ width: 2px;
172
+ background: var(--vp-c-brand-1);
173
+ border-radius: 999px;
174
+ box-shadow: 0 0 0 1px var(--vp-c-brand-soft);
175
+ content: '';
176
+ opacity: 0;
177
+ pointer-events: none;
178
+ transition: opacity 0.18s ease;
179
+ }
180
+
181
+ .resize-hotspot {
182
+ position: absolute;
183
+ top: var(--vp-nav-height);
184
+ right: 0;
185
+ bottom: 0;
186
+ left: 0;
187
+ }
188
+
189
+ .resize-indicator {
190
+ position: absolute;
191
+ top: 50%;
192
+ left: 50%;
193
+ width: 4px;
194
+ height: 28px;
195
+ border-right: 1px solid var(--vp-c-brand-1);
196
+ border-left: 1px solid var(--vp-c-brand-1);
197
+ opacity: 0;
198
+ pointer-events: none;
199
+ transform: translate(-50%, -50%);
200
+ transition: opacity 0.18s ease;
201
+ }
202
+
203
+ .sidebar-edge-toggle {
204
+ position: absolute;
205
+ top: 220px;
206
+ left: -2px;
207
+ display: inline-flex;
208
+ align-items: center;
209
+ justify-content: center;
210
+ width: 14px;
211
+ height: 44px;
212
+ padding: 0;
213
+ color: var(--vp-c-text-2);
214
+ background: var(--vp-c-bg);
215
+ border: 1px solid var(--vp-c-divider);
216
+ border-radius: 7px;
217
+ box-shadow: var(--vp-shadow-2);
218
+ cursor: pointer;
219
+ opacity: 0;
220
+ pointer-events: none;
221
+ transition:
222
+ opacity 0.18s ease,
223
+ border-color 0.18s ease,
224
+ background-color 0.18s ease;
225
+ }
226
+
227
+ .sidebar-edge-toggle img {
228
+ width: 10px;
229
+ height: 10px;
230
+ }
231
+
232
+ .sidebar-edge-tooltip {
233
+ position: absolute;
234
+ top: 50%;
235
+ left: calc(100% + 8px);
236
+ display: flex;
237
+ flex-direction: column;
238
+ gap: 2px;
239
+ min-width: 128px;
240
+ padding: 7px 9px;
241
+ color: var(--vp-c-text-1);
242
+ background: var(--vp-c-bg-elv);
243
+ border: 1px solid var(--vp-c-divider);
244
+ border-radius: 6px;
245
+ box-shadow: var(--vp-shadow-2);
246
+ font-size: 12px;
247
+ line-height: 18px;
248
+ opacity: 0;
249
+ pointer-events: none;
250
+ text-align: left;
251
+ transform: translate(2px, -50%);
252
+ transition:
253
+ opacity 0.16s ease,
254
+ transform 0.16s ease;
255
+ white-space: nowrap;
256
+ }
257
+
258
+ .sidebar-edge-tooltip kbd {
259
+ color: var(--vp-c-text-2);
260
+ font-family: var(--vp-font-family-mono);
261
+ font-size: 11px;
262
+ }
263
+
264
+ .sidebar-edge-toggle:hover .sidebar-edge-tooltip,
265
+ .sidebar-edge-toggle:focus-visible .sidebar-edge-tooltip {
266
+ opacity: 1;
267
+ transform: translate(0, -50%);
268
+ }
269
+
270
+ .sidebar-resize-handle:hover::before,
271
+ .sidebar-resize-handle.is-dragging::before,
272
+ .sidebar-resize-handle:hover .resize-indicator,
273
+ .sidebar-resize-handle.is-dragging .resize-indicator,
274
+ .sidebar-resize-handle:hover .sidebar-edge-toggle,
275
+ .sidebar-resize-handle.is-dragging .sidebar-edge-toggle,
276
+ .sidebar-resize-handle.is-hidden .sidebar-edge-toggle {
277
+ opacity: 1;
278
+ pointer-events: auto;
279
+ }
280
+
281
+ .sidebar-edge-toggle:hover {
282
+ color: var(--vp-c-brand-1);
283
+ background: var(--vp-c-bg-soft);
284
+ border-color: var(--vp-c-brand-1);
285
+ }
286
+
287
+ .sidebar-resize-handle.is-hidden {
288
+ left: 0;
289
+ width: 14px;
290
+ cursor: default;
291
+ }
292
+
293
+ .sidebar-resize-handle.is-hidden::before,
294
+ .sidebar-resize-handle.is-hidden .resize-indicator {
295
+ display: none;
296
+ }
297
+
298
+ .sidebar-resize-handle.is-hidden .sidebar-edge-toggle {
299
+ left: 0;
300
+ border-left-color: var(--vp-c-divider);
301
+ border-radius: 0 7px 7px 0;
302
+ }
303
+
304
+ :global(body.is-sidebar-resizing),
305
+ :global(body.is-sidebar-resizing *) {
306
+ cursor: col-resize !important;
307
+ user-select: none !important;
308
+ }
309
+
310
+ .sidebar-resize-handle.is-fullscreen {
311
+ display: none;
312
+ }
313
+
314
+ @media (max-width: 959px) {
315
+ .sidebar-resize-handle {
316
+ display: none;
317
+ }
318
+ }
319
+ </style>