Compare commits
23 Commits
1.0.0
...
8488c70b44
Author | SHA1 | Date | |
---|---|---|---|
8488c70b44 | |||
78e8e524dc | |||
57bd46b201 | |||
7aa0c69354 | |||
c50cdb0ad8 | |||
164ee498e9 | |||
9ae9f077ce | |||
05540db8d3 | |||
2e568395a5 | |||
e2727a7b83 | |||
faf626fbca | |||
e6cae1aec9 | |||
39e135d038 | |||
64c32bd452 | |||
5ab9b3db4b | |||
00a8fc630e | |||
232329a05c | |||
d1ee2539a9 | |||
abb43e054e | |||
d824da5a39 | |||
e6fdbf7a94 | |||
b56cc416d0 | |||
a367b12150 |
@ -1,6 +0,0 @@
|
|||||||
<template>
|
|
||||||
<h1>Hello Nuxt3</h1>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
</script>
|
|
280
app.vue
Normal file
280
app.vue
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex flex-col gap-10 bg-whitep-10">
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-center gap-20 relative w-[1200px] mx-auto"
|
||||||
|
>
|
||||||
|
<!-- MlButton: This button can be used for various actions like form submissions or dialog openings. Customize its appearance using the :pt prop. -->
|
||||||
|
<MlButton
|
||||||
|
:pt="{
|
||||||
|
root: {
|
||||||
|
class: 'flex justify-center items-center disabled:opacity-60',
|
||||||
|
},
|
||||||
|
outer: {
|
||||||
|
class:
|
||||||
|
'bg-gradient-to-r from-green-300 to-red-400 p-[2px] w-full focus:outline-none rounded-3xl',
|
||||||
|
},
|
||||||
|
inner: {
|
||||||
|
class:
|
||||||
|
'justify-center flex items-center bg-white px-5 py-2 w-full h-full font-semibold leading-[1.5] back bg-white rounded-3xl',
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
</MlButton>
|
||||||
|
|
||||||
|
<!-- MlPaginator: Handles item pagination. Customize the appearance and behavior via props. Listens to changes with @update:paginatedItems to manage displayed items. -->
|
||||||
|
<MlPaginator
|
||||||
|
:items="items"
|
||||||
|
:items-per-page="2"
|
||||||
|
:max-pages-shown="2"
|
||||||
|
@update:paginatedItems="handlePaginatedItems"
|
||||||
|
v-model="currentPage"
|
||||||
|
:pt="{
|
||||||
|
root: {
|
||||||
|
class:
|
||||||
|
'w-auto flex space-x-1 bg-white/85 shadow-2xl items-center px-3 py-2 rounded-full text-black',
|
||||||
|
},
|
||||||
|
paginator: { class: '' },
|
||||||
|
activePaginator: { class: 'bg-green-500' },
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<!-- MlDropDown: A customizable dropdown menu component for selecting options.
|
||||||
|
Use the :pt prop to define styles for the root, dropdown, title, and arrow sections.
|
||||||
|
The dropdown supports multiple items which can be styled individually using the :pt prop for each MlDropDownItem. -->
|
||||||
|
|
||||||
|
<MlDropDown
|
||||||
|
title="Dropdown"
|
||||||
|
:title="''"
|
||||||
|
:pt="{
|
||||||
|
root: {
|
||||||
|
class: 'relative cursor-pointer w-[100px] h-10 text-left relative',
|
||||||
|
},
|
||||||
|
dropdown: {
|
||||||
|
class: 'w-[150px] right-[-50px] absolute mt-4 block',
|
||||||
|
},
|
||||||
|
title: { class: 'w-[100px] h-10 bg-white shadow-2xl' },
|
||||||
|
arrow: { class: 'hidden' },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<!-- Each MlDropDownItem represents an option in the dropdown menu. Style each item and define click behavior for interactivity. -->
|
||||||
|
<MlDropDownItem :pt="{ root: { class: 'block px-1 py-3' } }">
|
||||||
|
<span
|
||||||
|
class="w-full cursor-pointer font-medium flex items-center justify-center"
|
||||||
|
>English</span
|
||||||
|
>
|
||||||
|
</MlDropDownItem>
|
||||||
|
<MlDropDownItem :pt="{ root: { class: 'block px-1 py-3' } }">
|
||||||
|
<span
|
||||||
|
class="w-full cursor-pointer font-medium flex items-center justify-center"
|
||||||
|
>Polis</span
|
||||||
|
>
|
||||||
|
</MlDropDownItem>
|
||||||
|
</MlDropDown>
|
||||||
|
|
||||||
|
<!-- MlThemeSwitch: A button for toggling between light and dark themes. Does not require additional props for basic functionality. -->
|
||||||
|
<MlThemeSwitch />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MlSlider: Displays a series of items as a slider. Use the :pt prop to style it and the default slot to customize the content of each slide. -->
|
||||||
|
<MlSlider
|
||||||
|
:items="items"
|
||||||
|
:direction="'horizontal'"
|
||||||
|
:pt="{
|
||||||
|
root: { class: '' },
|
||||||
|
slider: { class: 'text-white' },
|
||||||
|
counter: { class: 'max-w-[1200px] mx-auto px-6 container text-black' },
|
||||||
|
progress: { class: 'bg-black mt-4 h-1 transition-all duration-500' },
|
||||||
|
}"
|
||||||
|
class="my-[50px] relative z-30"
|
||||||
|
>
|
||||||
|
<template #default="{ item }">
|
||||||
|
<div
|
||||||
|
class="bg-white/85 backdrop-blur-md mx-auto my-4 rounded-3xl w-80 md:w-[800px] shadow-custom-lrb text-black"
|
||||||
|
>
|
||||||
|
<div class="flex justify-between items-center px-8 py-2 border-b-2">
|
||||||
|
<p class="font-semibold text-[12px] uppercase tracking-widest">
|
||||||
|
{{ item.title }}
|
||||||
|
</p>
|
||||||
|
<div class="bg-black rounded-lg w-5 h-0.5 cursor-pointer"></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex md:flex-row-reverse flex-col gap-8 py-12 md:py-8 md:w-[800px]"
|
||||||
|
>
|
||||||
|
<div class="flex justify-center w-full">
|
||||||
|
<!-- Placeholder for image content -->
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-4 mx-8">
|
||||||
|
<h1 class="font-bold text-2xl md:text-[32px]">
|
||||||
|
{{ item.title }}
|
||||||
|
</h1>
|
||||||
|
<p class="font-ibm text-lg">
|
||||||
|
{{ item.info }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</MlSlider>
|
||||||
|
|
||||||
|
<!-- MlSliderPoint: Similar to MlSlider but intended for full-page content viewing. Customize its layout and appearance using the :pt prop and slots. -->
|
||||||
|
<div class="flex w-full justify-center text-black">
|
||||||
|
<MlSliderPoint
|
||||||
|
:direction="direction"
|
||||||
|
:pt="{
|
||||||
|
root: {
|
||||||
|
class:
|
||||||
|
'px-5 w-full flex items-center justify-center flex-col md:max-w-[1200px] lg:flex-row md:justify-between md:gap-20 lg:gap-0',
|
||||||
|
},
|
||||||
|
slider: { class: 'w-full h-full md:max-h-[470px]' },
|
||||||
|
counter: { class: 'lg:rotate-90 z-10 w-[220px] md:w-[280px]' },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="opacity-90 mx-auto rounded-3xl w-80 md:max-w-[800px] md:w-full h-full"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex md:flex-row flex-col items-center gap-8 py-12 md:py-0 w-full h-full"
|
||||||
|
>
|
||||||
|
<div class="w-full">
|
||||||
|
<!-- Placeholder for image content -->
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-4 mb-4">
|
||||||
|
<h1 class="font-bold text-2xl md:text-[32px]">YourGold.cz</h1>
|
||||||
|
<div class="flex items-center gap-2 font-ibm">
|
||||||
|
<p class="bg-green-300 px-3 py-1 rounded-md">
|
||||||
|
Tag one
|
||||||
|
</p>
|
||||||
|
<p class="bg-green-300 px-3 py-1 rounded-md">
|
||||||
|
Tag two
|
||||||
|
</p>
|
||||||
|
<p class="bg-green-300 px-3 py-1 rounded-md">
|
||||||
|
Tag three
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p class="font-ibm text-[16px]">
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
Suspendisse varius enim in eros elementum tristique. Duis
|
||||||
|
cursus, mi quis viverra ornare, eros dolor interdum nulla, ut
|
||||||
|
commodo diam libero vitae erat.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MlSliderPoint>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tabber Component: Use this for tabbed data display. Bind the tabs data structure to manage different tab content dynamically. -->
|
||||||
|
<div
|
||||||
|
class="max-w-[1200px] mx-auto border-[1.5px] border-gray-400 rounded-2xl text-black dark:text-white"
|
||||||
|
>
|
||||||
|
<MlTabberBase :tabs="tabs" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// Setup script for handling paginator and tab data.
|
||||||
|
const currentItems = ref([]);
|
||||||
|
const currentPage = ref(1);
|
||||||
|
const handlePaginatedItems = (items) => {
|
||||||
|
currentItems.value = items;
|
||||||
|
};
|
||||||
|
// Array of items to be displayed and managed by MlPaginator.
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title:
|
||||||
|
"How to enforce conventional commits using git-cliff with a CI pipeline?",
|
||||||
|
date: "01.07.2024",
|
||||||
|
persone1: "Natalia Goc",
|
||||||
|
persone2: "Marek Goc",
|
||||||
|
info: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "Understanding JavaScript Promises",
|
||||||
|
date: "02.07.2024",
|
||||||
|
persone1: "John Doe",
|
||||||
|
persone2: "Jane Smith",
|
||||||
|
info: "JavaScript promises are used to handle asynchronous operations. They provide an alternative approach to callbacks by returning a value in the future.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: "An Introduction to WebAssembly",
|
||||||
|
date: "03.07.2024",
|
||||||
|
persone1: "Alice Johnson",
|
||||||
|
persone2: "Bob Brown",
|
||||||
|
info: "WebAssembly is a binary instruction format for a stack-based virtual machine, designed as a portable target for compilation of high-level languages like C, C++, and Rust.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: "Building Responsive Web Applications",
|
||||||
|
date: "04.07.2024",
|
||||||
|
persone1: "Emily White",
|
||||||
|
persone2: "Chris Green",
|
||||||
|
info: "Responsive web design ensures that web applications work well on a variety of devices, providing an optimal user experience across different screen sizes.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: "Exploring the Basics of Machine Learning",
|
||||||
|
date: "05.07.2024",
|
||||||
|
persone1: "Michael Lee",
|
||||||
|
persone2: "Sara Kim",
|
||||||
|
info: "Machine learning is a field of artificial intelligence that uses statistical techniques to give computer systems the ability to learn from data.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
title: "Getting Started with Docker",
|
||||||
|
date: "06.07.2024",
|
||||||
|
persone1: "David Brown",
|
||||||
|
persone2: "Laura Black",
|
||||||
|
info: "Docker is a tool designed to make it easier to create, deploy, and run applications by using containers, which allow a developer to package up an application with all of its parts.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
title: "Introduction to Kubernetes",
|
||||||
|
date: "07.07.2024",
|
||||||
|
persone1: "James Wilson",
|
||||||
|
persone2: "Olivia Martin",
|
||||||
|
info: "Kubernetes is an open-source platform designed to automate deploying, scaling, and operating application containers, providing a framework to run distributed systems resiliently.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Array of tabber to be displayed and managed by MlTabberBase.
|
||||||
|
const tabs = [
|
||||||
|
{
|
||||||
|
header: "Web App Development",
|
||||||
|
content: {
|
||||||
|
title: "Web App Development",
|
||||||
|
info: "From simple business portfolios to complex interactive web applications, we can realize almost any service available through the Web. We will take care of the aesthetics, accessibility, stability and performance of your web application.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "E-commerce",
|
||||||
|
content: {
|
||||||
|
title: "Mobile App Development",
|
||||||
|
info: "E-commerce services have became a fundamental element of many well prospering businesses. Having our own experience with it we will be able to help you with the high expectations of your online customers.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Business Management and ERP Systems",
|
||||||
|
content: {
|
||||||
|
title: "Digital Marketing",
|
||||||
|
info: "Well designed IT infrastructure can be a key element in your company’s success. With us you will discover how modern software can help you manage your business.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Hosting and IT Infrastructure",
|
||||||
|
content: {
|
||||||
|
title: "Web App Development",
|
||||||
|
info: "We are ready to fill any gaps in your infrastructure. Working with us you won’t have to worry about managing complex costs or hardware resources.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "IT Consulting",
|
||||||
|
content: {
|
||||||
|
title: "IT Consulting",
|
||||||
|
info: "We are happy to share our experiences with other companies. Besides free consulting during project cost evaluation we offer our knowledge as an independent and affordable service.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
3
assets/css/main.css
Normal file
3
assets/css/main.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
3
index.js
Normal file
3
index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import MyModule from './modules/module';
|
||||||
|
|
||||||
|
export default MyModule;
|
85
modules/module.ts
Normal file
85
modules/module.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// modules/my-module.ts
|
||||||
|
import {
|
||||||
|
defineNuxtModule,
|
||||||
|
createResolver,
|
||||||
|
addComponent,
|
||||||
|
addImports,
|
||||||
|
} from "@nuxt/kit";
|
||||||
|
|
||||||
|
export interface ModuleOptions {}
|
||||||
|
|
||||||
|
const components = [
|
||||||
|
{
|
||||||
|
name: "MlButton",
|
||||||
|
path: "../src/components/Ml/Button/MlButton.vue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MlPaginator",
|
||||||
|
path: "../src/components/Ml/Paginator/MlPaginator.vue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MlDropDown",
|
||||||
|
path: "../src/components/Ml/DropDown/MlDropDown.vue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MlDropDownItem",
|
||||||
|
path: "../src/components/Ml/DropDown/MlDropDownItem.vue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MlDropDownItem",
|
||||||
|
path: "../src/components/Ml/DropDown/MlDropDownItem.vue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MlSlider",
|
||||||
|
path: "../src/components/Ml/Slider/MlSlider.vue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MlSliderPoint",
|
||||||
|
path: "../src/components/Ml/SliderPoint/MlSliderPoint.vue",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const composables = [
|
||||||
|
{
|
||||||
|
name: "useRipple",
|
||||||
|
path: "../src/composables/useRipple.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "useMergeClasses",
|
||||||
|
path: "../src/composables/useMergeClasses.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "useBounce",
|
||||||
|
path: "../src/composables/useBounce.ts",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "useTailwindConf",
|
||||||
|
path: "../src/composables/useTailwindConf.ts",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export default defineNuxtModule<ModuleOptions>({
|
||||||
|
meta: {
|
||||||
|
name: "module",
|
||||||
|
configKey: "myModule",
|
||||||
|
},
|
||||||
|
defaults: {},
|
||||||
|
setup(_options, _nuxt) {
|
||||||
|
const resolver = createResolver(import.meta.url);
|
||||||
|
|
||||||
|
for (let item of components) {
|
||||||
|
addComponent({
|
||||||
|
name: item.name,
|
||||||
|
filePath: resolver.resolve(item.path),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let item of composables) {
|
||||||
|
addImports([
|
||||||
|
{
|
||||||
|
name: item.name,
|
||||||
|
from: resolver.resolve(item.path),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
@ -1,6 +1,7 @@
|
|||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
modules: ["@nuxtjs/tailwindcss", "@nuxtjs/color-mode"],
|
css: ["./assets/css/main.css"],
|
||||||
|
modules: ["@nuxtjs/tailwindcss", "@nuxtjs/color-mode", "./modules/module.ts"],
|
||||||
compatibilityDate: "2024-04-03",
|
compatibilityDate: "2024-04-03",
|
||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
colorMode: {},
|
colorMode: {},
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "nuxt3-reusable-components",
|
"name": "nuxt3-reusable-components",
|
||||||
"version": "1.1.4",
|
"version": "1.2.6",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "module.ts",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
|
"prepack": "nuxt build",
|
||||||
"dev": "nuxt dev",
|
"dev": "nuxt dev",
|
||||||
"generate": "nuxt generate",
|
"start": "nuxt start"
|
||||||
"preview": "nuxt preview",
|
|
||||||
"postinstall": "nuxt prepare"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/vue": "^2.1.4",
|
"@heroicons/vue": "^2.1.4",
|
||||||
|
@ -1,39 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<button :class="rootClasses" @click="useRipple($event, true)">
|
<button :class="rootClasses" @click="useRipple($event, true)">
|
||||||
<div :class="outerClasses">
|
<div :class="outerClasses">
|
||||||
<div :class="innerClasses">
|
<div :class="innerClasses">
|
||||||
<ml-spinner v-if="spinerPlace == 'prefix' && props.showSpiner" :color="props.spinerColor" :size="props.spinerSize" class="mx-2 fill-accent1" />
|
<slot></slot>
|
||||||
<slot></slot>
|
</div>
|
||||||
<ml-spinner v-if="spinerPlace == 'suffix' && props.showSpiner" :color="props.spinerColor" :size="props.spinerSize" class="mx-2 fill-accent1" />
|
</div>
|
||||||
</div>
|
</button>
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { ButtonProps, PTAttribs } from './types';
|
import { useRipple } from "#imports";
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { computed, ref } from "vue";
|
||||||
|
import type { ButtonProps, PTAttribs } from "./types";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
const props = withDefaults(defineProps<ButtonProps>(), {
|
const props = withDefaults(defineProps<ButtonProps>(), {
|
||||||
rounded: true,
|
rounded: true,
|
||||||
spinerSize: '6',
|
spinerSize: "6",
|
||||||
spinerColor: 'accent1',
|
spinerColor: "accent1",
|
||||||
spinerPlace: 'prefix'
|
spinerPlace: "prefix",
|
||||||
});
|
});
|
||||||
|
|
||||||
const classes = ref({
|
const classes = ref({
|
||||||
root: {
|
root: {
|
||||||
class: `flex justify-center items-center disabled:opacity-60`
|
class: ``,
|
||||||
},
|
},
|
||||||
outer: {
|
outer: {
|
||||||
class: `bg-gradient-to-r from-accent1 to-accent2 p-[2px] w-full focus:outline-none ${props.rounded ? 'rounded-3xl' : ''}`
|
class: ``,
|
||||||
},
|
},
|
||||||
inner: {
|
inner: {
|
||||||
class: `justify-center flex items-center bg-white dark:bg-gradient-to-r px-5 py-2 w-full h-full font-semibold leading-[1.5] back ${props.rounded ? 'rounded-3xl' : ''}`
|
class: ``,
|
||||||
}
|
},
|
||||||
} as PTAttribs);
|
} as PTAttribs);
|
||||||
|
|
||||||
const rootClasses = computed(() => twMerge(classes.value.root?.class, props.pt?.root?.class));
|
const rootClasses = computed(() =>
|
||||||
const innerClasses = computed(() => twMerge(classes.value.inner?.class, props.pt?.inner?.class));
|
twMerge(classes.value.root?.class, props.pt?.root?.class)
|
||||||
const outerClasses = computed(() => twMerge(classes.value.outer?.class, props.pt?.outer?.class));
|
);
|
||||||
|
const innerClasses = computed(() =>
|
||||||
|
twMerge(classes.value.inner?.class, props.pt?.inner?.class)
|
||||||
|
);
|
||||||
|
const outerClasses = computed(() =>
|
||||||
|
twMerge(classes.value.outer?.class, props.pt?.outer?.class)
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
import type { SpinnerSize, SpinnerColor } from '../Spinner/types';
|
|
||||||
|
|
||||||
export type ButtonProps = {
|
export type ButtonProps = {
|
||||||
rounded?: boolean;
|
rounded?: boolean;
|
||||||
pt?: PTAttribs;
|
pt?: PTAttribs;
|
||||||
spinerSize?: SpinnerSize;
|
|
||||||
spinerColor?: SpinnerColor;
|
|
||||||
spinerPlace?: spinerPlace;
|
spinerPlace?: spinerPlace;
|
||||||
showSpiner?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PTAttribs = {
|
export type PTAttribs = {
|
||||||
|
@ -1,61 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-click-outside="closeDropDown" :class="rootPT">
|
<div v-click-outside="closeDropDown" :class="rootPT">
|
||||||
<button
|
<button
|
||||||
id="dropdownDefaultButton"
|
id="dropdownDefaultButton"
|
||||||
data-dropdown-toggle="dropdown"
|
data-dropdown-toggle="dropdown"
|
||||||
:class="titlePT"
|
:class="titlePT"
|
||||||
type="button"
|
type="button"
|
||||||
@click="
|
@click="
|
||||||
useRipple($event, props.ripple);
|
useRipple($event, props.ripple);
|
||||||
openMenu();
|
openMenu();
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ props.title }}
|
{{ props.title }}
|
||||||
<span :class="arrowPT">
|
<span :class="arrowPT">
|
||||||
<ml-arrow></ml-arrow>
|
<ml-arrow></ml-arrow>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<div v-show="isMenuOpen" :class="dropdownPT" @click="isOpen = false">
|
<div v-show="isMenuOpen" :class="dropdownPT" @click="isOpen = false">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { computed, ref } from "vue";
|
||||||
import type { DropDownProps, DropDownPT } from './types';
|
import { useRipple } from "#imports";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
import type { DropDownProps, DropDownPT } from "./types";
|
||||||
|
|
||||||
const props = withDefaults(defineProps<DropDownProps>(), {
|
const props = withDefaults(defineProps<DropDownProps>(), {
|
||||||
isOpen: false
|
isOpen: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const PT = {
|
const PT = {
|
||||||
root: {
|
root: {
|
||||||
class: 'relative pointer'
|
class: "",
|
||||||
},
|
},
|
||||||
dropdown: {
|
dropdown: {
|
||||||
class: 'z-10 absolute bg-white dark:bg-BgDark/85 rounded-3xl pointer text-black dark:text-white text-center'
|
class:
|
||||||
},
|
"z-10 absolute bg-white rounded-3xl pointer text-black text-center",
|
||||||
title: {
|
},
|
||||||
class: 'text-black dark:text-BgLight inline-flex items-center rounded-lg font-medium text-center text-base pointer '
|
title: {
|
||||||
},
|
class:
|
||||||
arrow: {
|
"text-black inline-flex items-center rounded-lg font-medium text-center text-base pointer ",
|
||||||
class: 'px-2'
|
},
|
||||||
}
|
arrow: {
|
||||||
|
class: "px-2",
|
||||||
|
},
|
||||||
} as DropDownPT;
|
} as DropDownPT;
|
||||||
|
|
||||||
const rootPT = computed(() => twMerge(PT.root?.class, props.pt?.root?.class));
|
const rootPT = computed(() => twMerge(PT.root?.class, props.pt?.root?.class));
|
||||||
const titlePT = computed(() => twMerge(PT.title?.class, props.pt?.title?.class));
|
const titlePT = computed(() =>
|
||||||
const dropdownPT = computed(() => twMerge(PT.dropdown?.class, props.pt?.dropdown?.class));
|
twMerge(PT.title?.class, props.pt?.title?.class)
|
||||||
const arrowPT = computed(() => twMerge(PT.arrow?.class, props.pt?.arrow?.class));
|
);
|
||||||
|
const dropdownPT = computed(() =>
|
||||||
|
twMerge(PT.dropdown?.class, props.pt?.dropdown?.class)
|
||||||
|
);
|
||||||
|
const arrowPT = computed(() =>
|
||||||
|
twMerge(PT.arrow?.class, props.pt?.arrow?.class)
|
||||||
|
);
|
||||||
|
|
||||||
const isOpen = ref(props.isOpen);
|
const isOpen = ref(props.isOpen);
|
||||||
|
|
||||||
function openMenu() {
|
function openMenu() {
|
||||||
isOpen.value = !isOpen.value;
|
isOpen.value = !isOpen.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDropDown() {
|
function closeDropDown() {
|
||||||
isOpen.value = false;
|
isOpen.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMenuOpen = computed(() => isOpen.value);
|
const isMenuOpen = computed(() => isOpen.value);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from "vue";
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { twMerge } from 'tailwind-merge';
|
||||||
import type { DropDownItemPT, DropDownItemProps } from './types';
|
import type { DropDownItemPT, DropDownItemProps } from './types';
|
||||||
|
|
||||||
|
@ -29,10 +29,7 @@
|
|||||||
</swiper>
|
</swiper>
|
||||||
<div>
|
<div>
|
||||||
<div :class="counterClasses">
|
<div :class="counterClasses">
|
||||||
<div
|
<div :class="progressClass" :style="`width: ${progerssBar}%`"></div>
|
||||||
class="bg-BgDark dark:bg-BgLight mt-4 h-1 transition-all duration-500"
|
|
||||||
:style="`width: ${progerssBar}%`"
|
|
||||||
></div>
|
|
||||||
<div class="flex justify-between my-4">
|
<div class="flex justify-between my-4">
|
||||||
<button
|
<button
|
||||||
:disabled="isPrevDisabled"
|
:disabled="isPrevDisabled"
|
||||||
@ -61,6 +58,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useRipple } from "#imports";
|
||||||
import { ref, computed, defineProps, withDefaults } from "vue";
|
import { ref, computed, defineProps, withDefaults } from "vue";
|
||||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||||
import type { Swiper as swiper } from "swiper/types";
|
import type { Swiper as swiper } from "swiper/types";
|
||||||
@ -121,9 +119,12 @@ const classes = ref({
|
|||||||
class: ``,
|
class: ``,
|
||||||
},
|
},
|
||||||
counter: {
|
counter: {
|
||||||
class: `max-w-[1200px] mx-auto px-6 container`,
|
class: ``,
|
||||||
},
|
},
|
||||||
} as PTAttribs);
|
progress: {
|
||||||
|
class: "",
|
||||||
|
},
|
||||||
|
} as unknown as PTAttribs);
|
||||||
|
|
||||||
const rootClasses = computed(() =>
|
const rootClasses = computed(() =>
|
||||||
twMerge(classes.value.root?.class, props.pt?.root?.class)
|
twMerge(classes.value.root?.class, props.pt?.root?.class)
|
||||||
@ -134,6 +135,9 @@ const sliderClasses = computed(() =>
|
|||||||
const counterClasses = computed(() =>
|
const counterClasses = computed(() =>
|
||||||
twMerge(classes.value.counter?.class, props.pt?.counter?.class)
|
twMerge(classes.value.counter?.class, props.pt?.counter?.class)
|
||||||
);
|
);
|
||||||
|
const progressClass = computed(() =>
|
||||||
|
twMerge(classes.value.progress?.class, props.pt?.progress?.class)
|
||||||
|
);
|
||||||
|
|
||||||
const items = props.items;
|
const items = props.items;
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,22 +1,25 @@
|
|||||||
export type SliderProps = {
|
export type SliderProps = {
|
||||||
direction: 'horizontal' | 'vertical';
|
direction: "horizontal" | "vertical";
|
||||||
pt?: PTAttribs;
|
pt?: PTAttribs;
|
||||||
items: Array<[{ title: string; info: string }]>;
|
items: Array<[{ title: string; info: string }]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PTAttribs = {
|
export type PTAttribs = {
|
||||||
root?: {
|
root?: {
|
||||||
class: string;
|
class: string;
|
||||||
};
|
};
|
||||||
slider?: {
|
slider?: {
|
||||||
class: string;
|
class: string;
|
||||||
};
|
};
|
||||||
counter?: {
|
counter?: {
|
||||||
class: string;
|
class: string;
|
||||||
};
|
};
|
||||||
direction?: {
|
direction?: {
|
||||||
direction: string;
|
direction: string;
|
||||||
};
|
};
|
||||||
|
progress?: {
|
||||||
|
class: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type spinerPlace = 'suffix' | 'prefix';
|
export type spinerPlace = "suffix" | "prefix";
|
||||||
|
@ -19,18 +19,15 @@
|
|||||||
<slot />
|
<slot />
|
||||||
</swiper-slide>
|
</swiper-slide>
|
||||||
</swiper>
|
</swiper>
|
||||||
<div
|
<div :class="counterClasses">
|
||||||
class="flex justify-between items-center h-10 cursor-pointer"
|
|
||||||
:class="counterClasses"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
v-for="(slide, index) in 4"
|
v-for="(slide, index) in 4"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="[
|
:class="[
|
||||||
'bg-BgDark dark:bg-BgLight h-[3px] transition-all duration-500',
|
'bg-black h-[3px] transition-all duration-500',
|
||||||
index === currentSlideNumber
|
index === currentSlideNumber
|
||||||
? 'py-2 w-[16px] rounded-3xl'
|
? 'bg-black py-2 w-[16px] rounded-3xl'
|
||||||
: 'w-[25px] rounded-sm md:w-[24px]',
|
: 'h-[3px] bg-black w-[25px] rounded-sm md:w-[24px]',
|
||||||
]"
|
]"
|
||||||
@click="goToSlide(index), stopAutoSlide()"
|
@click="goToSlide(index), stopAutoSlide()"
|
||||||
></div>
|
></div>
|
||||||
@ -96,7 +93,9 @@ const props = withDefaults(
|
|||||||
const classes = ref({
|
const classes = ref({
|
||||||
root: { class: `` },
|
root: { class: `` },
|
||||||
slider: { class: `` },
|
slider: { class: `` },
|
||||||
counter: { class: `mx-auto px-6 container` },
|
counter: {
|
||||||
|
class: `mx-auto px-6 container flex justify-between items-center h-10 cursor-pointer`,
|
||||||
|
},
|
||||||
} as PTAttribs);
|
} as PTAttribs);
|
||||||
|
|
||||||
const rootClasses = computed(() =>
|
const rootClasses = computed(() =>
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
import { defineNuxtModule, addComponentsDir } from '@nuxt/kit'
|
|
||||||
|
|
||||||
export default defineNuxtModule({
|
|
||||||
setup(options, nuxt) {
|
|
||||||
addComponentsDir({
|
|
||||||
path: '~/components/Ml',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
@ -2,10 +2,8 @@
|
|||||||
export default {
|
export default {
|
||||||
content: [
|
content: [
|
||||||
"./components/**/*.{vue,js}",
|
"./components/**/*.{vue,js}",
|
||||||
"./layouts/**/*.vue",
|
|
||||||
"./pages/**/*.vue",
|
|
||||||
"./plugins/**/*.{js,ts}",
|
|
||||||
"./nuxt.config.{js,ts}",
|
"./nuxt.config.{js,ts}",
|
||||||
|
"./src/**/*.{vue,js,ts}",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
const webpack = require("webpack");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
entry: "./src/index.js",
|
|
||||||
output: {
|
|
||||||
path: "./dist/",
|
|
||||||
filename: "index.js",
|
|
||||||
library: "VuejsPaginate",
|
|
||||||
libraryTarget: "umd",
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
extensions: ["", ".js", ".vue"],
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /\.vue$/,
|
|
||||||
loader: "vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.js$/,
|
|
||||||
loader: "babel",
|
|
||||||
include: __dirname,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
|
||||||
minimize: true,
|
|
||||||
sourceMap: false,
|
|
||||||
mangle: true,
|
|
||||||
compress: {
|
|
||||||
warnings: false,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
};
|
|
Reference in New Issue
Block a user