Advance UI Elements
Scrollable Official link Preview link
Installation
npm install overlayscrollbars overlayscrollbars-vue
In your main.ts file all the following code:
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
.component('OverlayScrollbars', OverlayScrollbarsComponent)
scrollbar.vue
<template>
<OverlayScrollbarsComponent
:options="{ scrollbars: { autoHide: 'scroll' } }"
style="height: 300px; width: 100%;">
<h6 class="pb-2">Scrollbar</h6>
<p>
I'm quite interested in learning more about
<b>custom scrollbars</b> because they are becoming more common.
</p>
<p>
There are various justifications for customizing a scrollbar...
</p>
<p>
I never had the opportunity to learn about CSS scrollbar customization...
</p>
<p>
One crucial point to remember is that a scrollbar may operate
either <b>horizontally or vertically</b>...
</p>
</OverlayScrollbarsComponent>
</template>
<script setup>
</script>
Uninstalling Package
npm uninstall overlayscrollbars overlayscrollbars-vue
Swiper Slider Official link Preview link
Installation
npm i swiper@11.2.5
In your main.ts file all the following code:
import { Swiper, SwiperSlide } from 'swiper/vue';
.component('Swiper', Swiper)
.component('SwiperSlide', SwiperSlide)
SwiperSlider.vue
<template>
<Swiper
:space-between="30"
:centered-slides="true"
:autoplay="{ delay: 2500, disableOnInteraction: false }"
:pagination="{ clickable: true }"
:navigation="true"
class="my-swiper"
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
</Swiper>
</template>
<script setup>
// Import Swiper styles
import 'swiper/css';
import 'swiper/css/pagination';
import 'swiper/css/navigation';
// Pass modules to Swiper
const modules = [Autoplay, Pagination, Navigation];
</script>
<style scoped>
.my-swiper {
width: 100%;
height: 300px;
}
</style>
Uninstalling Package
npm uninstall swiper
Rating Official link Preview link
Installation
npm install vue-star-rating
In your main.ts file all the following code:
import StarRating from 'vue-star-rating';
.component('StarRating', StarRating)
rating.vue
<template>
<div>
<star-rating v-model="rating" :star-size="25" :show-rating="false" />
<p>Current Rating: {{ rating }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const rating = ref<number>(2)
</script>
<script lang="ts">
export default {
components: { StarRating }
}
</script>
Uninstalling Package
npm uninstall vue-star-rating
SweetAlert2 Official link Preview link
Installation
npm install sweetalert2
sweetAlert.vue
<template>
<button class="btn btn-primary sweet-1" type="button" @click="open()">Click it!</button>
</template>
<script setup lang="ts">
import Swal from 'sweetalert2';
function open() {
Swal.fire('Welcome! to the kreta theme!');
}
</script>
<style scoped></style>
Uninstalling Package
npm uninstall sweetalert2
Range Slider Official link Preview link
Installation
npm install vue-3-slider-component
In your main.ts file all the following code:
import VueSlider from 'vue-3-slider-component';
.component('VueSlider', VueSlider)
rangeSlider.vue
<template>
<VueSlider v-model="value" :min="100" :max="1000" />
</template>
<script setup>
import { ref } from 'vue';
const value = ref<number>(550)
</script>
Uninstalling Package
npm uninstall vue-3-slider-component
Image Cropper Official link Preview link
Installation
npm install vue-advanced-cropper
imageCropper.vue
<template>
<div class="container-fluid">
<div class="img-cropper">
<div class="row">
<div class="col-sm-12">
<Card :headerTitle="'Image Cropper'" :border="true" :padding="false">
<template #header5>
<p class="f-m-light mt-1">
Use <code>vue-advanced-cropper</code> to create an interactive image cropping tool that allows users to upload, zoom, move, and preview cropped images in real-time.
</p>
</template>
<div class="row align-items-center">
<div class="col-xl-9 col-md-12">
<div class="img-container">
<Cropper
ref="cropper"
:src="imageSrc"
:stencil-props="{
minAspectRatio: 10 / 20,
}"
:resize-image="true"
class="cropper"
@change="onChange"
/>
</div>
</div>
<div class="col-xl-3 col-md-12">
<div class="docs-preview clearfix"></div>
<div class="docs-data" v-if="result.coordinates">
<div class="input-group input-group-sm">
<span class="input-group-text">X</span>
<input class="form-control" id="dataX" type="text" placeholder="x" :value="result.coordinates.left" />
<span class="input-group-text">px</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-text">Y</span>
<input class="form-control" id="dataY" type="text" placeholder="y" :value="result.coordinates.top" />
<span class="input-group-text">px</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-text">Width</span>
<input class="form-control" id="dataWidth" type="text" placeholder="width" :value="result.coordinates.width" />
<span class="input-group-text">px</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-text">Height </span>
<input class="form-control" id="dataHeight" type="text" placeholder="height" :value="result.coordinates.height" />
<span class="input-group-text">px</span>
</div>
</div>
<img :src="result.image" v-if="result && result.image" class="img-fluid mt-2" />
</div>
</div>
</Card>
<Card>
<div class="row g-2">
<div class="col-xl-9 col-md-12 docs-buttons">
<div class="btn-group">
<button class="btn btn-primary" type="button" @click="zoom(2)">
<span class="docs-tooltip" v-tooltip :title="'Zoom In'"><span class="fa-solid fa-magnifying-glass-plus"></span></span>
</button>
<button class="btn button-light-primary" type="button" data-method="zoom" data-option="-0.1" title="Zoom Out" @click="zoom(0.5)">
<span class="docs-tooltip" v-tooltip :title="'Zoom Out'"><span class="fa-solid fa-magnifying-glass-minus txt-primary"></span></span>
</button>
</div>
<div class="btn-group">
<button class="btn btn-outline-secondary" type="button" @click="move('left')">
<span class="docs-tooltip" v-tooltip :title="'Move Left'"><span class="fa-solid fa-arrow-left"></span></span>
</button>
<button class="btn btn-outline-secondary" type="button" @click="move('right')">
<span class="docs-tooltip" v-tooltip :title="'Move Right'"><span class="fa-solid fa-arrow-right"></span></span>
</button>
<button class="btn btn-outline-secondary" type="button" @click="move('top')">
<span class="docs-tooltip" v-tooltip :title="'Move Up'"><span class="fa-solid fa-arrow-up"></span></span>
</button>
<button class="btn btn-outline-secondary" type="button" @click="move('bottom')">
<span class="docs-tooltip" v-tooltip :title="'Move Down'"><span class="fa-solid fa-arrow-down"></span></span>
</button>
</div>
<div class="btn-group">
<button class="btn btn-outline-success" type="button" @click="rotate(-45)">
<span class="docs-tooltip" v-tooltip :title="'Rotate Left'"><span class="fa-solid fa-rotate-left"></span></span>
</button>
<button class="btn btn-outline-success" type="button" @click="rotate(45)">
<span class="docs-tooltip" v-tooltip :title="'Rotate Right'"><span class="fa-solid fa-rotate-right"></span></span>
</button>
</div>
<div class="btn-group">
<button class="btn btn-outline-info" type="button" @click="flip(true, false)">
<span class="docs-tooltip" v-tooltip :title="'Flip Horizontal'"><SvgIcon :icon="'flip-horizontal'" /></span>
</button>
<button class="btn btn-outline-info" type="button" @click="flip(false, true)">
<span class="docs-tooltip" v-tooltip :title="'Flip Vertical'"><SvgIcon :icon="'flip-vertical'" /></span>
</button>
</div>
<div class="btn-group">
<button class="btn btn-outline-warning" type="button" @click="resize(2, 2)">
<span class="docs-tooltip" v-tooltip title="Resize(x2)"><span class="fa-solid fa-maximize"></span></span>
</button>
<button class="btn btn-outline-warning" type="button" @click="resize(1, 2)">
<span class="docs-tooltip" v-tooltip title="Resize height(2x)">
<span class="fa-solid fa-arrows-up-down"></span>
</span>
</button>
<button class="btn btn-outline-warning" type="button" @click="resize(2, 1)">
<span class="docs-tooltip" v-tooltip title="Resize width(2x)"><span class="fa-solid fa-arrows-left-right"></span></span>
</button>
<button class="btn btn-outline-warning" type="button" @click="resize(0.5, 0.5)">
<span class="docs-tooltip" v-tooltip title="Resize(x1/2)"><span class="fa-solid fa-minimize"></span></span>
</button>
<button class="btn btn-outline-warning" type="button" @click="maximize()">
<span class="docs-tooltip" v-tooltip title="Maximize"><span class="fa-solid fa-expand"></span></span>
</button>
<button class="btn btn-outline-warning" type="button" @click="center()">
<span class="docs-tooltip" v-tooltip title="Center"><span class="fa-solid fa-arrows-to-circle"></span></span>
</button>
</div>
<div class="btn-group"></div>
<div class="btn-group">
<label class="btn btn-outline-dark btn-upload" for="inputImage" title="Upload image file">
<input class="sr-only" id="inputImage" type="file" name="file" accept=".jpg,.jpeg,.png,.gif,.bmp,.tiff" @change="onFileChange" /><span
class="docs-tooltip"
data-bs-toggle="tooltip"
data-animation="false"
title="Upload"
><span class="fa-solid fa-upload"></span
></span>
</label>
<button class="btn btn-outline-dark" type="button" @click="reset()">
<span class="docs-tooltip" v-tooltip title="Destroy"><span class="fa-solid fa-power-off"></span></span>
</button>
</div>
<br />
</div>
</div>
</Card>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { Cropper, PreviewResult } from 'vue-advanced-cropper';
definePageMeta({
breadcrumb: 'Bonus Ui',
title: 'Image Cropper',
});
useHead({
title: 'Image Cropper',
});
const { imageSrc, cropper, result, onFileChange, onChange, zoom, move, rotate, flip, resize, center, maximize, reset } = imageCropper();
</script>
<style scoped lang="scss"></style>
imageCropper.ts
import { baseUtils } from '@/utils';
export function imageCropper() {
const { getImage } = baseUtils();
const imageSrc = ref(getImage('other-images/bg-profile.png'));
const cropper = ref();
let result = ref({
coordinates: {
width: 0,
height: 0,
top: 0,
left: 0,
angle: 0,
},
image: null,
size: {
width: 0,
height: 0,
},
});
function onFileChange(event: Event) {
const file = (event.target as HTMLInputElement)?.files?.[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e: ProgressEvent) => {
imageSrc.value = e.target?.result as string;
};
reader.readAsDataURL(file);
}
function onChange() {
const cropResult = cropper.value?.getResult();
if (cropResult) {
const canvas = cropper.value.getCanvas();
const croppedImage = canvas?.toDataURL('image/png');
result.value = {
coordinates: cropResult.coordinates,
image: croppedImage,
size: {
width: Math.round(cropResult.coordinates.width),
height: Math.round(cropResult.coordinates.height),
},
};
}
}
function zoom(factor: number) {
cropper.value.zoom(factor);
}
function move(direction: string) {
if (direction === 'left') {
cropper.value.move(-result.value.size.width / 4);
} else if (direction === 'right') {
cropper.value.move(result.value.size.width / 4);
} else if (direction === 'top') {
cropper.value.move(0, -result.value.size.height / 4);
} else if (direction === 'bottom') {
cropper.value.move(0, result.value.size.height / 4);
}
}
function rotate(angle: number) {
cropper.value.rotate(angle);
}
function flip(x: boolean, y: boolean) {
const { image } = cropper.value.getResult();
if (image.transforms.rotate % 180 !== 0) {
cropper.value.flip(!x, !y);
} else {
cropper.value.flip(x, y);
}
}
function resize(width = 1, height = 1) {
let startCoordinates: { left: number; width: number; top: number; height: number };
cropper.value.setCoordinates([
() => {
startCoordinates = result.value.coordinates;
return {
width: result.value.coordinates.width * width,
height: result.value.coordinates.height * height,
};
},
() => ({
left: startCoordinates.left + (startCoordinates.width - result.value.coordinates.width) / 2,
top: startCoordinates.top + (startCoordinates.height - result.value.coordinates.height) / 2,
}),
]);
}
function center() {
cropper.value.setCoordinates(() => ({
left: result.value.size.width / 2 - result.value.coordinates.width / 2,
top: result.value.size.height / 2 - result.value.coordinates.height / 2,
}));
}
function maximize() {
const center = {
left: result.value.coordinates.left + result.value.coordinates.width / 2,
top: result.value.coordinates.top + result.value.coordinates.height / 2,
};
cropper.value.setCoordinates([
() => ({
width: result.value.size.width,
height: result.value.size.height,
}),
() => ({
left: center.left - result.value.coordinates.width / 2,
top: center.top - result.value.coordinates.height / 2,
}),
]);
}
function reset() {
result.value.image = null;
imageSrc.value = '';
}
return {
imageSrc,
cropper,
result,
onFileChange,
onChange,
zoom,
move,
rotate,
flip,
resize,
center,
maximize,
reset,
};
}
Uninstalling Package
npm uninstall vue-advanced-cropper
File Upload (FilePond) Official link Preview link
Installation
npm install vue-filepond filepond-plugin-file-validate-type filepond-plugin-image-preview
In your main.ts file all the following code:
import type { DefineComponent } from 'vue';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import vueFilePond from 'vue-filepond';
const FilePond = vueFilePond(FilePondPluginImagePreview, FilePondPluginFileValidateType) as DefineComponent;
.component('FilePond', FilePond)
filepond.vue
<template>
<div class="filepond-wrapper">
<file-pond
name="file"
ref="pond"
label-idle='<h6>Drop files here or click to upload.</h6>
<span class="note">(This is just a demo. Files are <strong>not</strong> actually uploaded.)</span>'
:allow-multiple="false"
:max-files="1"
:server="serverConfig"
/>
</div>
</template>
<script setup>
import "filepond/dist/filepond.min.css"
const serverConfig = {
process: {
url: "https://httpbin.org/post",
method: "POST"
}
};
</script>
Uninstalling Package
npm uninstall vue-filepond filepond filepond-plugin-image-preview