added component
This commit is contained in:
72
resources/js/components/SMHeader.vue
Normal file
72
resources/js/components/SMHeader.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<a :href="`#${id}`" class="header">
|
||||
<h3>
|
||||
{{ props.text }}
|
||||
<span class="hash" @click.prevent="copyAnchor">#</span>
|
||||
</h3>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useToastStore } from "../store/ToastStore";
|
||||
|
||||
const props = defineProps({
|
||||
text: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: "",
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
|
||||
const computedHeaderId = (text: string): string => {
|
||||
return text.replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase();
|
||||
};
|
||||
|
||||
const id = ref(
|
||||
props.id && props.id.length > 0 ? props.id : computedHeaderId(props.text)
|
||||
);
|
||||
|
||||
const copyAnchor = () => {
|
||||
const currentUrl = window.location.href.replace(/#.*/, "");
|
||||
const newUrl = currentUrl + "#" + id.value;
|
||||
|
||||
navigator.clipboard
|
||||
.writeText(newUrl)
|
||||
.then(() => {
|
||||
useToastStore().addToast({
|
||||
title: "Copy to Clipboard",
|
||||
content: "The header URL has been copied to the clipboard",
|
||||
type: "success",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
useToastStore().addToast({
|
||||
title: "Copy to Clipboard",
|
||||
content: "Failed to copy the header URL to the clipboard",
|
||||
type: "danger",
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.header {
|
||||
color: var(--base-color-text) !important;
|
||||
text-decoration: none;
|
||||
|
||||
.hash {
|
||||
display: none;
|
||||
color: var(--primary-color);
|
||||
opacity: 75%;
|
||||
}
|
||||
|
||||
&:hover .hash {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,78 +0,0 @@
|
||||
<template>
|
||||
<div class="sm-heading">
|
||||
<router-link v-if="back != ''" :to="{ name: back }" class="sm-back">
|
||||
<ion-icon name="arrow-back-outline" />{{ backLabel }}
|
||||
</router-link>
|
||||
<router-link v-if="close != ''" :to="{ name: close }" class="sm-close">
|
||||
<ion-icon name="close-outline" />
|
||||
</router-link>
|
||||
<span v-if="closeBack" class="sm-close" @click="handleBack">
|
||||
<ion-icon name="close-outline" />
|
||||
</span>
|
||||
<h1>{{ heading }}</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
defineProps({
|
||||
heading: {
|
||||
type: String,
|
||||
default: "",
|
||||
required: true,
|
||||
},
|
||||
back: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
backLabel: {
|
||||
type: String,
|
||||
default: "Back",
|
||||
},
|
||||
close: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
closeBack: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
const handleBack = () => {
|
||||
router.back();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.sm-heading {
|
||||
position: relative;
|
||||
|
||||
.sm-back {
|
||||
position: absolute;
|
||||
padding-top: 2rem;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.sm-close {
|
||||
right: -10px;
|
||||
top: -10px;
|
||||
position: absolute;
|
||||
font-size: 120%;
|
||||
color: $font-color;
|
||||
|
||||
&:hover {
|
||||
color: $danger-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 640px) {
|
||||
.sm-heading .sm-close {
|
||||
right: 0;
|
||||
top: -20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user