Jump to content
Üyelik kaydınızı yaparak son yazılan içeriklerden haberdar olun! ×
  • entry
    1
  • comments
    0
  • views
    158

Ribbon Banner Component - VUEJS


Doğuhan ELMA

92 views

 

1.png

index.vue:

<script setup>

import RibbonBanner from "@/Components/RibbonBanner.vue";
</script>

<template>
    <div class="min-h-screen bg-blue-800 p-8">
        <div class="relative mx-auto bg-white rounded-xl shadow-xl aspect-square w-80">
            <RibbonBanner size="medium" color="amber" position="top-right">Doğuhan ELMA</RibbonBanner>
            <RibbonBanner size="large" color="amber" position="top-left">Doğuhan ELMA</RibbonBanner>
            <RibbonBanner size="medium" color="amber" position="bottom-left">Doğuhan ELMA</RibbonBanner>
            <RibbonBanner size="medium" color="amber" position="bottom-right">Doğuhan ELMA</RibbonBanner>
        </div>
    </div>
</template>

 

RibbonBanner.vue:

<script setup lang="ts">

export type RibbonProps = {
    position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
    size?: 'small' | 'medium' | 'large'
    color?: 'amber' | 'green' | 'purple' | 'cyan'
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Styles lookup
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const sizeClasses: Record<RibbonProps['size'], string> = {
    small: 'w-24',
    medium: 'w-28',
    large: 'w-36',
}

const positionClasses: Record<
    RibbonProps['position'],
    {
        wrapper: string
        shadeOne: string
        shadeTwo: string
        banner: string
    }
    > = {
    'top-left': {
        wrapper: '-top-2 -left-2',
        shadeOne: 'top-0 right-0',
        shadeTwo: 'bottom-0 left-0',
        banner: 'bottom-0 left-0 -rotate-45 origin-bottom-left',
    },
    'top-right': {
        wrapper: '-top-2 -right-2',
        shadeOne: 'top-0 left-0',
        shadeTwo: 'bottom-0 right-0',
        banner: 'bottom-0 right-0 rotate-45 origin-bottom-right',
    },
    'bottom-left': {
        wrapper: '-bottom-2 -left-2',
        shadeOne: 'top-0 left-0',
        shadeTwo: 'bottom-0 right-0',
        banner: 'top-0 left-0 rotate-45 origin-top-left',
    },
    'bottom-right': {
        wrapper: '-bottom-2 -right-2',
        shadeOne: 'top-0 right-0',
        shadeTwo: 'bottom-0 left-0',
        banner: 'top-0 right-0 -rotate-45 origin-top-right',
    },
}

const colorClasses: Record<
    RibbonProps['color'],
    {
        shades: string
        banner: string
    }
    > = {
    amber: {
        shades: 'bg-amber-500',
        banner: 'bg-amber-300 text-amber-800 hover:bg-yellow-300',
    },
    green: {
        shades: 'bg-green-500',
        banner: 'bg-green-300 text-green-800 hover:bg-emerald-300',
    },
    purple: {
        shades: 'bg-purple-500',
        banner: 'bg-purple-300 text-purple-800 hover:bg-violet-300',
    },
    cyan: {
        shades: 'bg-cyan-500',
        banner: 'bg-cyan-300 text-cyan-800 hover:bg-sky-300',
    },
}
const props = defineProps<{
    position: RibbonProps['position'],
    size:RibbonProps['size'],
    color:RibbonProps['color'],
}>()
</script>

<template>

    <div :class="[sizeClasses[size], positionClasses[position].wrapper, 'overflow-hidden rounded-sm aspect-square absolute']">
        <div :class="['absolute h-2 w-2', positionClasses[position].shadeOne, colorClasses[color].shades]"></div>
        <div :class="['absolute h-2 w-2', positionClasses[position].shadeTwo, colorClasses[color].shades]"></div>
        <a href="#" :class="['py-1.5 font-semibold uppercase text-xs tracking-wider block w-[141.42%] text-center absolute shadow-sm', positionClasses[position].banner , colorClasses[color].banner]">
            <slot />
        </a>
    </div>

</template>

 

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...