Skip to content

Commit 82ac922

Browse files
Cleaning up and adding/removing props
1 parent 500f802 commit 82ac922

File tree

8 files changed

+1542
-293
lines changed

8 files changed

+1542
-293
lines changed

src/plugin/CodeBlock.vue

Lines changed: 108 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
<template>
2-
<div
3-
class="v-code-block--container v-code-block-mb-5"
4-
:class="codeBlockClasses"
5-
>
6-
<div class="v-code-block--container-header" :style="headerStyles">
7-
<div
8-
class="v-code-block--container-label v-code-block-pb-1"
9-
:class="labelClasses"
10-
>
2+
<div class="v-code-block v-code-block--mb-5" :class="codeBlockClasses">
3+
<div
4+
v-if="label || tabs || slots.label || slots.tabs"
5+
class="v-code-block--header"
6+
:style="headerStyles"
7+
>
8+
<div class="v-code-block--label v-code-block--pb-1" :class="labelClasses">
119
<template v-if="slots.label">
1210
<slot name="label" />
1311
</template>
@@ -16,44 +14,62 @@
1614
</template>
1715
</div>
1816

19-
<div class="v-code-block--container-tabs" :style="tabGroupStyle">
17+
<div class="v-code-block--tabs" :style="tabGroupStyle">
2018
<template v-if="slots.tabs">
2119
<slot name="tabs" />
2220
</template>
2321
<template v-else>
2422
<!-- ======================================== Copy Code Tab/Button -->
2523
<div
26-
v-if="showCopyTab && showTabs"
27-
class="v-code-block--container-tab"
24+
v-if="copyTab && tabs"
25+
class="v-code-block--tab"
2826
:class="tabClasses"
2927
@click="copyCode"
3028
>
31-
<div class="v-code-block--container-button-copy">
32-
<fa-icon
33-
v-if="showCopyIcons"
34-
class="fa-fw v-code-block-me-1 v-code-block--container-button-copy-icon"
29+
<div class="v-code-block--button-copy">
30+
<StatusIcons
31+
v-if="copyIcons"
32+
class="v-code-block--button-copy-icon"
3533
:class="iconClasses"
36-
:icon="buttonIconValue"
34+
:icon="copyStatus"
3735
/>
38-
{{ buttonTextValue }}
36+
{{ copyTextValue }}
3937
</div>
4038
</div>
4139

4240
<!-- ======================================== Run Tab/Button -->
4341
<div
44-
v-if="showRunTab && showTabs && !isMobile"
45-
class="v-code-block--container-tab"
42+
v-if="runTab && tabs && !isMobile"
43+
class="v-code-block--tab"
4644
:class="tabClasses"
4745
@click="runCode"
4846
>
49-
<div class="v-code-block--container-button-run">Run</div>
47+
<div class="v-code-block--button-run">Run</div>
5048
</div>
5149
</template>
5250
</div>
5351
</div>
54-
<div class="v-code-block--container-code">
52+
<div class="v-code-block--code">
53+
<div
54+
class="v-code-block--code-copy-button"
55+
:class="copyButtonClasses"
56+
@click="copyCode"
57+
>
58+
<template v-if="slots.copyButton">
59+
<slot name="copyButton" />
60+
</template>
61+
<template v-else>
62+
<StatusIcons
63+
v-if="copyButton"
64+
class="v-code-block--button-copy-icon"
65+
:class="iconClasses"
66+
:icon="copyStatus"
67+
/>
68+
</template>
69+
</div>
70+
5571
<pre :class="`language-${props.lang}`" :style="preTagStyles">
56-
<code :class="`language-${props.lang} ${browserWindow ? 'v-code-block--container-code-browser' : ''}`" :style="codeTagStyles" v-html="renderCode"></code>
72+
<code :class="`language-${props.lang} ${browserWindow ? 'v-code-block--code-browser' : ''}`" :style="codeTagStyles" v-html="renderCode"></code>
5773
</pre>
5874
</div>
5975
</div>
@@ -70,9 +86,11 @@ import {
7086
watch,
7187
} from 'vue';
7288
import Prism from 'prismjs';
73-
// import PrismComponents from 'prismjs/components';
7489
import UAParser from 'ua-parser-js';
7590
91+
import StatusIcons from '@/plugin/StatusIcons.vue';
92+
import neonBunnyCarrotTheme from '@/plugin/theme/neon-bunny-carrot.css?inline';
93+
import neonBunnyTheme from '@/plugin/theme/neon-bunny.css?inline';
7694
import prismTheme from 'prismjs/themes/prism.css?inline';
7795
import prismThemeCoy from 'prismjs/themes/prism-coy.css?inline';
7896
import prismThemeDark from 'prismjs/themes/prism-dark.css?inline';
@@ -81,15 +99,13 @@ import prismThemeOkaidia from 'prismjs/themes/prism-okaidia.css?inline';
8199
import prismThemeSolarizedlight from 'prismjs/themes/prism-solarizedlight.css?inline';
82100
import prismThemeTomorrow from 'prismjs/themes/prism-tomorrow.css?inline';
83101
import prismThemeTwilight from 'prismjs/themes/prism-twilight.css?inline';
84-
import neonBunnyTheme from '@/plugin/theme/neon-bunny.css?inline';
85-
import neonBunnyCarrotTheme from '@/plugin/theme/neon-bunny-carrot.css?inline';
86102
87103
// ! Remove this later as it should be loaded by the user ! //
88104
import prismThemeNightOwl from 'prism-themes/themes/prism-night-owl.css?inline';
89105
90106
91107
// -------------------------------------------------- Emits & Slots & Injects //
92-
const emit = defineEmits(['copied', 'run']);
108+
const emit = defineEmits(['run', 'update:copy-status']);
93109
const slots = useSlots();
94110
const codeBlockGlobalOptions = inject('codeBlockGlobalOptions');
95111
@@ -110,20 +126,35 @@ const props = defineProps({
110126
required: false,
111127
default: '0.5rem',
112128
},
113-
copyIcon: {
129+
copyButton: {
130+
type: Boolean,
131+
required: false,
132+
default: true,
133+
},
134+
copyIcons: {
135+
type: Boolean,
136+
required: false,
137+
default: true,
138+
},
139+
copyTab: {
140+
type: Boolean,
141+
required: false,
142+
default: true,
143+
},
144+
copyFailedText: {
114145
type: String,
115146
required: false,
116-
default: 'fa-solid fa-copy',
147+
default: 'Copy failed!',
117148
},
118149
copyText: {
119150
type: String,
120151
required: false,
121152
default: 'Copy Code',
122153
},
123-
failedIcon: {
154+
copySuccessText: {
124155
type: String,
125156
required: false,
126-
default: 'fa-solid fa-xmark',
157+
default: 'Copied!',
127158
},
128159
floatingTabs: {
129160
type: Boolean,
@@ -138,7 +169,7 @@ const props = defineProps({
138169
indent: {
139170
type: Number,
140171
required: false,
141-
default: 4,
172+
default: 2,
142173
},
143174
label: {
144175
type: String,
@@ -155,93 +186,91 @@ const props = defineProps({
155186
required: false,
156187
default: 'auto',
157188
},
158-
showCopyIcons: {
159-
type: Boolean,
160-
required: false,
161-
default: true,
162-
},
163-
showRunTab: {
189+
persistentCopyButton: {
164190
type: Boolean,
165191
required: false,
166192
default: false,
167193
},
168-
showCopyTab: {
169-
type: Boolean,
170-
required: false,
171-
default: true,
172-
},
173-
showTabs: {
194+
runTab: {
174195
type: Boolean,
175196
required: false,
176-
default: true,
177-
},
178-
successIcon: {
179-
type: String,
180-
required: false,
181-
default: 'fa-solid fa-check',
197+
default: false,
182198
},
183199
tabGap: {
184200
type: String,
185201
required: false,
186202
default: '0.25rem',
187203
},
204+
tabs: {
205+
type: Boolean,
206+
required: false,
207+
default: false,
208+
},
188209
theme: {
189-
type: String, Boolean,
210+
type: [String, Boolean],
190211
required: false,
191-
default: '',
212+
default: 'neon-bunny',
192213
}
193214
});
194215
195216
196217
// -------------------------------------------------- Data //
197-
const buttonIconValue: string = ref('');
198-
const buttonTextValue: string = ref('');
218+
const copyTextValue: string = ref('');
199219
const convertedCode: string = ref('');
200220
const copying: boolean = ref(false);
201221
const copyStatus: string = ref('copy');
202-
const iconClass: string = ref('fa-solid fa-copy');
203222
const isMobile: boolean = ref(false);
204223
const stylesheetId = 'v-code-block--theme';
205224
const useTheme = ref('');
206225
207226
208227
// -------------------------------------------------- Computed //
209228
const codeBlockClasses = computed<string>(() => {
210-
return isMobile.value ? 'v-code-block--container-mobile' : '';
229+
return isMobile.value ? 'v-code-block--mobile' : '';
211230
});
212231
213232
const codeTagStyles = computed<object>(() => {
214233
const width = useTheme.value === 'coy' ? '100%' : '';
215234
return { width };
216235
});
217236
237+
const copyButtonClasses = computed<string>(() => {
238+
return {
239+
'v-code-block--code-copy-button': true,
240+
'v-code-block--code-copy-button-mobile': isMobile.value,
241+
[`v-code-block--code-copy-button-persist`]: props.persistentCopyButton,
242+
[`v-code-block--code-copy-button-status-${copyStatus.value}`]: true,
243+
};
244+
});
245+
218246
const headerStyles = computed<object>(() => {
219247
return {
220248
bottom: props.floatingTabs ? '1px' : '0',
221-
gap: props.tabGap,
249+
gap: convertToUnit(props.tabGap),
222250
};
223251
});
224252
225253
const iconClasses = computed<object>(() => {
226254
const theme = useTheme.value === '' || useTheme.value === 'prism' ? 'default' : useTheme.value;
227255
228256
const classes = {
229-
[`v-code-block--container-tab-${theme}-icon`]: true,
230-
[`v-code-block--container-button-copy-icon-status-${copyStatus.value}`]: true,
231-
[`v-code-block--container-tab-${theme}-icon-status-${copyStatus.value}`]: true,
257+
'v-code-block--me-1': true,
258+
[`v-code-block--tab-${theme}-icon`]: true,
259+
[`v-code-block--button-copy-icon-status-${copyStatus.value}`]: true,
260+
[`v-code-block--tab-${theme}-icon-status-${copyStatus.value}`]: true,
232261
};
233262
return classes;
234263
});
235264
236265
const labelClasses = computed<string>(() => {
237-
return isMobile.value ? 'v-code-block--container-label-mobile' : '';
266+
return isMobile.value ? 'v-code-block--label-mobile' : '';
238267
});
239268
240269
const preTagStyles = computed<object>(() => {
241270
const radius = props.codeBlockRadius;
242271
let borderRadius = `${radius} 0 ${radius} ${radius}`;
243272
244-
if (!props.showTabs || (!props.showCopyTab && !props.showRunTab)) {
273+
if (!props.tabs || (!props.copyTab && !props.runTab)) {
245274
borderRadius = radius;
246275
}
247276
@@ -268,14 +297,14 @@ const renderCode = computed<unknown>(() => {
268297
const tabClasses = computed<object>(() => {
269298
const theme = useTheme.value === '' || useTheme.value === 'prism' ? 'default' : useTheme.value;
270299
const classes = {
271-
[`v-code-block--container-tab-${theme}`]: true,
300+
[`v-code-block--tab-${theme}`]: true,
272301
};
273302
return classes;
274303
});
275304
276305
const tabGroupStyle = computed<object>(() => {
277306
return {
278-
gap: props.tabGap,
307+
gap: convertToUnit(props.tabGap),
279308
};
280309
});
281310
@@ -288,17 +317,14 @@ watch(props, () => {
288317
}
289318
290319
if (props.copyText) {
291-
buttonTextValue.value = props.copyText;
320+
copyTextValue.value = props.copyText;
292321
}
293322
});
294323
295-
console.log({ Prism });
296-
297324
298325
// -------------------------------------------------- Mounts //
299326
onBeforeMount(() => {
300-
buttonTextValue.value = props.copyText;
301-
buttonIconValue.value = props.copyIcon;
327+
copyTextValue.value = props.copyText;
302328
});
303329
304330
onMounted(() => {
@@ -310,9 +336,9 @@ onMounted(() => {
310336
311337
// -------------------------------------------------- Methods //
312338
function convertCode(): void {
313-
if (props.lang === 'json') {
314339
315-
convertedCode.value = JSON.stringify(props.code, null, props.indent);
340+
if (props.lang === 'json') {
341+
convertedCode.value = JSON.stringify(JSON.parse(props.code), null, props.indent);
316342
return;
317343
}
318344
@@ -339,23 +365,20 @@ function copyCode(): void {
339365
copying.value = true;
340366
341367
navigator.clipboard.writeText(convertedCode.value).then(() => {
342-
buttonIconValue.value = props.successIcon;
343-
buttonTextValue.value = 'Copied!';
344-
iconClass.value = 'fa-solid fa-check';
368+
copyTextValue.value = props.copySuccessText;
345369
copyStatus.value = 'success';
370+
emit('update:copy-status', copyStatus.value);
346371
}, (err) => {
347-
buttonIconValue.value = props.failedIcon;
348-
buttonTextValue.value = 'Copy failed!';
349-
iconClass.value = 'fa-solid fa-xmark';
372+
copyTextValue.value = props.copyFailedText;
350373
copyStatus.value = 'failed';
374+
emit('update:copy-status', copyStatus.value);
351375
console.error('Copy to clipboard failed: ', err);
352376
});
353377
354378
setTimeout(() => {
355-
buttonIconValue.value = props.copyIcon;
356-
buttonTextValue.value = props.copyText;
379+
copyTextValue.value = props.copyText;
357380
copyStatus.value = 'copy';
358-
iconClass.value = 'fa-solid fa-copy';
381+
emit('update:copy-status', copyStatus.value);
359382
copying.value = false;
360383
}, 3000);
361384
}
@@ -435,8 +458,10 @@ function runCode(): void {
435458

436459

437460
<style lang="scss">
461+
@import './styles/utilities';
462+
438463
.v-code-block {
439-
&--container {
464+
&- {
440465
&--label {
441466
&-mobile {
442467
input,
@@ -451,5 +476,6 @@ function runCode(): void {
451476
</style>
452477

453478
<style lang="scss" scoped>
454-
@import '../style';
479+
@import './styles/main';
455480
</style>
481+

0 commit comments

Comments
 (0)