vuepress-plugin-md-power 1.0.0-rc.101 → 1.0.0-rc.103

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.
@@ -68,15 +68,11 @@ function parseData(data: string | MessageData): MessageData {
68
68
  :data-past="past"
69
69
  :data-future="future"
70
70
  >
71
- <iframe
72
- :src="source"
73
- :style="{ height }"
74
- :title="`Can I use ${feature}`"
75
- />
71
+ <iframe :src="source" :style="{ height }" :title="`Can I use ${feature}`" />
76
72
  </div>
77
73
  </template>
78
74
 
79
- <style scoped>
75
+ <style>
80
76
  .ciu_embed {
81
77
  margin: 16px -24px;
82
78
  }
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
+ import type { HighlighterCore } from 'shiki/core'
2
3
  import editorData from '@internal/md-power/replEditorData'
3
- import { getHighlighterCore } from 'shiki/core'
4
+ import { createHighlighterCore } from 'shiki/core'
4
5
  import { onMounted, onUnmounted, ref, shallowRef, watch } from 'vue'
5
- import type { HighlighterCore } from 'shiki/core'
6
6
  import { resolveCodeInfo } from '../composables/codeRepl.js'
7
7
 
8
8
  let highlighter: HighlighterCore | null = null
@@ -17,7 +17,7 @@ const textAreaEl = shallowRef<HTMLTextAreaElement>()
17
17
  const input = ref('')
18
18
 
19
19
  async function init() {
20
- highlighter = await getHighlighterCore({
20
+ highlighter = await createHighlighterCore({
21
21
  themes: 'light' in theme && 'dark' in theme ? [theme.light, theme.dark] : [theme],
22
22
  langs: Object.keys(grammars).map(key => grammars[key]),
23
23
  loadWasm: () => import('shiki/wasm'),
@@ -1,10 +1,10 @@
1
1
  <script setup lang="ts">
2
2
  import { defineAsyncComponent, shallowRef } from 'vue'
3
3
  import { useCodeRepl } from '../composables/codeRepl.js'
4
- import IconClose from './IconClose.vue'
5
- import IconConsole from './IconConsole.vue'
6
- import IconRun from './IconRun.vue'
7
- import Loading from './Loading.vue'
4
+ import IconClose from './icons/IconClose.vue'
5
+ import IconConsole from './icons/IconConsole.vue'
6
+ import IconRun from './icons/IconRun.vue'
7
+ import Loading from './icons/Loading.vue'
8
8
 
9
9
  defineProps<{
10
10
  editable?: boolean
@@ -101,7 +101,7 @@ function runCode() {
101
101
  padding-top: 6px;
102
102
  margin: 0 -1.5rem;
103
103
  background-color: var(--vp-code-block-bg);
104
- transition: background-color var(--t-color);
104
+ transition: background-color var(--vp-t-color);
105
105
  }
106
106
 
107
107
  .code-repl-title {
@@ -111,7 +111,7 @@ function runCode() {
111
111
  margin: 0 -1.5rem;
112
112
  background-color: var(--vp-code-block-bg);
113
113
  border-bottom: solid 1px var(--vp-c-divider);
114
- transition: var(--t-color);
114
+ transition: var(--vp-t-color);
115
115
  transition-property: background, border;
116
116
  }
117
117
 
@@ -142,7 +142,7 @@ function runCode() {
142
142
  line-height: 48px;
143
143
  color: var(--vp-code-tab-active-text-color);
144
144
  white-space: nowrap;
145
- transition: color var(--t-color);
145
+ transition: color var(--vp-t-color);
146
146
  }
147
147
 
148
148
  .icon-run {
@@ -156,7 +156,7 @@ function runCode() {
156
156
  cursor: pointer;
157
157
  border: solid 1px var(--vp-c-text-3);
158
158
  border-radius: 100%;
159
- transition: var(--t-color);
159
+ transition: var(--vp-t-color);
160
160
  transition-property: color, border;
161
161
  }
162
162
 
@@ -171,7 +171,7 @@ function runCode() {
171
171
  justify-content: space-between;
172
172
  padding: 4px 10px 4px 20px;
173
173
  border-top: solid 2px var(--vp-c-divider);
174
- transition: border-color var(--t-color);
174
+ transition: border-color var(--vp-t-color);
175
175
  }
176
176
 
177
177
  .output-head .title {
@@ -184,7 +184,7 @@ function runCode() {
184
184
  .output-head .output-version {
185
185
  font-size: 12px;
186
186
  color: var(--vp-c-text-3);
187
- transition: color var(--t-color);
187
+ transition: color var(--vp-t-color);
188
188
  }
189
189
 
190
190
  .output-head .icon-close {
@@ -193,7 +193,7 @@ function runCode() {
193
193
  margin-left: 20px;
194
194
  color: var(--vp-c-text-3);
195
195
  cursor: pointer;
196
- transition: color var(--t-color);
196
+ transition: color var(--vp-t-color);
197
197
  }
198
198
 
199
199
  .output-head .icon-close:hover {
@@ -227,7 +227,7 @@ function runCode() {
227
227
  .output-content .stderr pre,
228
228
  .output-content.rust .stderr pre.error {
229
229
  color: var(--vp-c-danger-1, #b8272c);
230
- transition: color var(--t-color);
230
+ transition: color var(--vp-t-color);
231
231
  }
232
232
 
233
233
  .output-content.rust .stderr pre {
@@ -237,6 +237,6 @@ function runCode() {
237
237
  .output-content .stderr + .stdout {
238
238
  margin-top: 12px;
239
239
  border-top: 1px solid var(--vp-c-divider);
240
- transition: border-color var(--t-color);
240
+ transition: border-color var(--vp-t-color);
241
241
  }
242
242
  </style>
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { computed } from 'vue'
3
2
  import type { CodeSandboxTokenMeta } from '../../shared/index.js'
3
+ import { computed } from 'vue'
4
4
 
5
5
  const props = defineProps<CodeSandboxTokenMeta>()
6
6
 
@@ -11,19 +11,17 @@ const SANDBOX = 'allow-forms allow-modals allow-popups allow-presentation allow-
11
11
 
12
12
  const source = computed(() => {
13
13
  const params = new URLSearchParams()
14
- if (props.filepath) {
14
+ if (props.filepath)
15
15
  params.set(props.type === 'embed' ? 'module' : 'file', encodeURIComponent(props.filepath))
16
- }
17
16
 
18
17
  if (props.type === 'embed') {
19
18
  params.set('view', props.layout ? props.layout.replace(/,/g, '+') : 'Editor+Preview')
20
19
 
21
- if (props.console) {
20
+ if (props.console)
22
21
  params.set('expanddevtools', '1')
23
- }
24
- if (props.navbar === false) {
22
+
23
+ if (props.navbar === false)
25
24
  params.set('hidenavigation', '1')
26
- }
27
25
  }
28
26
  else {
29
27
  params.set('from-embed', '')
@@ -0,0 +1,245 @@
1
+ <script setup lang="ts">
2
+ import { useStorage } from '@vueuse/core'
3
+ import { onMounted, ref, shallowRef, watch } from 'vue'
4
+
5
+ interface TabProps extends Record<string, unknown> {
6
+ id: string
7
+ }
8
+ const props = withDefaults(defineProps<{
9
+ id: string
10
+ tabId?: string
11
+ active?: number
12
+ data: TabProps[]
13
+ }>(), { active: 0, tabId: '' })
14
+
15
+ const CODE_TAB_STORE_NAME = 'VUEPRESS_CODE_TAB_STORE'
16
+ const codeTabStore = useStorage<Record<string, string>>(CODE_TAB_STORE_NAME, {})
17
+
18
+ // Index of current active item
19
+ const activeIndex = ref(props.active)
20
+
21
+ // Refs of the tab buttons
22
+ const tabRefs = shallowRef<HTMLUListElement[]>([])
23
+
24
+ // Update store
25
+ function updateStore(): void {
26
+ if (props.tabId)
27
+ codeTabStore.value[props.tabId] = props.data[activeIndex.value].id
28
+ }
29
+
30
+ // Activate next tab
31
+ function activateNext(index = activeIndex.value): void {
32
+ activeIndex.value = index < tabRefs.value.length - 1 ? index + 1 : 0
33
+ tabRefs.value[activeIndex.value].focus()
34
+ }
35
+
36
+ // Activate previous tab
37
+ function activatePrev(index = activeIndex.value): void {
38
+ activeIndex.value = index > 0 ? index - 1 : tabRefs.value.length - 1
39
+ tabRefs.value[activeIndex.value].focus()
40
+ }
41
+
42
+ // Handle keyboard event
43
+ function keyboardHandler(event: KeyboardEvent, index: number): void {
44
+ if (event.key === ' ' || event.key === 'Enter') {
45
+ event.preventDefault()
46
+ activeIndex.value = index
47
+ }
48
+ else if (event.key === 'ArrowRight') {
49
+ event.preventDefault()
50
+ activateNext()
51
+ }
52
+ else if (event.key === 'ArrowLeft') {
53
+ event.preventDefault()
54
+ activatePrev()
55
+ }
56
+
57
+ if (props.tabId)
58
+ codeTabStore.value[props.tabId] = props.data[activeIndex.value].id
59
+ }
60
+
61
+ function getInitialIndex(): number {
62
+ if (props.tabId) {
63
+ const valueIndex = props.data.findIndex(
64
+ ({ id }) => codeTabStore.value[props.tabId] === id,
65
+ )
66
+
67
+ if (valueIndex !== -1)
68
+ return valueIndex
69
+ }
70
+
71
+ return props.active
72
+ }
73
+
74
+ onMounted(() => {
75
+ activeIndex.value = getInitialIndex()
76
+
77
+ watch(
78
+ () => codeTabStore.value[props.tabId],
79
+ (newValue, oldValue) => {
80
+ if (props.tabId && newValue !== oldValue) {
81
+ const index = props.data.findIndex(({ id }) => id === newValue)
82
+
83
+ if (index !== -1)
84
+ activeIndex.value = index
85
+ }
86
+ },
87
+ )
88
+ })
89
+ function onTabNavClick(index: number): void {
90
+ activeIndex.value = index
91
+ updateStore()
92
+ }
93
+ </script>
94
+
95
+ <template>
96
+ <div v-if="data.length" class="vp-code-tabs">
97
+ <div class="vp-code-tabs-nav" role="tablist">
98
+ <button
99
+ v-for="(item, index) in data"
100
+ :key="index"
101
+ :ref="(el) => el && (tabRefs[index] = el as HTMLUListElement)"
102
+ class="vp-code-tab-nav" :class="{ active: index === activeIndex }"
103
+ type="button" role="tab"
104
+ :aria-controls="`codetab-${id}-${index}`"
105
+ :aria-selected="index === activeIndex"
106
+ @click="() => onTabNavClick(index)"
107
+ @keydown="(e) => keyboardHandler(e, index)"
108
+ >
109
+ <slot :name="`title${index}`" :value="item.id" :is-active="index === activeIndex" />
110
+ </button>
111
+ </div>
112
+ <div
113
+ v-for="(item, index) in data"
114
+ :id="`codetab-${id}-${index}`" :key="index"
115
+ class="vp-code-tab" :class="{ active: index === activeIndex }"
116
+ role="tabpanel" :aria-expanded="index === activeIndex"
117
+ >
118
+ <div class="vp-code-tab-title">
119
+ <slot :name="`title${index}`" :value="item.id" :is-active="index === activeIndex" />
120
+ </div>
121
+ <slot :name="`tab${index}`" :value="item.id" :is-active="index === activeIndex" />
122
+ </div>
123
+ </div>
124
+ </template>
125
+
126
+ <style>
127
+ .vp-code-tabs-nav {
128
+ padding: 0 12px;
129
+ margin: 16px 0 0;
130
+ overflow: auto hidden;
131
+ white-space: nowrap;
132
+ list-style: none;
133
+ background-color: var(--vp-code-tab-bg);
134
+ border-radius: 6px 6px 0 0;
135
+ box-shadow: inset 0 -1px var(--vp-code-tab-divider);
136
+ transition: background-color var(--vp-t-color), box-shadow var(--vp-t-color);
137
+ }
138
+
139
+ @media print {
140
+ .vp-code-tabs-nav {
141
+ display: none;
142
+ }
143
+ }
144
+
145
+ @media (max-width: 639px) {
146
+ .vp-code-tabs-nav {
147
+ margin: 16px -24px 0;
148
+ border-radius: 0;
149
+ }
150
+
151
+ .vp-doc li .vp-code-tabs-nav {
152
+ border-top-left-radius: 6px;
153
+ }
154
+ }
155
+
156
+ .vp-code-tab-nav {
157
+ position: relative;
158
+ padding: 0 12px;
159
+ font-size: 14px;
160
+ font-weight: 500;
161
+ line-height: 48px;
162
+ color: var(--vp-code-tab-text-color);
163
+ white-space: nowrap;
164
+ border-bottom: 1px solid transparent;
165
+ transition: color var(--vp-t-color);
166
+ }
167
+
168
+ .vp-code-tab-nav:hover {
169
+ color: var(--vp-code-tab-hover-text-color);
170
+ }
171
+
172
+ .vp-code-tab-nav::after {
173
+ position: absolute;
174
+ right: 8px;
175
+ bottom: -1px;
176
+ left: 8px;
177
+ z-index: 1;
178
+ display: block;
179
+ width: auto;
180
+ height: 2px;
181
+ content: "";
182
+ background: transparent;
183
+ border-radius: 2px;
184
+ transition: background var(--vp-t-color);
185
+ }
186
+
187
+ .vp-code-tab-nav:focus-visible {
188
+ outline: none;
189
+ }
190
+
191
+ .vp-code-tab-nav.active {
192
+ color: var(--vp-code-tab-active-text-color);
193
+ background: transparent;
194
+ }
195
+
196
+ .vp-code-tab-nav.active::after {
197
+ background: var(--vp-code-tab-active-bar-color);
198
+ }
199
+
200
+ .vp-code-tab-nav .vp-icon {
201
+ width: 18px;
202
+ height: 18px;
203
+ margin-left: 0;
204
+ }
205
+
206
+ .vp-code-tab-nav span {
207
+ vertical-align: middle;
208
+ }
209
+
210
+ @media (max-width: 419px) {
211
+ .hint-container .vp-code-tabs-nav {
212
+ margin: 0.85rem -0.75rem 0 -1rem;
213
+ }
214
+ }
215
+
216
+ .vp-code-tab {
217
+ display: none;
218
+ }
219
+
220
+ @media print {
221
+ .vp-code-tab {
222
+ display: block;
223
+ }
224
+ }
225
+
226
+ .vp-code-tab.active {
227
+ display: block;
228
+ }
229
+
230
+ .vp-doc .vp-code-tab div[class*="language-"] {
231
+ margin-top: 0;
232
+ border-top-left-radius: 0;
233
+ border-top-right-radius: 0;
234
+ }
235
+
236
+ .vp-code-tab-title {
237
+ display: none;
238
+ }
239
+
240
+ @media print {
241
+ .vp-code-tab-title {
242
+ display: block;
243
+ }
244
+ }
245
+ </style>
@@ -12,7 +12,7 @@ const el = ref<HTMLElement>()
12
12
 
13
13
  function toggle(e: HTMLElementEventMap['click']) {
14
14
  const target = e.target as HTMLElement
15
- if (target.matches('.comment'))
15
+ if (target.matches('.comment') || e.currentTarget === target)
16
16
  return
17
17
  active.value = !active.value
18
18
  }
@@ -60,7 +60,7 @@ onUnmounted(() => {
60
60
  background-color: var(--vp-c-bg-safe);
61
61
  border: solid 1px var(--vp-c-divider);
62
62
  border-radius: 8px;
63
- transition: border var(--t-color), background-color var(--t-color);
63
+ transition: border var(--vp-t-color), background-color var(--vp-t-color);
64
64
  }
65
65
 
66
66
  .vp-file-tree .vp-file-tree-title {
@@ -69,7 +69,7 @@ onUnmounted(() => {
69
69
  font-weight: bold;
70
70
  color: var(--vp-c-text-1);
71
71
  border-bottom: solid 1px var(--vp-c-divider);
72
- transition: color var(--t-color), border-color var(--t-color);
72
+ transition: color var(--vp-t-color), border-color var(--vp-t-color);
73
73
  }
74
74
 
75
75
  .vp-file-tree ul {
@@ -106,7 +106,7 @@ onUnmounted(() => {
106
106
  .file-tree-item .tree-node.folder > .name {
107
107
  color: var(--vp-c-text-1);
108
108
  cursor: pointer;
109
- transition: color var(--t-color);
109
+ transition: color var(--vp-t-color);
110
110
  }
111
111
 
112
112
  .file-tree-item .tree-node.folder > .name:hover {
@@ -130,7 +130,7 @@ onUnmounted(() => {
130
130
  mask: var(--icon) no-repeat;
131
131
  -webkit-mask-size: 100% 100%;
132
132
  mask-size: 100% 100%;
133
- transition: color var(--t-color);
133
+ transition: color var(--vp-t-color);
134
134
  }
135
135
 
136
136
  .file-tree-item .tree-node .name.focus {
@@ -141,7 +141,7 @@ onUnmounted(() => {
141
141
  color: var(--vp-c-bg);
142
142
  background-color: var(--vp-c-brand-2);
143
143
  border-radius: 4px;
144
- transition: color var(--t-color), background-color var(--t-color);
144
+ transition: color var(--vp-t-color), background-color var(--vp-t-color);
145
145
  }
146
146
 
147
147
  .file-tree-item .tree-node .name.focus:hover {
@@ -153,7 +153,7 @@ onUnmounted(() => {
153
153
  margin-left: 20px;
154
154
  overflow: hidden;
155
155
  color: var(--vp-c-text-3);
156
- transition: color var(--t-color);
156
+ transition: color var(--vp-t-color);
157
157
  }
158
158
 
159
159
  .file-tree-item .tree-node [class*="vpi-"] {
@@ -170,7 +170,7 @@ onUnmounted(() => {
170
170
  padding-left: 8px !important;
171
171
  margin: 0 0 0 6px !important;
172
172
  border-left: solid 1px var(--vp-c-divider);
173
- transition: border-color var(--t-color);
173
+ transition: border-color var(--vp-t-color);
174
174
  }
175
175
 
176
176
  .file-tree-item:not(.expanded) > ul {
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
+ import type { PDFTokenMeta } from '../../shared/index.js'
2
3
  import { onMounted, toRefs } from 'vue'
3
4
  import { usePDF } from '../composables/pdf.js'
4
5
  import { useSize } from '../composables/size.js'
5
- import type { PDFTokenMeta } from '../../shared/index.js'
6
6
 
7
7
  const props = defineProps<PDFTokenMeta>()
8
8
 
@@ -1,9 +1,9 @@
1
1
  <script setup lang="ts">
2
+ import type { PlotOptions } from '../../shared/index.js'
2
3
  import { onClickOutside, useMediaQuery } from '@vueuse/core'
3
4
  import { computed, ref, shallowRef } from 'vue'
4
5
  import { usePageFrontmatter } from 'vuepress/client'
5
6
  import { pluginOptions } from '../options.js'
6
- import type { PlotOptions } from '../../shared/index.js'
7
7
 
8
8
  const props = defineProps<Omit<PlotOptions, 'tag'>>()
9
9
 
@@ -81,7 +81,7 @@ function onClick() {
81
81
  transition: color ease 0.25s, background-color ease 0.25s;
82
82
  }
83
83
 
84
- .dark .vp-plot {
84
+ [data-theme="dark"] .vp-plot {
85
85
  background-color: var(--vp-c-bg-plot-dark, #fff);
86
86
  }
87
87
 
@@ -90,8 +90,8 @@ function onClick() {
90
90
  color: var(--vp-c-plot-light, #fff);
91
91
  }
92
92
 
93
- .dark .vp-plot.hover:hover,
94
- .dark .vp-plot.active {
93
+ [data-theme="dark"] .vp-plot.hover:hover,
94
+ [data-theme="dark"] .vp-plot.active {
95
95
  color: var(--vp-c-plot-dark, #000);
96
96
  }
97
97
  </style>
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
- import { computed, getCurrentInstance, ref } from 'vue'
3
- import Loading from './Loading.vue'
4
2
  import type { ReplitTokenMeta } from '../../shared/index.js'
3
+ import { computed, getCurrentInstance, ref } from 'vue'
4
+ import Loading from './icons/Loading.vue'
5
5
 
6
6
  const props = defineProps<ReplitTokenMeta>()
7
7