# Animated components for Vue and Nuxt. # Getting Started Welcome to [**Inspira UI**](https://inspira-ui.com){rel=""nofollow""}, a community-driven project for [Vue](https://vuejs.org){rel=""nofollow""}! This collection offers beautifully designed, reusable components, taking inspiration from the amazing work done on both [Aceternity UI](https://ui.aceternity.com){rel=""nofollow""} and [Magic UI](https://magicui.design){rel=""nofollow""}. While we're not officially affiliated with these projects, we have received permission from Aceternity UI's creator to adapt those fantastic designs for the Vue ecosystem. Additionally, Inspira UI includes custom components developed by us and contributed by the community. ### About Inspira UI Inspira UI is **not** a traditional component library. Instead, it's a curated collection of elegant components you can easily integrate into your applications. Simply pick what you need, copy the code, and customize it to fit your project. The code is yours to use and modify as you like! ### Why Inspira UI? This project began to fill a gap in the Vue community for a similar set of components. Inspira UI brings the beauty and functionality of Aceternity UI, Magic UI, and custom contributions to Vue, making it easier for developers to build stunning applications. ### Key Features - Completely [free and open source](https://github.com/unovue/inspira-ui){rel=""nofollow""} - Highly [configurable](https://inspira-ui.com/components) to meet your design needs - A wide range of [components](https://inspira-ui.com/components) to choose from - Optimized for mobile use - Fully compatible with Nuxt ### Acknowledgments Special thanks to: - [Aceternity UI](https://ui.aceternity.com){rel=""nofollow""} for inspiring this Vue adaptation. - [Magic UI](https://magicui.design){rel=""nofollow""} for their design inspiration. - [shadcn-vue](https://www.shadcn-vue.com/){rel=""nofollow""} for the Vue port of shadcn-ui and contributing some components for docs. - [shadcn-docs-nuxt](https://github.com/ZTL-UwU/shadcn-docs-nuxt){rel=""nofollow""} for the beautifully crafted Nuxt documentation site. ### About Me Hi, I'm [Rahul Vashishtha](https://rahulv.dev){rel=""nofollow""}. I started Inspira UI to bring a similar experience to the Vue ecosystem, inspired by Aceternity UI, Magic UI, and community contributions. I'm continuously working on it to make it better. Feel free to check out my work on [GitHub](https://github.com/rahul-vashishtha){rel=""nofollow""} and join me on this journey [here](https://github.com/unovue/inspira-ui){rel=""nofollow""}! Feel free to explore and enjoy building with Inspira UI! # Installation This guide will help you install and set up Inspira UI components in your Vue or Nuxt application. ::warning If you are using Tailwind CSS v3, **[Checkout Inspira UI v1 here](https://v1.inspira-ui.com){rel=""nofollow""}.** :: ## Getting Started with Inspira UI ::steps ### Set up `tailwindcss` To begin, install `tailwindcss` using this [Vite install guide for Vue](https://tailwindcss.com/docs/installation){rel=""nofollow""} or using this [framework-specific guide for Nuxt](https://tailwindcss.com/docs/installation/framework-guides/nuxt){rel=""nofollow""}. ### Add dependencies Install following supporting libraries. :::code-group ```bash [npm] npm install @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ```bash [pnpm] pnpm install @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ```bash [bun] bun add @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ```bash [yarn] yarn add @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ::: Follow this guide to setup `motion-v` on [Vue or Nuxt](https://motion.dev/docs/vue){rel=""nofollow""}. ### Update your `main.css` file :::tip Skip this step if you are using `shadcn-vue` . ::: Add the following code to your `main.css` file, this setup the variable required for the components: :::tabs{.w-full} ::::tabs-item{icon="simple-icons:nuxt" label="Nuxt UI"} :::::code-collapse ```css [main.css] @import "tailwindcss"; @import "@nuxt/ui"; @theme static { --color-background: var(--ui-bg); --color-foreground: var(--ui-text); --color-card: var(--ui-bg-elevated); --color-card-foreground: var(--ui-text); --color-popover: var(--ui-bg-elevated); --color-popover-foreground: var(--ui-text); --color-muted: var(--ui-bg-muted); --color-muted-foreground: var(--ui-text-muted); --color-accent: var(--ui-bg-accented); --color-accent-foreground: var(--ui-text); --color-border: var(--ui-border); --color-input: var(--ui-border); --color-primary: var(--ui-primary); --color-primary-foreground: var(--ui-text-inverted); --color-secondary: var(--ui-secondary); --color-secondary-foreground: var(--ui-text-inverted); --color-destructive: var(--ui-error); --color-destructive-foreground: var(--ui-text-inverted); --color-ring: var(--ui-primary); --radius: var(--ui-radius); } :root { --background: var(--ui-bg); --foreground: var(--ui-text); --card: var(--ui-bg-elevated); --card-foreground: var(--ui-text); --popover: var(--ui-bg-elevated); --popover-foreground: var(--ui-text); --muted: var(--ui-bg-muted); --muted-foreground: var(--ui-text-muted); --accent: var(--ui-bg-accented); --accent-foreground: var(--ui-text); --border: var(--ui-border); --input: var(--ui-border); --primary: var(--ui-primary); --primary-foreground: var(--ui-text-inverted); --secondary: var(--ui-secondary); --secondary-foreground: var(--ui-text-inverted); --destructive: var(--ui-error); --destructive-foreground: var(--ui-text-inverted); --ring: var(--ui-primary); } ``` ::::: :::: ::::tabs-item{icon="simple-icons:tailwindcss" label="Other TailwindCSS Kit"} :::::code-collapse ```css [main.css] @import "tailwindcss"; @import "tw-animate-css"; @custom-variant dark (&:is(.dark *)); :root { --card: oklch(1 0 0); --card-foreground: oklch(0.141 0.005 285.823); --popover: oklch(1 0 0); --popover-foreground: oklch(0.141 0.005 285.823); --primary: oklch(0.21 0.006 285.885); --primary-foreground: oklch(0.985 0 0); --secondary: oklch(0.967 0.001 286.375); --secondary-foreground: oklch(0.21 0.006 285.885); --muted: oklch(0.967 0.001 286.375); --muted-foreground: oklch(0.552 0.016 285.938); --accent: oklch(0.967 0.001 286.375); --accent-foreground: oklch(0.21 0.006 285.885); --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: oklch(0.577 0.245 27.325); --border: oklch(0.92 0.004 286.32); --input: oklch(0.92 0.004 286.32); --ring: oklch(0.705 0.015 286.067); --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.141 0.005 285.823); } .dark { --background: oklch(0.141 0.005 285.823); --foreground: oklch(0.985 0 0); --card: oklch(0.141 0.005 285.823); --card-foreground: oklch(0.985 0 0); --popover: oklch(0.141 0.005 285.823); --popover-foreground: oklch(0.985 0 0); --primary: oklch(0.985 0 0); --primary-foreground: oklch(0.21 0.006 285.885); --secondary: oklch(0.274 0.006 286.033); --secondary-foreground: oklch(0.985 0 0); --muted: oklch(0.274 0.006 286.033); --muted-foreground: oklch(0.705 0.015 286.067); --accent: oklch(0.274 0.006 286.033); --accent-foreground: oklch(0.985 0 0); --destructive: oklch(0.396 0.141 25.723); --destructive-foreground: oklch(0.637 0.237 25.331); --border: oklch(0.274 0.006 286.033); --input: oklch(0.274 0.006 286.033); --ring: oklch(0.442 0.017 285.786); } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); } @layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } } html { color-scheme: light dark; } html.dark { color-scheme: dark; } html.light { color-scheme: light; } ``` ::::: :::: ::: :: ::tip{.mt-12 icon="tabler:check"} Great job! Your project is now configured to use Inspira UI. :: ### Optional: Add Icon Support A variety of Inspira UI components and demos utilize the `` component with Iconify icons. Although optional, we recommend installing it for an optimal experience. To add icon support to your Vue.js or Nuxt.js project, please follow the [Iconify Vue guide](https://iconify.design/docs/icon-components/vue/){rel=""nofollow""}. ### Start Using Inspira UI 🚀 Now, you can start using Inspira UI components in your project. Choose the components you need, copy the code, and integrate them into your application. # How To Contribute Thank you for your interest in contributing to the **Inspira UI** project! Your contributions help make this project better for everyone. Please take a moment to read through these guidelines to ensure a smooth collaboration. ## Table of Contents 1. [Getting Started](https://inspira-ui.com/#getting-started) 2. [Code of Conduct](https://inspira-ui.com/#code-of-conduct) 3. [How to Contribute](https://inspira-ui.com/#how-to-contribute) - [Reporting Bugs](https://inspira-ui.com/#reporting-bugs) - [Suggesting Enhancements](https://inspira-ui.com/#suggesting-enhancements) - [Adding New Components](https://inspira-ui.com/#adding-new-components) 4. [Project Structure](https://inspira-ui.com/#project-structure) 5. [Style Guidelines](https://inspira-ui.com/#style-guidelines) - [Coding Standards](https://inspira-ui.com/#coding-standards) - [Component Format](https://inspira-ui.com/#component-format) - [Commit Messages](https://inspira-ui.com/#commit-messages) 6. [Documentation Guidelines](https://inspira-ui.com/#documentation-guidelines) - [Single-File Components](https://inspira-ui.com/#single-file-components) - [Multi-File Components](https://inspira-ui.com/#multi-file-components) 7. [Testing](https://inspira-ui.com/#testing) 8. [License](https://inspira-ui.com/#license) --- ## Getting Started - **Fork the Repository**: Create a personal fork of the project on GitHub. - **Clone Your Fork**: Clone your forked repository to your local machine. - **Create a Branch**: Create a new branch for your contribution (`git checkout -b feature/YourFeatureName`). - **Install Dependencies**: Run `pnpm install` to install all necessary dependencies. ## Code of Conduct By participating in this project, you agree to abide by the [Code of Conduct](https://inspira-ui.com/code-of-conduct), which aims to foster an open and welcoming environment. ## How to Contribute ### Reporting Bugs If you find a bug, please open an [issue](https://github.com/unovue/inspira-ui/issues){:target="\_blank" rel=""nofollow""} and include: - A clear and descriptive title. - Steps to reproduce the issue. - Expected and actual results. - Screenshots or code snippets, if applicable. ### Suggesting Enhancements We welcome suggestions for new features or improvements. Please open an [issue](https://github.com/unovue/inspira-ui/issues){:target="\_blank" rel=""nofollow""} and include: - A clear and descriptive title. - A detailed description of the enhancement. - Any relevant examples or mockups. ### Adding New Components We appreciate contributions that add new components to the library. Please ensure that: - The component is generally useful and aligns with the project's goals. - The component is compatible with both **Nuxt** and **Vue**. - You follow the coding and documentation guidelines outlined below. - You include unit tests for your component. #### Components guidelines 1. **Create or Update `index.ts`**:br Each folder under `components/content/inspira/ui//` should have an `index.ts` that exports all Vue files. For example: ```ts // index.ts export { default as Book } from "./Book.vue"; export { default as BookDescription } from "./BookDescription.vue"; export { default as BookHeader } from "./BookHeader.vue"; export { default as BookTitle } from "./BookTitle.vue"; ``` 2. **Registry Dependencies:** If your new component depends on (or uses) other Inspira UI components, you must update the `COMPONENT_DEPENDENCIES` map in `~/scripts/crawl-content.ts` to reflect those relationships. This helps the library understand which components should be installed together when a user adds them via the CLI. 3. **Nuxt-Only Features:** If your new component or its example uses Nuxt-only features such as ``, please mention this in the documentation. This ensures users know there may be limitations or additional steps when using the component outside of Nuxt. :br This ensures that users can install the component through the CLI and that all dependencies are properly declared. 4. **Avoid External Components:** When creating components, avoid using external UI components (like `` or similar) that are not part of the core Vue.js ecosystem. 5. **Explicit Imports:** Even if you're using Nuxt's auto-imports feature during development, always include explicit imports in your component code. This ensures compatibility with Vue.js users who don't have auto-imports. For example: ```vue ``` 6. **Icon Usage:** If you need icons in your demos or components, use the built-in `` component rather than pasting raw SVGs into your templates. ## Project Structure Understanding the project structure is crucial for effective contribution: - **Components Directory**: - Main components should be placed in `components/content/inspira/ui//`. - Include an `index.ts` file to export each component within that folder. - Example components should be placed in `components/content/inspira/examples//`. - **Documentation**: - Documentation files are located in the `content/2.components//` directory. - After adding a component, write its documentation in this directory. ## Style Guidelines ### Coding Standards - **Language**: All components should be written in **Vue.js** with TypeScript support. - **Styling**: Use **Tailwind CSS** classes for styling whenever possible. - **Naming Conventions**: Use `PascalCase` for component names and filenames. ### Component Format Your Vue components should adhere to the following structure: ```vue ``` **Props typing and code style** Refer to this Vue.js documentation page -> {rel=""nofollow""} ```vue ``` **Constants, interfaces, types and variants** For reusability purposes, you can also add an `index.ts` file at the root of the component folder to export interfaces, constants, and other useful code elements. Keep in mind that developers will copy and paste the component code into their projects, so it should be very easy to customize according to their standards. Contants have to be `CAPS_CAMEL_CASE` in order to identify them clearly inside the code. And `prefix` them. Please never use Enums; use `{} as const` instead. 😘 ```typescript // DON'T ⛔ const Direction = { Top: 'top'} as const const ComponentNameDirection = { Top: 'top'} as const // DON'T ⛔ enum COMPONENT_NAME_DIRECTION_WRONG = { Top = 'top'}; // DO ✅ import type { ObjectValues } from "@/lib/utils"; export const COMPONENT_NAME_DIRECTION = { Top: 'top', Bottom: 'bottom'} as const //Types and Interfaces should use CamelCase to differentiate them from constants and variables. export type ComponentNameDirection = ObjectValues; interface { direction: ComponentNameDirection; //Enforce correct value : 'top' or 'bottom' } ``` You can check the `PatternBackground` component files `components/content/inspira/ui/pattern-background` for a complete example. **Notes:** - Use ` ``` #credits - Ported from [Fancy Components](https://fancycomponents.dev/docs/components/blocks/stacking-cards){rel=""nofollow""}. :: # Cube Carousel ::component-viewer --- component-files: - CubeCarousel.vue - index.ts component-id: cube-carousel config: CubeCarouselConfig demo-file: CubeCarouselDemo.vue --- #api ## API ### `CubeCarousel` | Prop Name | Type | Default | Description | | ------------------ | ------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------- | | `items` | `CubeCarouselItem[]` | — | Four or more image or video items to place on the cube faces. | | `width` | `number` | — | Width of each face in pixels. | | `height` | `number` | — | Height of each face in pixels. | | `class` | `string` | — | Additional classes for the carousel root. | | `debug` | `boolean` | `false` | Shows face colors and item IDs for inspecting the cube. | | `perspective` | `number` | `600` | CSS perspective distance in pixels. | | `direction` | `"top" | "bottom" | "left" | "right"` | `"left"` | Rotation axis and direction. | | `transition` | `Record` | `{ duration: 1.25, ease: [...] }` | Motion transition used for button and keyboard rotations. | | `snapTransition` | `Record` | `{ type: "spring", damping: 30, stiffness: 200 }` | Transition used when drag snaps to a face. | | `dragSpring` | `CubeCarouselSpringConfig` | `{ stiffness: 200, damping: 30 }` | Spring used while following pointer drag. | | `autoPlay` | `boolean` | `false` | Automatically advances through the items. | | `autoPlayInterval` | `number` | `3000` | Delay between autoplay rotations in milliseconds. | | `onIndexChange` | `(index: number) => void` | — | Called after a rotation finishes. | | `enableDrag` | `boolean` | `true` | Enables pointer and touch drag interaction. | | `dragSensitivity` | `number` | `0.5` | Rotation amount produced by pointer movement. | ### `CubeCarouselItem` | Property | Type | Required | Description | | -------- | ------------------- | -------- | --------------------------------- | | `id` | `string` | Yes | Stable identifier for the item. | | `type` | `"image" | "video"` | Yes | Selects the media renderer. | | `src` | `string` | Yes | Image or video source URL. | | `alt` | `string` | No | Alternative text for image items. | | `poster` | `string` | No | Poster image URL for video items. | ## Interaction Drag along the carousel axis to rotate it. Release to snap to the nearest quarter-turn. When the carousel is focused, use the arrow keys matching its axis. The exposed `next`, `prev`, and `getCurrentItemIndex` methods can also control it from a parent component. ```vue ``` #credits - Ported from [Fancy Components Box Carousel](https://fancycomponents.dev/docs/components/carousel/box-carousel){rel=""nofollow""}. - Demo artwork by [Daniel Petho](https://www.cosmos.so/danielpetho/box-carousel-demo){rel=""nofollow""}. - Inspired by [Framer University](https://framer.university/resources/3d-box-carousel-in-framer){rel=""nofollow""}. :: # Direction Aware Hover Card ::component-viewer --- component-files: - DirectionAwareHover.vue component-id: direction-aware-hover config: DirectionAwareHoverConfig demo-file: DirectionAwareHoverDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------------- | -------- | ----------- | ----------------------------------------------- | | `imageUrl` | `string` | Required | The URL of the image to be displayed. | | `class` | `string` | `undefined` | Additional CSS classes for the card container. | | `imageClass` | `string` | `undefined` | Additional CSS classes for the image element. | | `childrenClass` | `string` | `undefined` | Additional CSS classes for the content overlay. | #credits - Credits to [M Atif](https://github.com/atif0075){rel=""nofollow""} for porting this component. - Ported from [Aceternity UI's Direction Aware Hover](https://ui.aceternity.com/components/direction-aware-hover){rel=""nofollow""} :: # Fey Cards ::component-viewer --- component-files: - FeyCards.vue component-id: fey-cards config: FeyCardsConfig demo-file: FeyCardsDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ----------------- | -------------- | ------------------------------------------------------ | ------------------------------------------------------------------ | | `imgSrc` | `string[]` | `[]` | Array of image sources used for the stacked cards. | | `mainImg` | `string` | `-` | Main image shown behind the card stack. | | `idleImg` | `string` | `-` | Idle image shown before the hovered swap effect. | | `cardSpacing` | `number` | `32` | Horizontal spacing between stacked cards. | | `spring` | `SpringConfig` | `{ type: "spring", visualDuration: 0.5, bounce: 0.2 }` | Motion spring configuration for the entrance and shift animations. | | `shiftDistance` | `number` | `60` | Distance cards move horizontally when a hover state is active. | | `swapDuration` | `number` | `0.5` | Duration of the image swap transition in seconds. | | `entranceStagger` | `number` | `0.2` | Delay between the entrance animations of each card. | | `class` | `string` | `-` | Additional Tailwind classes applied to the wrapper. | #credits - Inspired by [Aceternity UI](https://ui.aceternity.com/labs/fey-card){rel=""nofollow""}. :: # Flip Card ::component-viewer --- component-files: - FlipCard.vue component-id: flip-card config: FlipCardConfig demo-file: FlipCardDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | ------------------------------------------ | | `class` | `string` | `-` | The class to be applied to the component. | | `rotate` | `x | y` | `y` | You can pass the rotate value as you want. | | Slot Name | Description | | --------- | --------------------------- | | `default` | Component to show as front. | | `back` | Component to show as back. | #credits - Credits to [SivaReddy Uppathi](https://github.com/sivareddyuppathi){rel=""nofollow""} for this component. :: # Floating Card ::component-viewer --- component-files: - FloatingCard.vue component-id: floating-card config: FloatingCardConfig demo-file: FloatingCardDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------- | -------- | ------- | ------------------------------------------------------- | | `rotateDepth` | `number` | `17.5` | Maximum X/Y rotation applied while the card is hovered. | | `translateDepth` | `number` | `20` | Maximum X/Y translation applied while tracking cursor. | | `class` | `string` | `-` | Additional Tailwind classes applied to the wrapper. | #credits - Inspired by [Aceternity UI](https://ui.aceternity.com/components/comet-card){rel=""nofollow""}. :: # Glare Card ::component-viewer --- component-files: - GlareCard.vue component-id: glare-card config: GlareCardConfig demo-file: GlareCardDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | --------------------------------------------------------- | | `class` | `string` | `-` | Additional Tailwind CSS class names to apply to the card. | #credits - Credits to [SivaReddy Uppathi](https://github.com/sivareddyuppathi){rel=""nofollow""} for this component. - Inspired from [Aceternity UI](https://ui.aceternity.com/components/glare-card){rel=""nofollow""}. :: # Fluid Cursor ::component-viewer --- component-files: - FluidCursor.vue component-id: fluid-cursor config: FluidCursorConfig demo-file: FluidCursorDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------------------- | --------- | ------------------------ | ---------------------------------------------------------------------------------- | | `simResolution` | `number` | `128` | Resolution for the simulation grid affecting fluid detail and performance. | | `dyeResolution` | `number` | `1440` | Resolution for the fluid dye (color) texture. | | `captureResolution` | `number` | `512` | Resolution for capturing input events. | | `densityDissipation` | `number` | `3.5` | Rate at which color density dissipates over time. | | `velocityDissipation` | `number` | `2` | Rate at which velocity dissipates over time, affecting fluid momentum persistence. | | `pressure` | `number` | `0.1` | Pressure factor used in fluid physics calculations. | | `pressureIterations` | `number` | `20` | Number of iterations for pressure solver accuracy. | | `curl` | `number` | `3` | Intensity of curl/vorticity effect to enhance swirling motions. | | `splatRadius` | `number` | `0.2` | Radius of the pointer's splat effect in the fluid. | | `splatForce` | `number` | `6000` | Force applied by the pointer to the fluid on interaction. | | `shading` | `boolean` | `true` | Enable or disable shading effects for depth and light on fluid colors. | | `colorUpdateSpeed` | `number` | `10` | Speed at which pointer colors update dynamically. | | `backColor` | `object` | `{ r: 0.5, g: 0, b: 0 }` | Background color of the fluid in RGB format. | | `transparent` | `boolean` | `true` | Whether the canvas background is transparent. | | `class` | `string` | `undefined` | Additional CSS classes for the outer container div. | #credits - Inspired from [Fluid Cursor by Cursify](https://cursify.vercel.app/components/fluid-cursor){rel=""nofollow""} - Utilizes WebGL 1/2 context and custom GLSL shaders for fluid physics and rendering. :: # Image Trail Cursor ::component-viewer --- component-files: - ImageTrailCursor.vue - trail-variants.ts component-id: image-trail-cursor config: ImageTrailCursorConfig demo-file: ImageTrailCursorDemo.vue dependencies: gsap --- #api ## API | Prop Name | Type | Default | Description | | --------- | ------------- | --------- | ------------------------------------------------------ | | `images` | `string[]` | `[]` | Array of image URLs to display in the trailing effect. | | `variant` | `VariantType` | `"type1"` | Animation variant type (`"type1"` through `"type7"`). | > 💡 This component creates a full-width, full-height container with high z-index for cursor tracking. Each image is 190px wide with a 1.1 aspect ratio and rounded corners. #credits - Inspired by modern cursor trail effects and image hover interactions. - Built with Vue 3 Composition API for optimal reactivity and performance. - Ported from [Codrops Article](https://tympanus.net/codrops/2023/10/18/ideas-for-image-motion-trail-animations/){rel=""nofollow""} :: # Sleek Line Cursor ::component-viewer --- component-files: - SleekLineCursor.vue component-id: sleek-line-cursor config: SleekLineCursorConfig demo-file: SleekLineCursorDemo.vue --- ## API | Prop Name | Type | Default | Description | | ----------- | ------------------- | ----------- | ------------------------------------------------------------------------- | | `class` | `string | string[]` | `undefined` | Additional CSS classes for the canvas container element. | | `trails` | `number` | `20` | Number of trailing lines rendered behind the cursor. | | `size` | `number` | `50` | Number of spring-connected nodes per trail. | | `friction` | `number` | `0.5` | Global friction applied to velocity. | | `dampening` | `number` | `0.25` | Velocity damping applied between connected nodes. | | `tension` | `number` | `0.98` | Reduces spring intensity across the tail, giving a fluid tapering motion. | > 💡 This component uses `pointer-events-none` and is fixed fullscreen by default. You can extend or override its styling via the `class` prop. #credits - Ported from [Canvas Cursor by Cursify](https://cursify.vercel.app/components/canvas-cursor){rel=""nofollow""}. :: # Smooth Cursor ::component-viewer --- component-files: - SmoothCursor.vue component-id: smooth-cursor config: SmoothCursorConfig demo-file: SmoothCursorDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | -------------- | --------------- | ------------------------------------------------------- | | `cursor` | `Component` | `DefaultCursor` | Custom cursor component to replace the default cursor | | `springConfig` | `SpringConfig` | `See below` | Configuration object for the spring animation behavior. | ### SpringConfig Type ```ts interface springConfig { damping: number; stiffness: number; mass: number; restDelta: number; } ``` #credits - Credits to [Whbbit1999](https://github.com/Whbbit1999){rel=""nofollow""} for this component. - Ported from [Magic UI Smooth Cursor](https://magicui.design/docs/components/smooth-cursor){rel=""nofollow""}. :: # Tailed Cursor ::component-viewer --- component-files: - TailedCursor.vue component-id: tailed-cursor config: TailedCursorConfig demo-file: TailedCursorDemo.vue dependencies: ogl --- #api ## API | Prop Name | Type | Default | Description | | -------------------- | ---------- | ---------------------------------------------- | ------------------------------------------------------------ | | `colors` | `string[]` | `["#ff9346", "#7cff67", "#ffee51", "#00d8ff"]` | Array of colors for each tail ribbon. | | `baseSpring` | `number` | `0.03` | Spring strength for tail movement responsiveness. | | `baseFriction` | `number` | `0.9` | Friction factor slowing down the tail movement. | | `baseThickness` | `number` | `30` | Base thickness of the tail ribbons. | | `offsetFactor` | `number` | `0.05` | Horizontal offset factor between each ribbon line. | | `maxAge` | `number` | `500` | Maximum age for tail segments controlling their fade timing. | | `pointCount` | `number` | `50` | Number of points composing each ribbon tail. | | `speedMultiplier` | `number` | `0.6` | Speed multiplier controlling the animation speed. | | `enableFade` | `boolean` | `false` | Enables fading effect on tail edges. | | `enableShaderEffect` | `boolean` | `false` | Enables dynamic shader wave effect on ribbons. | | `effectAmplitude` | `number` | `2` | Amplitude of the shader wave effect when enabled. | | `backgroundColor` | `number[]` | `[0, 0, 0, 0]` | RGBA background clear color for the WebGL canvas. | #credits - Built with [OGL](https://github.com/oframe/ogl){rel=""nofollow""}, a lightweight WebGL framework. - Inspired from [Codrops Article](https://tympanus.net/codrops/2019/09/24/crafting-stylised-mouse-trails-with-ogl/){rel=""nofollow""} :: # iPhone Mockup ::component-viewer --- component-files: - iPhone15ProMockup.vue component-id: iphone-mockup config: iPhone15ProMockupConfig demo-file: iPhone15ProMockupDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | ---------------------------------------------- | | `width` | `number` | `433` | Width of the mockup SVG in pixels. | | `height` | `number` | `882` | Height of the mockup SVG in pixels. | | `src` | `string` | `null` | URL of the image to display inside the mockup. | #credits - Ported from [Magic UI](https://magicui.design/docs/components/iphone-15-pro){rel=""nofollow""}. :: # Safari Mockup ::component-viewer --- component-files: - SafariMockup.vue component-id: safari-mockup config: SafariMockupConfig demo-file: SafariMockupDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | ---------------------------------------------- | | `url` | `string` | `null` | URL displayed in the mockup's address bar. | | `src` | `string` | `null` | URL of the image to display inside the mockup. | | `width` | `number` | `1203` | Width of the mockup SVG in pixels. | | `height` | `number` | `753` | Height of the mockup SVG in pixels. | #credits - Ported from [Magic UI](https://magicui.design/docs/components/safari){rel=""nofollow""}. :: # HTML ASCII ::component-viewer --- component-files: - HtmlAscii.vue component-id: html-ascii config: HtmlAsciiConfig demo-file: HtmlAsciiDemo.vue --- Press the surface to switch the glyph output to monochrome. #api ## API | Prop | Type | Default | Description | | ------------ | --------- | ------- | ---------------------------------------------------- | | `cellSize` | `number` | `8` | Glyph cell size in pixels. Values below `5` use `5`. | | `frameRate` | `number` | `60` | Maximum render frequency. | | `pixelRatio` | `number` | `1` | Render scale, clamped between `0.25` and `2`. | | `paused` | `boolean` | `false` | Pauses the render loop. | | `autoPause` | `boolean` | `true` | Pauses while off-screen or the document is hidden. | | `class` | `string` | — | Additional classes merged onto the surface element. | ### Slots | Slot | Description | | --------- | ----------------------------------------- | | `default` | HTML content rendered through the effect. | #credits - Bitmap character technique adapted from [movAX13h](https://www.shadertoy.com/user/movAX13h){rel=""nofollow""}. :: # HTML Blaze ::component-viewer --- component-files: - HtmlBlaze.vue component-id: html-blaze config: HtmlBlazeConfig demo-file: HtmlBlazeDemo.vue --- #api ## API | Prop | Type | Default | Description | | ------------ | --------- | ------- | --------------------------------------------------- | | `strength` | `number` | `0.03` | Amount of heat displacement. | | `scale` | `number` | `6` | Scale of the flame noise field. | | `speed` | `number` | `1` | Animation speed of the fire. | | `frameRate` | `number` | `60` | Maximum render frequency. | | `pixelRatio` | `number` | `1` | Render scale, clamped between `0.25` and `2`. | | `paused` | `boolean` | `false` | Pauses the render loop. | | `autoPause` | `boolean` | `true` | Pauses while off-screen or the document is hidden. | | `class` | `string` | — | Additional classes merged onto the surface element. | ### Slots | Slot | Description | | --------- | ----------------------------------------- | | `default` | HTML content rendered through the effect. | #credits - Uses the MIT-licensed Simplex Noise implementation by [Ashima Arts](https://github.com/ashima/webgl-noise){rel=""nofollow""}. :: # HTML Chromatic ::component-viewer --- component-files: - HtmlChromatic.vue component-id: html-chromatic config: HtmlChromaticConfig demo-file: HtmlChromaticDemo.vue --- #api ## API | Prop | Type | Default | Description | | -------------- | --------- | ------- | --------------------------------------------------- | | `strength` | `number` | `0.03` | Maximum red and blue channel separation. | | `mouseDamping` | `number` | `0.9` | Smoothing applied to pointer movement. | | `frameRate` | `number` | `60` | Maximum render frequency. | | `pixelRatio` | `number` | `1` | Render scale, clamped between `0.25` and `2`. | | `paused` | `boolean` | `false` | Pauses the render loop. | | `autoPause` | `boolean` | `true` | Pauses while off-screen or the document is hidden. | | `class` | `string` | — | Additional classes merged onto the surface element. | ### Slots | Slot | Description | | --------- | ----------------------------------------- | | `default` | HTML content rendered through the effect. | :: # HTML Cloth ::component-viewer --- component-files: - HtmlCloth.vue component-id: html-cloth config: HtmlClothConfig demo-file: HtmlClothDemo.vue --- #api ## API | Prop | Type | Default | Description | | ------------ | --------- | ------- | --------------------------------------------------- | | `strength` | `number` | `0.03` | Amount of vector-field displacement. | | `scale` | `number` | `6` | Scale of the cloth field. | | `speed` | `number` | `1` | Animation speed of the field. | | `frameRate` | `number` | `60` | Maximum render frequency. | | `pixelRatio` | `number` | `1` | Render scale, clamped between `0.25` and `2`. | | `paused` | `boolean` | `false` | Pauses the render loop. | | `autoPause` | `boolean` | `true` | Pauses while off-screen or the document is hidden. | | `class` | `string` | — | Additional classes merged onto the surface element. | ### Slots | Slot | Description | | --------- | ----------------------------------------- | | `default` | HTML content rendered through the effect. | #credits - Vector field based on the work of [MartinRGB](https://www.shadertoy.com/view/DttSRB){rel=""nofollow""}. :: # HTML Drag ::component-viewer --- component-files: - HtmlDrag.vue component-id: html-drag config: HtmlDragConfig demo-file: HtmlDragDemo.vue --- Scroll over the surface to bend its segmented WebGL plane. Enable `mouseEnabled` to add press-and-drag deformation; leave it disabled to keep the HTML selectable. #api ## API | Prop | Type | Default | Description | | -------------- | --------- | ------- | ------------------------------------------------------------- | | `strength` | `number` | `1.25` | Amount of vertical surface bending. | | `mouseDamping` | `number` | `0.9` | Smoothing applied to pointer movement. | | `mouseEnabled` | `boolean` | `false` | Enables press-and-drag deformation and blocks text selection. | | `frameRate` | `number` | `60` | Maximum render frequency. | | `pixelRatio` | `number` | `1` | Render scale, clamped between `0.25` and `2`. | | `paused` | `boolean` | `false` | Pauses the render loop. | | `autoPause` | `boolean` | `true` | Pauses while off-screen or the document is hidden. | | `class` | `string` | — | Additional classes merged onto the surface element. | ### Slots | Slot | Description | | --------- | ----------------------------------------- | | `default` | HTML content rendered through the effect. | :: # HTML in Canvas ::component-viewer --- component-files: - HtmlInCanvas.vue - HtmlInCanvasRenderer.ts - captureElement.ts - index.ts component-id: html-in-canvas config: HtmlInCanvasConfig demo-file: HtmlInCanvasDemo.vue --- HTML in Canvas is an experimental browser API. When it is unavailable, the component captures a styled DOM snapshot and passes it through the same WebGL shader. The original DOM remains available for interaction and accessibility. Your fragment shader must define `mainImage(out vec4 fragColor, in vec2 fragCoord)`. The captured HTML is available through `iChannel0`. Use `HtmlLiquid`, `HtmlChromatic`, `HtmlAscii`, `HtmlCloth`, `HtmlBlaze`, or `HtmlDrag` when you want a focused, typed effect. Each component delegates rendering and fallback behavior to this shared renderer. Pass `vertexShaderCode` when the effect also needs vertex-stage logic. It must define `main()` without a `#version` directive. The segmented surface exposes built-in `vec2 position` and `vec2 textureCoord` attributes, and the same uniforms are available to both shader stages. #api ## API | Prop | Type | Default | Description | | ------------------ | ---------------- | ------- | ------------------------------------------------------------------ | | `shaderCode` | `string` | — | Fragment shader body containing a `mainImage` function. | | `vertexShaderCode` | `string` | — | Optional vertex shader body containing a `main` function. | | `uniforms` | `ShaderUniforms` | `{}` | Custom numeric, boolean, vector, or matrix uniforms. | | `frameRate` | `number` | `60` | Maximum render frequency. | | `pixelRatio` | `number` | `1` | Render scale, clamped between `0.25` and `2`. | | `speed` | `number` | `1` | Multiplier applied to `iTime`. | | `mouseDamping` | `number` | `0.85` | Smoothing applied to pointer movement. | | `paused` | `boolean` | `false` | Pause the render loop. | | `autoPause` | `boolean` | `true` | Pause while the component is off-screen or the document is hidden. | | `interactive` | `boolean` | `true` | Track pointer input for `iMouse`. | | `class` | `string` | — | Additional classes merged onto the root element. | ### Shader inputs `iResolution`, `iTime`, `iTimeDelta`, `iFrameRate`, `iFrame`, `iMouse`, `iDate`, `iHasContent`, `iChannel0`, and `iChannelResolution` follow ShaderToy conventions. `iPointerVelocity`, `iPointerEnergy`, and `iPointerAge` provide a damped pointer impulse for effects that should settle after movement. `iPointerInside` transitions between `0` and `1` as the pointer leaves or enters the surface. `iScrollVelocity` provides damped vertical wheel input for vertex deformation. `iHasContent` is `1` when the HTML texture is available. ### Events | Event | Payload | Description | | --------- | --------- | --------------------------------------------------- | | `ready` | — | Emitted after the first HTML texture is rendered. | | `error` | `string` | Emitted when shader compilation or rendering fails. | | `support` | `boolean` | Reports native HTML-in-Canvas availability. | ### Slots | Slot | Description | | --------- | -------------------------------------------- | | `default` | HTML content captured as the shader texture. | #credits - Built against the [WICG HTML-in-Canvas proposal](https://github.com/WICG/html-in-canvas){rel=""nofollow""}. :: # HTML Liquid ::component-viewer --- component-files: - HtmlLiquid.vue component-id: html-liquid config: HtmlLiquidConfig demo-file: HtmlLiquidDemo.vue --- #api ## API | Prop | Type | Default | Description | | -------------- | --------- | ------- | --------------------------------------------------- | | `strength` | `number` | `0.03` | Amount of texture displacement. | | `frequency` | `number` | `18` | Density of the flowing surface and pointer ripples. | | `speed` | `number` | `3` | Motion speed of the liquid field. | | `mouseDamping` | `number` | `0.9` | Smoothing applied to pointer movement. | | `frameRate` | `number` | `60` | Maximum render frequency. | | `pixelRatio` | `number` | `1` | Render scale, clamped between `0.25` and `2`. | | `paused` | `boolean` | `false` | Pauses the render loop. | | `autoPause` | `boolean` | `true` | Pauses while off-screen or the document is hidden. | | `class` | `string` | — | Additional classes merged onto the surface element. | ### Slots | Slot | Description | | --------- | ----------------------------------------- | | `default` | HTML content rendered through the effect. | :: # All Components :components-list # Balance Slider ::component-viewer --- component-files: - BalanceSlider.vue component-id: balance-slider config: BalanceSliderConfig demo-file: BalanceSliderDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------- | -------- | ----------- | --------------------------------------------------- | | `initialValue` | `number` | `50` | Initial position of the slider (0-100). | | `leftColor` | `string` | `"#e68a00"` | Background color for the left side of the slider. | | `rightColor` | `string` | `"#ffffff"` | Background color for the right side of the slider. | | `minShiftLimit` | `number` | `40` | Minimum limit where shifting animation activates. | | `maxShiftLimit` | `number` | `68` | Maximum limit where shifting animation deactivates. | | `leftContent` | `string` | `"LEFT"` | Text displayed in the tooltip for the left side. | | `rightContent` | `string` | `"RIGHT"` | Text displayed in the tooltip for the right side. | | `indicatorColor` | `string` | `"#FFFFFF"` | Color of the central indicator on the slider. | #credits - Inspired and ported from code shared in [Jhey's CSS only version of Balance Slider](https://x.com/jh3yy/status/1748809599598399792?s=46){rel=""nofollow""} - Original concept by [Malay Vasa](https://x.com/MalayVasa/status/1748726374079381930){rel=""nofollow""}. :: # Color Picker ::component-viewer --- component-files: - ColorPicker.vue - ObjectColorInput.vue - ContrastRatio.vue - index.ts component-id: color-picker config: ColorPickerConfig demo-file: ColorPickerDemo.vue dependencies: "@uiw/color-convert" --- #api ## API ### ColorPicker Props | Prop Name | Type | Default | Description | | --------------------- | -------------------------------------------- | ----------- | ------------------------------------------------- | | `value` | `string | HsvaColor | HslaColor | RgbaColor` | `undefined` | The current color value in any supported format | | `type` | `'hsl' | 'hsla' | 'rgb' | 'rgba' | 'hex'` | `'hsl'` | Default color format to display in inputs | | `swatches` | `HexColor[]` | `[]` | Array of predefined color swatches | | `hideContrastRatio` | `boolean` | `false` | Hide the accessibility contrast ratio section | | `hideDefaultSwatches` | `boolean` | `false` | Hide the default color swatches | | `class` | `string` | `""` | Additional CSS classes for the popover content | | `open` | `boolean` | `false` | Control the open/closed state of the color picker | ### ColorPicker Events | Event Name | Type | Description | | -------------- | ----------------------------------- | ------------------------------------------- | | `value-change` | `(value: ColorPickerValue) => void` | Emitted when the selected color changes | | `update:open` | `(value: boolean) => void` | Emitted when the popover open state changes | ### ColorPickerValue Type ```typescript interface ColorPickerValue { hex: string; // Hex color string (e.g., "#ff0000") hsl: HslaColor; // HSL color object with h, s, l, a properties hsla: HslaColor; // HSLA color object with h, s, l, a properties rgb: RgbaColor; // RGB color object with r, g, b, a properties rgba: RgbaColor; // RGBA color object with r, g, b, a properties } ``` #credits - Credits to [kalix127](https://github.com/kalix127){rel=""nofollow""} for porting this component. - Inspired by [@uplusion23](https://21st.dev/uplusion23/color-picker/color-picker-with-swatches-and-onchange){rel=""nofollow""}. :: # File Upload ::component-viewer --- component-files: - FileUpload.vue - FileUploadGrid.vue component-id: file-upload config: FileUploadConfig demo-file: FileUploadDemo.vue --- #api ## API ### `FileUpload` The `FileUpload` component serves as a wrapper for the file upload effect. It manages mouse events to create a 3D perspective. #### Props | Prop Name | Type | Default | Description | | --------- | ------ | ------- | ----------------------------------------------------- | | `class` | String | - | Additional classes for styling the container element. | #### Emits | Event Name | Type | Description | | ---------- | ------------------------- | ---------------------------------------------------------- | | `onChange` | `(files: File[]) => void` | Callback function triggered when files are added/uploaded. | ### `FileUploadGrid` The `FileUploadGrid` component provides the background grid pattern for the file upload area. It is intended to be used within a `FileUpload` component to create the visual grid effect behind the upload interface. #### Props | Prop Name | Type | Default | Description | | --------- | ------ | ------- | -------------------------------------- | | `class` | String | - | Additional classes for custom styling. | #credits - Credits to [kalix127](https://github.com/kalix127){rel=""nofollow""} for porting this component. - Inspired by [AcernityUI](https://ui.aceternity.com/components/file-upload){rel=""nofollow""}. :: # Halo Search ::component-viewer --- component-files: - HaloSearch.vue component-id: halo-search config: HaloSearchConfig demo-file: HaloSearchDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | ------------------------------------------ | | `class` | `string` | `""` | Additional CSS classes for root container. | #credits - Design inspired by futuristic UI concepts and ambient lighting effects popular in modern web and app design. - Inspired from UiVerse Search input challenge. :: # Input ::component-viewer --- component-files: - IInput.vue component-id: input config: InputConfig demo-file: InputDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------- | ----------------- | ------- | ----------------------------------------------------------- | | `defaultValue` | `string | number` | `""` | Default value of the input field. | | `class` | `string` | `""` | Additional CSS classes for custom styling. | | `containerClass` | `string` | `""` | Additional CSS classes for custom styling of the container. | #credits - Built on ShadCN Vue's Input component foundation, with extended functionality for modern UI/UX needs. - Ported from [Aceternity UI's Signup Form Input Component](https://ui.aceternity.com/components/signup-form){rel=""nofollow""} :: # Placeholders And Vanish Input ::component-viewer --- component-files: - VanishingInput.vue component-id: vanishing-input config: VanishingInputConfig demo-file: VanishingInputDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | --------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------- | | `placeholders` | `Array` | `["Placeholder 1", "Placeholder 2", "Placeholder 3"]` | An array of placeholder texts that cycle through as prompts in the input field. | This component listens to the following events emitted by the `VanishingInput` component: | Event Name | Parameters | Description | | ---------- | ---------- | --------------------------------------- | | `change` | `Event` | Triggered when the input value changes. | | `submit` | `string` | Triggered when the input is submitted. | #credits - Credits to [M Atif](https://github.com/atif0075){rel=""nofollow""} for porting this component. - Ported from [Aceternity UI's Placeholders And Vanish Input](https://ui.aceternity.com/components/placeholders-and-vanish-input){rel=""nofollow""}. :: # Animate Grid ::component-viewer --- component-files: - AnimateGrid.vue component-id: animate-grid config: AnimateGridConfig demo-file: AnimateGridDemo.vue --- #instructions #### Add SVG file Add at least one SVG file to the same folder as your component and update the import in your component to use it #api ## API | Prop Name | Type | Default | Description | | -------------------- | -------- | ------------------- | --------------------------------------------------- | | `textGlowStartColor` | `string` | `"#38ef7d80"` | Color of the box shadow start. | | `textGlowEndColor` | `string` | `"#38ef7d"` | Color of the box shadow end. | | `perspective` | `number` | `600` | You can pass perspective to transform CSS property. | | `rotateX` | `number` | `-1` | You can pass rotateX to transform CSS property. | | `rotateY` | `number` | `-15` | You can pass rotateY to transform CSS property. | | `cards` | `[]` | `"[{logo: 'src'}]"` | Cards to display in grid. | | `class` | `string` | `""` | Additional tailwind CSS classes for custom styling. | #credits - Thanks to [SivaReddy Uppathi](https://github.com/sivareddyuppathi){rel=""nofollow""} for providing this component. :: # Animated Circular Progress Bar ::component-viewer --- component-files: - AnimatedCircularProgressBar.vue component-id: animated-circular-progressbar config: AnimatedCircularProgressBarConfig demo-file: AnimatedCircularProgressBarDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------------------- | --------- | -------------------- | ------------------------------------------- | | `class` | `string` | `-` | The class to be applied to the component. | | `max` | `number` | `100` | The maximum value of the gauge. | | `min` | `number` | `0` | The minimum value of the gauge. | | `value` | `number` | `0` | The current value of the gauge. | | `gaugePrimaryColor` | `string` | `rgb(79 70 229)` | The primary color of the gauge. | | `gaugeSecondaryColor` | `string` | `rgba(0, 0, 0, 0.1)` | The secondary color of the gauge. | | `circleStrokeWidth` | `number` | `10` | The width of the circle progress bar. | | `showPercentage` | `boolean` | `true` | Show the value inside the circle | | `duration` | `number` | `1` | The duration of the animation (in seconds). | #credits - Credits to [Magic UI](https://magicui.design/docs/components/animated-circular-progress-bar){rel=""nofollow""}. - Credits to [SivaReddy Uppathi](https://github.com/sivareddyuppathi){rel=""nofollow""} for porting this component. :: # Animated List ::component-viewer --- component-files: - AnimatedList.vue - Notification.vue component-id: animated-list config: AnimatedListConfig demo-file: AnimatedListDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | -------------------------------------------------------------- | | `delay` | `number` | `1` | The delay in milliseconds before adding each item to the list. | #credits - Inspired by [Magic UI](https://magicui.design/docs/components/animated-list){rel=""nofollow""}. :: # Animated Modal ::component-viewer --- component-files: - AnimatedModal.vue - AnimatedModalBody.vue - AnimatedModalContent.vue - AnimatedModalFooter.vue - AnimatedModalTrigger.vue - AnimatedModalContext.ts - useAnimatedModal.ts - index.ts component-id: animated-modal config: AnimatedModalConfig demo-file: AnimatedModalDemo.vue dependencies: motion-v @vueuse/core --- #api ## API ### `` #### Props | Prop Name | Type | Default | Description | | ------------- | --------- | ------- | ------------------------------- | | `open` | `boolean` | `-` | Controlled open state. | | `defaultOpen` | `boolean` | `false` | Uncontrolled initial state. | | `closeOnEsc` | `boolean` | `true` | Close modal when pressing `Esc` | #### Events | Event Name | Payload | Description | | ------------- | --------- | ------------------------------------ | | `update:open` | `boolean` | Fired when open state changes. | | `open` | - | Fired when `openModal()` is called. | | `close` | - | Fired when `closeModal()` is called. | #### Slots | Slot Name | Slot Props | | --------- | ------------------------------------------- | | `default` | `open`, `openModal`, `closeModal`, `toggle` | #### Composable - `useAnimatedModal()` — access modal state/methods from any nested child component (must be used within ``). ### `` #### Props | Prop Name | Type | Default | Description | | ---------------- | ---------------------- | -------- | ----------------------------------------- | | `class` | `string` | `""` | Extra classes for the modal panel. | | `overlayClass` | `string` | `""` | Extra classes for the overlay. | | `contentClass` | `string` | `""` | Extra classes for the content wrapper. | | `showClose` | `boolean` | `true` | Show close button. | | `closeOnOutside` | `boolean` | `true` | Close when clicking outside the dialog. | | `lockScroll` | `boolean` | `true` | Lock page scroll while the modal is open. | | `zIndex` | `number` | `10000` | Z-index for the modal layer. | | `teleportTo` | `string | HTMLElement` | `"body"` | Teleport target for the modal layer. | #credits - Ported from [Aceternity UI's Animated Modal](https://ui.aceternity.com/components/animated-modal){rel=""nofollow""}. - Animations powered by [motion-v](https://motion.dev/){rel=""nofollow""}. :: # Animated Tabs ::component-viewer --- component-files: - AnimatedTabs.vue - AnimatedTabsFadeInDiv.vue - types.ts - index.ts component-id: animated-tabs config: AnimatedTabsConfig demo-file: AnimatedTabsDemo.vue dependencies: motion-v --- #api ## API ### `` Tip: give the wrapper a fixed height (e.g. `h-[20rem] md:h-[40rem]`) so the stacked content can be positioned absolutely. #### Props | Prop Name | Type | Default | Description | | -------------------- | --------------- | ------- | --------------------------------------------- | | `tabs` | `AnimatedTab[]` | `-` | Tabs metadata list. | | `modelValue` | `string` | `-` | Controlled active tab value. | | `containerClassName` | `string` | `""` | Extra classes for the tablist container. | | `tabClassName` | `string` | `""` | Extra classes for each tab button. | | `activeTabClassName` | `string` | `""` | Extra classes for the active pill background. | | `contentClassName` | `string` | `""` | Extra classes for each stacked content card. | #### Events | Event Name | Payload | Description | | ------------------- | -------- | ------------------------------------------------ | | `update:modelValue` | `string` | Fired when active tab changes (controlled mode). | #### Slots | Slot Name | Slot Props | Description | | --------- | --------------------------- | ------------------------------------- | | `content` | `tab`, `active`, `hovering` | Render the tab content (recommended). | #### Types ##### `AnimatedTab` | Field | Type | Required | Description | | ---------------- | --------------------- | -------- | ---------------------------------------------------------------- | | `title` | `string` | yes | Tab label (used by the default UI). | | `value` | `string` | yes | Unique tab id used for active state. | | `panelClassName` | `string` | no | Optional panel background classes (used by demos / consumers). | | `content` | `Component` | no | Fallback content component when `#content` slot is not provided. | | `contentProps` | `Record` | no | Props passed to the `content` component. | #credits - Ported from [Aceternity UI Tabs](https://ui.aceternity.com/components/tabs){rel=""nofollow""}. - Animations powered by [motion-v](https://motion.dev/docs/vue){rel=""nofollow""}. :: # Animated Tooltip ::component-viewer --- component-files: - AnimatedTooltip.vue component-id: animated-tooltip config: AnimatedTooltipConfig demo-file: AnimatedTooltipDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | ----------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `items` | `Array<{id: number, name: string, designation: string, image: string}>` | `[]` | An array of objects, each representing an item. Each object in the array should have the following properties: id, name, designation, image | #credits - Credits to [M Atif](https://github.com/atif0075){rel=""nofollow""} for this component. - Inspired from [Aceternity UI's Animated Tooltip](https://ui.aceternity.com/components/animated-tooltip){rel=""nofollow""}. :: # Bento Grid ::component-viewer --- component-files: - BentoGrid.vue - BentoGridCard.vue - BentoGridItem.vue component-id: bento-grid config: BentoGridConfig demo-file: BentoGridDemo.vue --- #api ## API #### `BentoGridItem` | Slot Name | Description | | ------------- | --------------------------------- | | `title` | Component to show as title. | | `description` | Component to show as description. | | `icon` | Component to show as icon. | | `header` | Component to show as header. | #### `BentoGridCard` | Slot Name | Description | | ------------ | -------------------------------- | | `background` | Component to show in background. | | Props Name | Type | Description | | ------------- | --------- | ------------------------------------ | | `name` | `string` | Name or title to show on card. | | `icon` | `?string` | Icon component to show on card. | | `description` | `string` | Description content to show on card. | | `href` | `string` | Link to the url for CTA. | | `cta` | `string` | Text to show on CTA. | #credits - Credits to [Aceternity UI](https://ui.aceternity.com/components/bento-grid){rel=""nofollow""} and [Magic UI](https://magicui.design/docs/components/bento-grid){rel=""nofollow""} for this fantastic component. :: # Book ::component-viewer --- component-files: - Book.vue - BookHeader.vue - BookTitle.vue - BookDescription.vue - index.ts component-id: book config: BookConfig demo-file: BookDemo.vue --- #api ## API #### `Book` | Prop Name | Type | Default | Description | | ------------ | ------- | ------- | --------------------------------------------- | | `class` | String | - | Additional classes for styling the component. | | `duration` | Number | 1000 | Animation duration in milliseconds. | | `color` | String | "zinc" | Color theme for the book gradient. | | `isStatic` | Boolean | false | Disables hover animations when true. | | `size` | String | "md" | Size variant of the book. | | `radius` | String | "md" | Border radius variant of the book. | | `shadowSize` | String | "lg" | Shadow size variant of the book. | #### `BookHeader` | Prop Name | Type | Default | Description | | --------- | ------ | ------- | -------------------------------------- | | `class` | String | - | Additional classes for custom styling. | #### `BookTitle` | Prop Name | Type | Default | Description | | --------- | ------ | ------- | -------------------------------------- | | `class` | String | - | Additional classes for custom styling. | #### `BookDescription` | Prop Name | Type | Default | Description | | --------- | ------ | ------- | -------------------------------------- | | `class` | String | - | Additional classes for custom styling. | #credits - Credits to [x/UI](https://ui.3x.gl/docs/book){rel=""nofollow""} for inspiring this component. - Credits to [kalix127](https://github.com/kalix127){rel=""nofollow""} for porting this component. :: # Circular Gallery ::component-viewer --- component-files: - CircularGallery.vue - index.ts component-id: circular-gallery config: CircularGalleryConfig demo-file: CircularGalleryDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | --------------------- | -------- | ------------------------------------------------- | | `radius` | `number` | `100` | Distance in pixels from the center to each child. | | `duration` | `number` | `10` | Time in seconds for one full rotation. | | `easing` | `string` | `linear` | CSS timing function used for the rotation. | | `direction` | `normal` \| `reverse` | `normal` | Rotation direction. | | `class` | `string` | — | Additional classes for the component root. | | `pauseOnHover` | `boolean` | `false` | Pauses the rotation while a child is hovered. | ## Usage Pass the elements to arrange around the circle through the default slot: ```vue One Two Three ``` #credits - Ported from [Fancy Components Circling Elements](https://fancycomponents.dev/docs/components/blocks/circling-elements){rel=""nofollow""}. :: # Compare ::component-viewer --- component-files: - Compare.vue - StarField.vue component-id: compare config: CompareConfig demo-file: CompareDemo.vue --- #api ## API ### Props | Prop Name | Type | Default | Description | | ------------------------- | ------------------ | ---------------- | ----------------------------------------- | | `firstImage` | `string` | `""` | URL of the first image | | `secondImage` | `string` | `""` | URL of the second image | | `firstImageAlt` | `string` | `"First image"` | Alt text for first image | | `secondImageAlt` | `string` | `"Second image"` | Alt text for second image | | `class` | `string` | `""` | Additional classes for the component | | `firstContentClass` | `string` | `""` | Classes applied to first content wrapper | | `secondContentClass` | `string` | `""` | Classes applied to second content wrapper | | `initialSliderPercentage` | `number` | `50` | Initial position of slider (0-100) | | `slideMode` | `"hover" | "drag"` | `"hover"` | Interaction mode for the slider | | `showHandlebar` | `boolean` | `true` | Show/hide the handle bar | | `autoplay` | `boolean` | `false` | Enable/disable autoplay | | `autoplayDuration` | `number` | `5000` | Duration of autoplay cycle in ms | ### Events | Event Name | Payload | Description | | ------------------- | -------- | -------------------------------------------- | | `update:percentage` | `number` | Emitted when slider position changes (0-100) | | `drag:start` | - | Emitted when dragging starts | | `drag:end` | - | Emitted when dragging ends | | `hover:enter` | - | Emitted when mouse enters component | | `hover:leave` | - | Emitted when mouse leaves component | ### Slots | Slot Name | Default Content | Description | | ---------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | `first-content` | `` element if `firstImage` prop is provided | Content shown on the left/first side of the comparison. Has full access to component width/height. | | `second-content` | `` element if `secondImage` prop is provided | Content shown on the right/second side of the comparison. Has full access to component width/height. | | `handle` | Default slider handle with dots icon | Custom handle for the slider. Automatically positioned at the dividing line. Should handle positioning with absolute positioning. | #credits - Credits to [M Atif](https://github.com/atif0075){rel=""nofollow""} for this component. - Inspired from [Aceternity UI's Compare](https://ui.aceternity.com/components/compare){rel=""nofollow""}. :: # Container Scroll ::component-viewer --- component-files: - ContainerScroll.vue - ContainerScrollTitle.vue - ContainerScrollCard.vue component-id: container-scroll config: ContainerScrollConfig demo-file: ContainerScrollDemo.vue --- #api ## API ### `ContainerScroll` The `ContainerScroll` component creates a 3D scroll effect. As the user scrolls, the content inside the container is transformed with scale, rotation, and translation effects. | Prop Name | Type | Default | Description | | ------------ | ------ | ------- | ----------------------------------------------------------------------------- | | `rotate` | Number | `0` | Controls the rotation of the inner content based on the scroll progress. | | `scale` | Number | `1` | Controls the scaling transformation applied to the content during the scroll. | | `translateY` | Number | `0` | Controls the vertical translation of the title during the scroll. | ### `ContainerScrollTitle` The `ContainerScrollTitle` component handles the title's transformation as the user scrolls, applying a vertical translation effect. | Prop Name | Type | Default | Description | | ----------- | ------ | ------- | ----------------------------------------------- | | `translate` | Number | `0` | Controls the vertical translation of the title. | ### `ContainerScrollCard` The `ContainerScrollCard` component applies scale and rotation effects to the card content as the user scrolls through the page. | Prop Name | Type | Default | Description | | --------- | ------ | ------- | ------------------------------------------------ | | `rotate` | Number | `0` | Controls the rotation effect of the card. | | `scale` | Number | `1` | Controls the scaling effect applied to the card. | ## CSS Variables To customize the scroll animations and responsiveness, you can set the following CSS variables: - **`--scale-start`**: Initial scale value for the card. - **`--scale-end`**: Final scale value for the card as the scroll progresses. - **`--rotate-start`**: Initial rotation value for the card. - **`--rotate-end`**: Final rotation value for the card as the scroll progresses. #credits - Inspired by [Aceternity UI Container Scroll Animation](https://ui.aceternity.com/components/container-scroll-animation){rel=""nofollow""}. :: # Dock ::component-viewer --- component-files: - Dock.vue - DockIcon.vue - DockSeparator.vue - index.ts - types.ts - injectionKeys.ts component-id: dock config: DockConfig demo-file: DockDemo.vue --- #api ## API ### `Dock` | Prop Name | Type | Description | | --------------- | -------- | --------------------------------------------------------------------- | | `class` | `string` | Additional classes to apply to the dock container. | | `magnification` | `number` | Magnification factor for the dock icons on hover (default: 60). | | `distance` | `number` | Distance from the icon center where magnification applies. | | `direction` | `string` | Alignment of icons (`top`, `middle`, `bottom`) (default: middle). | | `orientation` | `string` | Orientation of Dock (`vertical`, `horizontal`) (default: horizontal). | | Slot Name | Description | | --------- | ---------------------------------------------------- | | `default` | Dock Dock or other child components to be displayed. | ### `DockIcon` | Slot Name | Description | | --------- | ------------------------------------------------------- | | `default` | Component or icon to be displayed inside the dock icon. | #credits - Credits to macOS Dock for the design inspiration and the fantastic hover magnification effect. :: # Expandable Gallery ::component-viewer --- component-files: - ExpandableGallery.vue component-id: expandable-gallery config: ExpandableGalleryConfig demo-file: ExpandableGalleryDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | ---------- | ------- | ---------------------------------------------- | | `images` | `string[]` | `[]` | Array of image URLs to display in the gallery. | #credits - Inspired from [Expandable Gallery Component by David MrĂĄz](https://x.com/davidm_ml/status/1872319793124282653){rel=""nofollow""} :: # Float ::component-viewer --- component-files: - Float.vue - index.ts component-id: float config: FloatConfig demo-file: FloatDemo.vue --- #api ## API | Prop | Type | Default | Description | | --------------- | -------------------------- | --------------- | ---------------------------------------------------- | | `speed` | `number` | `0.5` | Amount of time progression per animation frame. | | `amplitude` | `[number, number, number]` | `[10, 30, 30]` | Position movement on the X, Y, and Z axes in pixels. | | `rotationRange` | `[number, number, number]` | `[15, 15, 7.5]` | Rotation range on the X, Y, and Z axes in degrees. | | `timeOffset` | `number` | `0` | Phase offset for desynchronising multiple floaters. | | `class` | `string` | — | Additional classes merged onto the animated wrapper. | Place the content to animate in the default slot. The wrapper preserves 3D transforms and updates its position on every animation frame. #credits - Ported from [Fancy Components Float](https://fancycomponents.dev/docs/components/blocks/float){rel=""nofollow""}. :: # Images Slider ::component-viewer --- component-files: - ImagesSlider.vue component-id: images-slider config: ImagesSliderConfig demo-file: ImagesSliderDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------------ | ------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------ | | `images` | `string[]` | `[]` | An array of image URLs to show in the slider. | | `hideOverlay` | `boolean` | `false` | Don't create an overlay for the image slider. Slot won't be rendered. | | `overlayClass` | `string` | `''` | A class string to be applied to the overlay container. | | `imageClass` | `string` | `'bg-cover bg-center bg-no-repeat'` | Class string to apply to each of the images. | | `enterFromClass` | `string` | `'scale-0 origin-center'` | Class string applied to the 'enter-from-class' prop on the image transition. | | `enterActiveClass` | `string` | `'transition-transform duration-300 ease-in-out'` | Class string applied to the 'enter-active-class' prop on the image transition. | | `leaveActiveClass` | `string` | `'transition-transform duration-300 ease-in-out'` | Class string applied to the 'leave-active-class' prop on the image transition. | | `autoplay` | `boolean|number` | `false` | Autoplay interval in ms, or `false` to disable. | | `direction` | `'vertical'|'horizontal'` | `'vertical'` | The axis on which the slider should operate. | | `perspective` | `string` | `'1000px'` | The perspective to apply to the slider container. | | `modelValue` | `number` | `0` | Two-way binding for the current slide image index. | #credits - Component by [Craig Riley](https://github.com/craigrileyuk){rel=""nofollow""} for porting this component. - Credits to [Aceternity UI](https://ui.aceternity.com/components/images-slider){rel=""nofollow""} for inspiring this component. :: # Lens ::component-viewer --- component-files: - Lens.vue - Rays.vue - Beams.vue component-id: lens config: LensConfig demo-file: LensDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------ | -------------------------- | -------------------- | ---------------------------------------------------------------------------- | | `zoomFactor` | `number` | `1.5` | The magnification factor for the lens. | | `lensSize` | `number` | `170` | The diameter of the lens in pixels. | | `position` | `{ x: number, y: number }` | `{ x: 200, y: 150 }` | The static position of the lens (when isStatic is true). | | `isStatic` | `boolean` | `false` | If true, the lens stays in a fixed position; if false, it follows the mouse. | | `hovering` | `boolean` | `"false"` | External control for the hover state. | #credits - Credits to [Aceternity UI](https://ui.aceternity.com/components/lens){rel=""nofollow""}. - Credits to [SivaReddy Uppathi](https://github.com/sivareddyuppathi){rel=""nofollow""} for porting this component. :: # Link Preview ::component-viewer --- component-files: - LinkPreview.vue component-id: link-preview config: LinkPreviewConfig demo-file: LinkPreviewDemo.vue dependencies: qss --- #api ## API | Prop Name | Type | Default | Description | | ----------- | --------- | ------- | ------------------------------------------------------------------------------------------- | | `class` | `string` | `""` | Custom class applied to the main element. | | `linkClass` | `string` | `""` | Custom class applied to the link element. | | `width` | `number` | `200` | Width of the preview image. | | `height` | `number` | `125` | Height of the preview image. | | `isStatic` | `boolean` | `false` | Determines if the preview image is static or a URL preview (set to `true` for static mode). | | `imageSrc` | `string` | `""` | The source of the image to display (required if `isStatic` is `true`). | | `url` | `string` | `""` | URL for the link and for generating the preview image (required if `isStatic` is `false`). | #credits - Credits to [M Atif](https://github.com/atif0075){rel=""nofollow""} for porting this component. - Ported from [Aceternity UI's Link Preview](https://ui.aceternity.com/components/link-preview){rel=""nofollow""}. :: # Marquee ::component-viewer --- component-files: - Marquee.vue - ReviewCard.vue component-id: marquee config: MarqueeConfig demo-file: MarqueeDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | --------- | ------- | ------------------------------------------------------------------------- | | `class` | `string` | `''` | Custom CSS classes to apply to the outermost container of the marquee. | | `reverse` | `boolean` | `false` | Sets the scrolling direction to reverse (right to left or bottom to top). | | `pauseOnHover` | `boolean` | `false` | Pauses the marquee animation when hovered. | | `vertical` | `boolean` | `false` | Sets the scrolling direction to vertical instead of horizontal. | | `repeat` | `number` | `4` | Number of times the content inside the marquee should be repeated. | ## CSS Variables You can customize the speed and gap between the items by setting the following CSS variables: - **`--duration`**: Controls the speed of the marquee animation. - **`--gap`**: Sets the space between repeated items in the marquee. #credits - Inspired by [Magic UI](https://magicui.design/docs/components/marquee){rel=""nofollow""}. :: # Media Text ::component-viewer --- component-files: - MediaText.vue - index.ts component-id: media-text config: MediaTextConfig demo-file: MediaTextDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------------------- | ---------------------------- | ----------------------------- | ----------------------------------------------- | | `firstText` | `string` | — | Text rendered before the media. | | `secondText` | `string` | — | Text rendered after the media. | | `mediaUrl` | `string` | — | Image or video URL. | | `mediaType` | `"image" | "video"` | — | Media element to render. | | `mediaContainerClass` | `string` | — | Classes applied to the animated media wrapper. | | `fallbackUrl` | `string` | — | Poster URL used by videos. | | `as` | `string` | `p` | Element used for the text fragments. | | `autoPlay` | `boolean` | `true` | Autoplay the video when `mediaType` is `video`. | | `loop` | `boolean` | `true` | Loop the video when `mediaType` is `video`. | | `muted` | `boolean` | `true` | Mute the video when `mediaType` is `video`. | | `playsInline` | `boolean` | `true` | Keep video playback inline on mobile devices. | | `alt` | `string` | Generated | Alternative text for an image. | | `triggerType` | `"hover" | "ref" | "inView"` | `hover` | Trigger used to reveal the media. | | `useInViewOptions` | `UseInViewOptions` | `{ once: true, amount: 0.5 }` | Options passed to the in-view trigger. | | `animationVariants` | `object` | Width spring reveal | Motion variants for the media wrapper. | | `class` | `string` | — | Classes merged onto the root element. | | `leftTextClass` | `string` | — | Classes applied to the first text fragment. | | `rightTextClass` | `string` | — | Classes applied to the second text fragment. | The component exposes `animate()` and `reset()` for the `ref` trigger. #credits - Ported from [Fancy Components Media Between Text](https://fancycomponents.dev/docs/components/blocks/media-between-text){rel=""nofollow""}. :: # Morphing Tabs ::component-viewer --- component-files: - MorphingTabs.vue component-id: morphing-tabs config: MorphingTabsConfig demo-file: MorphingTabsDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------------ | ---------- | ------- | ---------------------------------------------- | | `class` | `string` | `""` | Additional class names to style the component. | | `tabs` | `string[]` | `[]` | Tabs. | | `activeTab` | `string` | `""` | Current active Tab. | | `margin` | `number` | `20` | Active tab margin left and right. | | `blurStdDeviation` | `number` | `6` | Svg blur stdDeviation, tab rounded use it. | #credits - Credits to [Whbbit1999](https://github.com/Whbbit1999){rel=""nofollow""} for this component. - Inspired and ported from [@Preet "Exclusion tabs"](https://x.com/wickedmishra/status/1823026659894940124){rel=""nofollow""}. :: # Multi Step Loader ::component-viewer --- component-files: - MultiStepLoader.vue component-id: multi-step-loader config: MultiStepLoaderConfig demo-file: MultiStepLoaderDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ----------------- | --------- | ------- | ---------------------------------------------------------------------------- | | `loading` | `boolean` | `false` | Controls the visibility of the loader. When `true`, the loader is displayed. | | `steps` | `Step[]` | `[]` | Array of step objects defining the loading sequence. | | `defaultDuration` | `number` | `1500` | The duration of each step in milliseconds. | | `preventClose` | `boolean` | `false` | If `true`, the close button will not be shown. | | Event Name | Payload Type | Description | | -------------- | ------------ | -------------------------------------------------------------------- | | `state-change` | `number` | Emitted when the current step changes, providing the new step index. | | `complete` | `void` | Emitted when all steps have been completed. | | `close` | `void` | Emitted when the loader is closed by button. | #credits - Credits to [M Atif](https://github.com/atif0075){rel=""nofollow""} for this component. - Inspired from [Aceternity UI's Multi Step Loader](https://ui.aceternity.com/components/multi-step-loader){rel=""nofollow""}. :: # Parallax Float ::component-viewer --- component-files: - ParallaxFloat.vue - ParallaxFloatElement.vue - ParallaxFloatContext.ts - index.ts component-id: parallax-float config: ParallaxFloatConfig demo-file: ParallaxFloatDemo.vue --- #api ## API ### ParallaxFloat | Prop Name | Type | Default | Description | | -------------- | -------- | ------- | ------------------------------------------------ | | `sensitivity` | `number` | `1` | Multiplier applied to each element's depth. | | `easingFactor` | `number` | `0.05` | Per-frame interpolation toward the target point. | | `class` | `string` | — | Additional classes for the container. | ### ParallaxFloatElement | Prop Name | Type | Default | Description | | --------- | -------- | ------- | --------------------------------------------- | | `depth` | `number` | `1` | Relative movement depth for the element. | | `class` | `string` | — | Positioning and styling classes for the item. | ## Usage Use `ParallaxFloat` as the container and place each independently moving layer inside `ParallaxFloatElement`: ```vue Portrait ``` #credits - Ported from [Fancy Components Parallax Floating](https://fancycomponents.dev/docs/components/image/parallax-floating){rel=""nofollow""}. :: # Path Marquee ::component-viewer --- component-files: - PathMarquee.vue - index.ts component-id: path-marquee config: PathMarqueeConfig demo-file: PathMarqueeDemo.vue --- #api ## API | Prop | Type | Default | Description | | -------------------------- | --------------------------- | --------------------------------- | ----------------------------------------------------- | | `path` | `string` | — | SVG path data used to position each item. | | `pathId` | `string` | Generated | ID assigned to the SVG path. | | `showPath` | `boolean` | `false` | Render the path stroke. | | `width` | `string | number` | `"100%"` | SVG width. | | `height` | `string | number` | `"100%"` | SVG height. | | `viewBox` | `string` | `"0 0 100 100"` | SVG coordinate system. | | `preserveAspectRatio` | `string` | `"xMidYMid meet"` | SVG aspect-ratio behavior. | | `baseVelocity` | `number` | `5` | Automatic movement speed. | | `direction` | `"normal" | "reverse"` | `"normal"` | Initial movement direction. | | `easing` | `(value: number) => number` | — | Optional easing function for path progress. | | `slowdownOnHover` | `boolean` | `false` | Slow movement while an item is hovered. | | `slowDownFactor` | `number` | `0.3` | Speed multiplier while hovering. | | `slowDownSpringConfig` | `object` | `{ damping: 50, stiffness: 400 }` | Spring used for hover speed changes. | | `useScrollVelocity` | `boolean` | `false` | Add scroll velocity to the movement speed. | | `scrollAwareDirection` | `boolean` | `false` | Change direction from the latest scroll direction. | | `scrollSpringConfig` | `object` | `{ damping: 50, stiffness: 400 }` | Spring used for scroll velocity. | | `repeat` | `number` | `3` | Number of times to repeat slot content. | | `draggable` | `boolean` | `false` | Allow pointer dragging along the path. | | `dragSensitivity` | `number` | `0.2` | Multiplier applied to pointer drag velocity. | | `dragVelocityDecay` | `number` | `0.96` | Decay applied to released drag momentum. | | `dragAwareDirection` | `boolean` | `false` | Follow the latest drag direction automatically. | | `grabCursor` | `boolean` | `false` | Use grab and grabbing cursors when draggable. | | `enableRollingZIndex` | `boolean` | `true` | Layer items based on their current path position. | | `zIndexBase` | `number` | `1` | Starting z-index value. | | `zIndexRange` | `number` | `10` | Range added across the path. | | `cssVariableInterpolation` | `object[]` | `[]` | Interpolate CSS variables across path progress. | | `responsive` | `boolean` | `false` | Scale the path coordinate space to fit its container. | | `class` | `string` | — | Additional classes merged onto the root element. | Pass one or more elements as the default slot. Each slot element is repeated and positioned along the path. #credits - Ported from [Fancy Components Marquee Along SVG Path](https://fancycomponents.dev/docs/components/blocks/marquee-along-svg-path){rel=""nofollow""}. :: # Photo Gallery ::component-viewer --- component-files: - PhotoGallery.vue component-id: photo-gallery config: PhotoGalleryConfig demo-file: PhotoGalleryDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------- | ------------------- | ------- | ------------------------------------------------------ | | `items` | `"[{src: string}]"` | `[]` | Pass items / image src to animate | | `containerClass` | `string` | `""` | Additional tailwind CSS classes for container styling. | | `class` | `string` | `""` | Additional tailwind CSS classes for custom styling. | #credits - All images from [Pexels](https://www.pexels.com/@soldiervip/){rel=""nofollow""} - Thanks to [SivaReddy Uppathi](https://github.com/sivareddyuppathi){rel=""nofollow""} for providing this component. :: # Scroll Island ::component-viewer --- component-files: - ScrollIsland.vue component-id: scroll-island config: ScrollIslandConfig demo-file: ScrollIslandDemo.vue dependencies: "@number-flow/vue" --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------------ | ----------------------------------------------- | | `class` | `string` | `""` | Additional CSS classes for custom styling. | | `title` | `string` | `"Progress"` | Title displayed in the header of the component. | | `height` | `string` | `44` | Height of the component. | #credits - Inspired by the work of [Ali Samadi](https://x.com/alisamadi__/status/1854312982559502556){rel=""nofollow""} & [Nitish Khagwal](https://x.com/nitishkmrk){rel=""nofollow""} - [NumberFlow by Maxwell Barvian](https://number-flow.barvian.me/vue){rel=""nofollow""} for number formatting and animations. :: # Shader Toy Viewer ::component-viewer --- component-files: - ShaderToy.vue - InspiraShaderToy.ts component-id: shader-toy config: ShaderToyConfig demo-file: ShaderToyDemo.vue dependencies: ogl --- #api ## API | Prop Name | Type | Default | Description | | ------------ | ----------------------------------- | --------- | --------------------------------------------------------- | | `shaderCode` | `string` | `-` | GLSL fragment shader source code from ShaderToy. | | `uniforms` | `Record` | `{}` | Values for custom uniforms declared by the shader. | | `mouseMode` | `'click' | 'hover'` | `'click'` | Mouse tracking mode: either on click or continuous hover. | | `hue` | `number` | `0` | Adjust the hue of the shader output. | | `saturation` | `number` | `1` | Adjust the saturation of the shader output. | | `brightness` | `number` | `1` | Adjust the brightness of the shader output. | | `speed` | `number` | `1` | Adjust the speed of the shader output. | | `frameRate` | `number` | `60` | Caps render frequency for heavier shaders. | | `pixelRatio` | `number` | `1` | Controls canvas render scale for quality/performance. | | `paused` | `boolean` | `false` | Pauses playback manually. | | `autoPause` | `boolean` | `true` | Pauses rendering while off-screen or when the tab hides. | | `class` | `string` | `-` | Custom classes to apply to the container. | #credits - Built with [OGL](https://github.com/oframe/ogl){rel=""nofollow""}. - Inspired by [Shadertoy](https://shadertoy.com/){rel=""nofollow""} and adapted for Vue compatibility. :: # SVG Mask ::component-viewer --- component-files: - SVGMask.vue component-id: svg-mask config: SvgMaskConfig demo-file: SvgMaskDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------ | -------- | ------- | ------------------------------------------ | | `class` | `string` | `""` | Additional CSS classes for custom styling. | | `size` | `number` | `10` | Initial size of the mask in pixels. | | `revealSize` | `number` | `600` | Size of the mask during hover in pixels. | #credits - Ported from [Aceternity UI's SVG Mask Effect](https://ui.aceternity.com/components/text-generate-effect){rel=""nofollow""}. :: # Timeline ::component-viewer --- component-files: - Timeline.vue component-id: timeline config: TimelineConfig demo-file: TimelineDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------- | ---------------------------------- | ------- | -------------------------------------------------- | | `containerClass` | `string` | `""` | Additional CSS classes for the timeline container. | | `class` | `string` | `""` | Additional CSS classes for styling. | | `items` | `{ id: string; label: string; }[]` | `[]` | List of timeline items, each with an ID and label. | | `title` | `string` | `""` | Title of the timeline section. | | `description` | `string` | `""` | Description text displayed below the title. | #credits - Inspired and ported from [Aceternity UI's Timeline](https://ui.aceternity.com/components/timeline){rel=""nofollow""}. :: # Tracing Beam ::component-viewer --- component-files: - TracingBeam.vue component-id: tracing-beam config: TracingBeamConfig demo-file: TracingBeamDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | ------------------------------------------ | | `class` | `string` | `""` | Additional CSS classes for custom styling. | #credits - Ported from [Aceternity UI](https://ui.aceternity.com/components/tracing-beam){rel=""nofollow""}; :: # Animated Beam ::component-viewer --- component-files: - AnimatedBeam.vue component-id: animated-beam config: AnimatedBeamConfig demo-file: AnimatedBeamDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------------- | ------------- | ---------------------- | ---------------------------------------------------------------------------- | | `class` | `string` | `""` | Additional CSS classes to apply to the component for customization. | | `containerRef` | `HTMLElement` | N/A | Reference to the container element where the beam is rendered. | | `fromRef` | `HTMLElement` | N/A | Reference to the starting element from which the beam originates. | | `toRef` | `HTMLElement` | N/A | Reference to the ending element where the beam points to. | | `curvature` | `number` | `0` | Controls the curvature of the beam; higher values create a more curved path. | | `reverse` | `boolean` | `false` | Reverses the animation direction of the beam if set to `true`. | | `pathColor` | `string` | `"gray"` | Color of the beam's path. | | `pathWidth` | `number` | `2` | Stroke width of the beam's path. | | `pathOpacity` | `number` | `0.2` | Opacity of the beam's path. | | `gradientStartColor` | `string` | `"#FFAA40"` | Starting color of the beam's gradient animation. | | `gradientStopColor` | `string` | `"#9C40FF"` | Ending color of the beam's gradient animation. | | `delay` | `number` | `0` | Delay before the beam's animation starts, in seconds. | | `duration` | `number` | `Random between 4–7 s` | Duration of the beam's animation cycle, in seconds. | | `startXOffset` | `number` | `0` | Horizontal offset for the beam's starting point. | | `startYOffset` | `number` | `0` | Vertical offset for the beam's starting point. | | `endXOffset` | `number` | `0` | Horizontal offset for the beam's ending point. | | `endYOffset` | `number` | `0` | Vertical offset for the beam's ending point. | #credits - Inspired and ported from [Magic UI Animated Beam](https://magicui.design/docs/components/animated-beam){rel=""nofollow""}. :: # Border Beam ::component-viewer --- component-files: - BorderBeam.vue component-id: border-beam config: BorderBeamConfig demo-file: BorderBeamDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------- | -------- | ----------- | --------------------------------------------------------------------- | | `class` | `string` | `""` | Additional CSS classes for custom styling. | | `size` | `number` | `200` | Size of the animated border beam effect. | | `duration` | `number` | `15` | Duration of the animation in seconds. | | `borderWidth` | `number` | `1.5` | Width of the border around the beam effect. | | `anchor` | `number` | `90` | Anchor point for the beam, determining its position along the border. | | `colorFrom` | `string` | `"#ffaa40"` | Starting color for the gradient of the beam. | | `colorTo` | `string` | `"#9c40ff"` | Ending color for the gradient of the beam. | | `delay` | `number` | `0` | Delay before the animation starts, in seconds. | #credits - Ported from [Magic UI](https://magicui.design/docs/components/border-beam){rel=""nofollow""}. :: # Confetti ::component-viewer --- component-files: - Confetti.vue - ConfettiButton.vue component-id: confetti config: ConfettiConfig demo-file: ConfettiDemo.vue dependencies: canvas-confetti dev-dependencies: "@types/canvas-confetti" --- #api ## API ### Props #### `Confetti` | Prop Name | Type | Default | Description | | --------------- | ----------------------- | ------- | ----------------------------------------------------------------- | | `options` | `ConfettiOptions` | `{}` | Options for individual confetti bursts. | | `globalOptions` | `ConfettiGlobalOptions` | `{}` | Global options for the confetti instance (e.g., resize behavior). | | `manualstart` | `boolean` | `false` | If `true`, confetti won't start automatically on mount. | #### `ConfettiOptions` | Property | Type | Default | Description | | ------------------------- | -------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | `particleCount` | `number` | `50` | The number of confetti particles to launch. | | `angle` | `number` | `90` | The angle in degrees at which to launch the confetti. | | `spread` | `number` | `45` | The spread in degrees of the confetti. | | `startVelocity` | `number` | `45` | The initial velocity of the confetti particles. | | `decay` | `number` | `0.9` | The rate at which confetti particles slow down. | | `gravity` | `number` | `1` | The gravity applied to confetti particles. | | `drift` | `number` | `0` | The horizontal drift applied to confetti particles. | | `ticks` | `number` | `200` | The number of animation frames the confetti should last. | | `origin` | `{ x: number, y: number }` | `{ x: 0.5, y: 0.5 }` | The origin point (from 0 to 1) of the confetti emission. | | `colors` | `string[]` | `['#26ccff', '#a25afd', '#ff5e7e', '#88ff5a', '#fcff42', '#ffa62d', '#ff36ff']` | Array of color strings in HEX format for the confetti particles. | | `shapes` | `string[]` | `['square', 'circle']` | Array of shapes for the confetti particles. | | `scalar` | `number` | `1` | Scaling factor for confetti particle sizes. | | `zIndex` | `number` | `100` | The z-index value for the confetti canvas element. | | `disableForReducedMotion` | `boolean` | `false` | Disables confetti for users who prefer reduced motion. | | `useWorker` | `boolean` | `true` | Use a Web Worker for better performance. | | `resize` | `boolean` | `true` | Whether to automatically resize the canvas when the window resizes. | | `canvas` | `HTMLCanvasElement | null` | `null` | Custom canvas element to draw confetti on. | | `gravity` | `number` | `1` | The gravity applied to confetti particles. | | `drift` | `number` | `0` | The horizontal drift applied to particles. | | `flat` | `boolean` | `false` | If `true`, confetti particles will be flat (no rotation or 3D effect). | #### `ConfettiButton` | Prop Name | Type | Default | Description | | --------- | -------------------------------------------------- | ------- | ------------------------------------------------ | | `options` | `ConfettiOptions & { canvas?: HTMLCanvasElement }` | `{}` | Options for confetti when the button is clicked. | #credits - Built using the [canvas-confetti](https://www.npmjs.com/package/canvas-confetti){rel=""nofollow""} library. - Ported from [Magic UI Confetti](https://magicui.design/docs/components/confetti){rel=""nofollow""}. :: # Dither Shader ::component-viewer --- component-files: - DitherShader.vue component-id: dither-shader config: DitherShaderConfig demo-file: DitherShaderDemo.vue --- #api ## API | Prop | Type | Default | Description | | ----------------- | ------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------- | | `src` | `string` | `–` | Source image URL | | `gridSize` | `number` | `4` | Size of the dithering grid cells | | `ditherMode` | `"bayer" | "halftone" | "noise" | "crosshatch"` | `"bayer"` | Type of dithering pattern | | `colorMode` | `"original" | "grayscale" | "duotone" | "custom"` | `"original"` | Color processing mode | | `invert` | `boolean` | `false` | Invert the dithered output colors | | `pixelRatio` | `number` | `1` | Pixelation multiplier (1 = no pixelation, higher = more pixelated) | | `primaryColor` | `string` | `"#000000"` | Primary color for duotone mode | | `secondaryColor` | `string` | `"#ffffff"` | Secondary color for duotone mode | | `customPalette` | `string[]` | `["#000000", "#ffffff"]` | Custom color palette array for custom mode | | `brightness` | `number` | `0` | Brightness adjustment (-1 to 1) | | `contrast` | `number` | `1` | Contrast adjustment (0 to 2, 1 = normal) | | `backgroundColor` | `string` | `"transparent"` | Background color behind the dithered image | | `objectFit` | `"cover" | "contain" | "fill" | "none"` | `"cover"` | Object fit behavior | | `threshold` | `number` | `0.5` | Threshold bias for dithering (0 to 1) | | `animated` | `boolean` | `false` | Enable animation effect | | `animationSpeed` | `number` | `0.02` | Animation speed (lower = slower) | | `class` | `string` | `–` | Additional CSS classes for the container (use this to set size via Tailwind) | #credits - Inspired and ported from [Aceternity UI Dither Shader](https://ui.aceternity.com/components/dither-shader){rel=""nofollow""}. :: # Glow Border ::component-viewer --- component-files: - GlowBorder.vue component-id: glow-border config: GlowBorderConfig demo-file: GlowBorderDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | ------------------- | ------- | ---------------------------------------------------------- | | `duration` | `number` | `10` | Duration of the glowing border animation. | | `color` | `string | string[]` | `#FFF` | Color or array of colors to applied on the glowing border. | | `borderRadius` | `number` | `10` | Radius of the border. | | `borderWidth` | `number` | `2` | Width of the border. | #instructions Add following entry to inline theme in your `main.css` file. ```css @theme inline { --animate-glow: glow var(--duration) infinite linear; @keyframes glow { 0% { background-position: 0% 0%; } 50% { background-position: 100% 100%; } to { background-position: 0% 0%; } } } ``` #credits - Credits to [Magic UI](https://magicui.design/docs/components/shine-border){rel=""nofollow""} for this fantastic component. :: # Glowing Effect ::component-viewer --- component-files: - GlowingEffect.vue component-id: glowing-effect config: GlowingEffectConfig demo-file: GlowingEffectDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------------ | --------------------- | ----------- | ----------------------------------------------------------------------------------------------------- | | `blur` | `number` | `0` | The blur radius applied to the glow layer. | | `inactiveZone` | `number` | `0.7` | Defines the inner radius (as a fraction of the smallest dimension) within which the glow is inactive. | | `proximity` | `number` | `0` | Additional proximity distance (in pixels) to trigger the glow when the cursor is near the element. | | `spread` | `number` | `20` | Size of the spread of the glow effect around the element. | | `variant` | `"default" | "white"` | `"default"` | Variant of the glow style (e.g., a white-themed version). | | `glow` | `boolean` | `false` | Controls the visibility of the static glow border. | | `class` | `string` | `""` | Additional CSS classes for custom styling. | | `disabled` | `boolean` | `true` | Disables the proximity detection and glow animations when `true`. | | `movementDuration` | `number` | `2` | Duration (in seconds) of the smooth rotation animation. | | `borderWidth` | `number` | `1` | Width (in pixels) of the border applied to the glow effect. | #credits - Ported from (Aceternity UI Glowing Effect) [{rel=""nofollow""}] :: # Images Badge ::component-viewer --- component-files: - ImagesBadge.vue component-id: images-badge config: ImagesBadgeConfig demo-file: ImagesBadgeDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ----------------- | ----------------------------------- | --------------------------- | ------------------------------------------------------------------------- | | `text` | `string` | — | Text label displayed next to the folder badge. | | `images` | `string[]` | — | Array of image URLs to display (up to 3 are shown). | | `class` | `string` | — | Additional CSS classes for the root element. | | `href` | `string` | — | Optional link URL; renders an `` tag instead of `
` when provided. | | `target` | `string` | — | Link target attribute (e.g. `_blank` for new tab). | | `folderSize` | `{ width: number; height: number }` | `{ width: 32, height: 24 }` | Folder icon dimensions in pixels. | | `teaserImageSize` | `{ width: number; height: number }` | `{ width: 20, height: 14 }` | Image dimensions while peeking (idle state) in pixels. | | `hoverImageSize` | `{ width: number; height: number }` | `{ width: 48, height: 32 }` | Image dimensions when hovered in pixels. | | `hoverTranslateY` | `number` | `-35` | How far images translate upward on hover in pixels. | | `hoverSpread` | `number` | `20` | Horizontal spread between images on hover in pixels. | | `hoverRotation` | `number` | `15` | Fan rotation angle for images on hover in degrees. | #credits - Ported from [Aceternity UI Images Badge](https://ui.aceternity.com/components/images-badge){rel=""nofollow""} :: # Meteors ::component-viewer --- component-files: - Meteors.vue component-id: meteors config: MeteorsConfig demo-file: MeteorsDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------- | -------- | ------- | ----------------------------------------------------------------- | | `count` | `number` | `20` | The number of meteors to display in the animation. | | `class` | `string` | `""` | Additional CSS classes to apply to the meteors for customization. | #instructions Add following entry to inline theme in your `main.css` file. ```css @theme inline { --animate-meteor-effect: meteor 5s linear infinite; @keyframes meteor { 0% { transform: rotate(215deg) translateX(0); opacity: 1; } 70% { opacity: 1; } 100% { transform: rotate(215deg) translateX(-500px); opacity: 0; } } } ``` #credits - Ported from [Aceternity UI's Meteor Effect](https://ui.aceternity.com/components/meteors){rel=""nofollow""} :: # Neon Border ::component-viewer --- component-files: - NeonBorder.vue component-id: neon-border config: NeonBorderConfig demo-file: NeonBorderDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------------- | -------------------------- | ----------- | ----------------------------------------------- | | `color1` | `string` | `"#0496ff"` | Primary color of the neon border. | | `color2` | `string` | `"#ff0a54"` | Secondary color of the neon border. | | `animationType` | `"none" | "half" | "full"` | `"half"` | Type of animation effect applied to the border. | | `duration` | `number` | `6` | Duration of the animation effect in seconds. | | `class` | `string` | `""` | Additional CSS classes for styling. | #instructions Add following entry to inline theme in your `main.css` file. ```css @theme inline { --animate-neon-border: neon-border var(--neon-border-duration) linear infinite; @keyframes neon-border { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } } ``` #credits - Inspired by modern neon border effects. :: # Particle Image ::component-viewer --- component-files: - ParticleImage.vue - inspiraImageParticles.js - inspiraImageParticles.d.ts component-id: particle-image config: ParticleImageConfig demo-file: ParticleImageDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ----------------- | ----------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------- | | `imageSrc` | `string` | `null` | Source URL for the image to which the particle effect is applied. | | `class` | `string` | `null` | Additional CSS classes to apply to the image element. | | `canvasWidth` | `string` | `null` | Width of the particle effect canvas. | | `canvasHeight` | `string` | `null` | Height of the particle effect canvas. | | `gravity` | `string` | `null` | Gravity force affecting the particle movement. | | `particleSize` | `string` | `null` | Size of the particles. | | `particleGap` | `string` | `null` | Gap between particles. | | `mouseForce` | `string` | `null` | Force applied to particles based on mouse movement. | | `renderer` | `"default" | "webgl"` | `null` | The renderer to use for particle generation, either default or WebGL. | | `color` | `string` | `#FFF` | Hexadecimal color code used for particles. Supports 3 or 6 character hex codes. | | `colorArr` | `number[]` | `null` | Array of numbers to define multiple particle colors. | | `initPosition` | `"random" | "top" | "left" | "bottom" | "right" | "misplaced" | "none"` | `random` | Initial position of the particles when the animation starts. | | `initDirection` | `"random" | "top" | "left" | "bottom" | "right" | "none"` | `random` | Initial direction of the particles when the animation starts. | | `fadePosition` | `"explode" | "top" | "left" | "bottom" | "right" | "random" | "none"` | `none` | Position where the particles fade out. | | `fadeDirection` | `"random" | "top" | "left" | "bottom" | "right" | "none"` | `none` | Direction in which the particles fade out. | | `noise` | `number` | `null` | Noise of the particles. | | `responsiveWidth` | `boolean` | `false` | Should the canvas be responsive. | #credits - Credits to [Nuxt Labs](https://nuxtlabs.com){rel=""nofollow""} for this inspiration. - Credits to [NextParticles](https://nextparticle.nextco.de){rel=""nofollow""} for the base of the animation library. :: # Progressive Blur ::component-viewer --- component-files: - ProgressiveBlur.vue component-id: progressive-blur config: ProgressiveBlurConfig demo-file: ProgressiveBlurDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | --------------- | ------------------------------------- | ---------- | ------------------------------------------------------------ | | `direction` | `"top" | "right" | "bottom" | "left"` | `"bottom"` | Direction in which the blur progressively increases. | | `blurLayers` | `number` | `8` | Number of blur layers used to create the progressive effect. | | `blurIntensity` | `number` | `0.25` | Blur strength multiplier per layer (in pixels). | | `class` | `string` | `""` | Optional class applied to the wrapper container. | > This component also accepts all valid `motion-v` props for a `div`. #credits - Ported from [Motion Primitives Progressive Blur](https://motion-primitives.com/docs/progressive-blur){rel=""nofollow""}. - Powered by `motion-v` :: # Scales ::component-viewer --- component-files: - Scales.vue component-id: scales config: ScalesConfig demo-file: ScalesDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------- | ---------------------------------------- | ------------ | ------------------------------------------------------- | | `orientation` | `"horizontal" | "vertical" | "diagonal"` | `"diagonal"` | Direction of the repeating line pattern. | | `size` | `number` | `10` | Size of each repeating tile in pixels. | | `color` | `string` | — | CSS color value for the pattern lines. | | `class` | `string` | — | Additional CSS classes for the inner pattern overlay. | | `containerClass` | `string` | — | Additional CSS classes for the outer container element. | #credits - Ported from [Aceternity UI Scales](https://ui.aceternity.com/components/scales){rel=""nofollow""}. :: # Scratch To Reveal ::component-viewer --- component-files: - ScratchToReveal.vue component-id: scratch-to-reveal config: ScratchToRevealConfig demo-file: ScratchToRevealDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------------- | ------------------------ | ------- | --------------------------------------------------------------------------------------------- | | `class` | `string` | `""` | The class name to apply to the component. | | `width` | `number` | `""` | Width of the scratch container. | | `height` | `number` | `""` | Height of the scratch container. | | `minScratchPercentage` | `number` | `50` | Minimum percentage of scratched area to be considered as completed (Value between 0 and 100). | | `gradientColors` | `[string,string,string]` | `-` | Gradient colors for the scratch effect. | | Event Name | Payload | Description | | ---------- | ------- | -------------------------------------------------- | | `complete` | `-` | Callback function called when scratch is completed | | Slot Name | Default Content | Description | | --------- | --------------- | -------------------------------------- | | `default` | `-` | The text below the scratch-off ticket. | #credits - Credits to [Whbbit1999](https://github.com/Whbbit1999){rel=""nofollow""} for this component. - Inspired by [MagicUI Scratch To Reveal](https://magicui.design/docs/components/scratch-to-reveal){rel=""nofollow""}. :: # Spring Calendar ::component-viewer --- component-files: - SpringCalendar.vue - TextMorph.vue component-id: spring-calendar config: SpringCalendarConfig demo-file: SpringCalendarDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | -------------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------- | | `calendarData` | `Array<{ month: string; date: number; day: string; events?: { title: string; day: string; time: string }[] }>` | **—** | Array defining each calendar day and its optional events. *Required*. | | `initialIndex` | `number` | `0` | Day index initially selected. | ### Emits | Event | Payload | Description | | -------------------- | -------- | ------------------------------------------------------------------ | | `update:activeIndex` | `number` | Fires when a day button is clicked, emitting the new active index. | #credits - Inspired from the work of [sekachov](https://x.com/sekachov){rel=""nofollow""} :: # Animated Testimonials ::component-viewer --- component-files: - AnimatedTestimonials.vue component-id: animated-testimonials config: AnimatedTestimonialsConfig demo-file: AnimatedTestimonialsDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | --------------- | ------- | ---------------------------------------------------------------------------------------------- | | `testimonials` | `Testimonial[]` | `[]` | An array of testimonial objects containing quote, name, image, and designation. | | `autoplay` | `boolean` | `false` | Whether to cycle through testimonials automatically. | | `duration` | `number` | `5000` | Duration (in milliseconds) to wait before automatically transitioning to the next testimonial. | ### Testimonial Object Each testimonial object must contain the following fields: | Property | Type | Description | | ------------- | -------- | ----------------------------------------------------------------- | | `quote` | `string` | The testimonial text. | | `name` | `string` | The name of the person or entity providing the testimonial. | | `designation` | `string` | The position or role of the testimonial author (e.g., CEO, user). | | `image` | `string` | URL of the image or avatar for the testimonial author. | #credits - Ported from (Aceternity UI Animated Testimonials) [{rel=""nofollow""}]. :: # Design Testimonials ::component-viewer --- component-files: - DesignTestimonials.vue component-id: design-testimonials config: DesignTestimonialsConfig demo-file: DesignTestimonialsDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | ------------------- | ---------------- | -------------------------------------------------------------------- | | `title` | `string` | `"Testimonials"` | Vertical label shown on the left side of the layout. | | `duration` | `number` | `6000` | Time (in ms) before automatically switching to the next testimonial. | | `testimonials` | `TestimonialItem[]` | **required** | List of testimonial entries to render and animate. | ### `TestimonialItem` Object Each testimonial must follow this structure: | Property | Type | Description | | --------- | -------- | -------------------------------------------------------- | | `quote` | `string` | The testimonial text, animated word-by-word. | | `author` | `string` | Name of the testimonial author. | | `role` | `string` | Role or designation of the author. | | `company` | `string` | Company or organization name (used in badge and ticker). | #credits - Animation powered by `motion-v` - Ported from [Design Testimonials by Jatin Yadav](https://21st.dev/community/components/jatin-yadav05/design-testimonial/default){rel=""nofollow""} :: # Testimonial Slider ::component-viewer --- component-files: - TestimonialSlider.vue component-id: testimonial-slider config: TestimonialSliderConfig demo-file: TestimonialSliderDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | -------------- | ------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------- | | `testimonials` | `Array<{ img: string; quote: string; name: string; role: string }>` | `[]` | Array of testimonial objects displayed by the slider. | | `autoRotate` | `boolean` | `true` | If `true`, the slider advances automatically every `duration` seconds. | | `duration` | `number` | `5` | Interval in seconds between slides when auto‑rotation is enabled. | :: # 3D Text ::component-viewer --- component-files: - Text3d.vue component-id: text-3d config: Text3dConfig demo-file: Text3dDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------------- | --------- | ---------- | -------------------------------------------------- | | `textColor` | `string` | `"white"` | Color of the main text. | | `letterSpacing` | `number` | `-0.1` | Adjusts the spacing between letters in `ch` units. | | `strokeColor` | `string` | `"black"` | Color of the text stroke. | | `shadowColor` | `string` | `"yellow"` | Color of the text shadow. | | `strokeSize` | `number` | `20` | Thickness of the text stroke in pixels. | | `shadow1Size` | `number` | `7` | Size of the first shadow layer in pixels. | | `shadow2Size` | `number` | `10` | Size of the second shadow layer in pixels. | | `class` | `string` | `""` | Additional CSS classes for custom styling. | | `animate` | `boolean` | `true` | Enables wiggle animation when set to `true`. | | `animationDuration` | `number` | `1500` | Duration of the wiggle animation in milliseconds. | :: # Blur Reveal ::component-viewer --- component-files: - BlurReveal.vue component-id: blur-reveal config: BlurRevealConfig demo-file: BlurRevealDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------- | -------- | ------- | ---------------------------------------------------------------------------- | | `duration` | `number` | `1` | Duration of the blur fade in animation. | | `delay` | `number` | `1` | Delay between child components to reveal | | `blur` | `string` | `10px` | Amount of blur to apply to the child components. | | `yOffset` | `number` | `20` | Specifies the vertical offset distance (yOffset) for the entrance animation. | #credits - Credits to [Magic UI](https://magicui.design/docs/components/blur-fade){rel=""nofollow""} for this fantastic component. :: # Box Reveal ::component-viewer --- component-files: - BoxReveal.vue component-id: box-reveal config: BoxRevealConfig demo-file: BoxRevealDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------- | -------- | ----------- | ---------------------------------------------------- | | `color` | `string` | `"#5046e6"` | Background color of the reveal box. | | `duration` | `number` | `0.5` | Duration of the reveal animation in seconds. | | `delay` | `number` | `0.25` | Delay before the reveal animation starts in seconds. | | `class` | `string` | `""` | Additional CSS classes for custom styling. | #credits - Ported from [Magic UI Box Reveal](https://magicui.design/docs/components/box-reveal){rel=""nofollow""}. :: # Breathing Text ::component-viewer --- component-files: - BreathingText.vue - index.ts component-id: breathing-text config: BreathingTextConfig demo-file: BreathingTextDemo.vue --- #api ## API | Prop | Type | Default | Description | | --------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------------------------- | | `text` | `string` | Slot content | Text to split into independently animated letters. | | `as` | `string` | `"span"` | HTML element used for the root text node. | | `fromFontVariationSettings` | `string` | — | Font variation settings used at the start of each cycle. | | `toFontVariationSettings` | `string` | — | Font variation settings used at the end of each cycle. | | `transition` | `Transition` | `{ duration: 1.5, ease: "easeInOut" }` | Motion transition for each letter. | | `staggerDuration` | `number` | `0.1` | Delay between each letter's animation. | | `staggerFrom` | `"first" | "last" | "center" | number` | `"first"` | Origin used to calculate the stagger order. | | `repeatDelay` | `number` | `0.1` | Delay between repeated breathing cycles. | | `class` | `string` | — | Additional classes merged onto the root element. | Use a variable font and pass the axes it supports. For example, Roboto Flex can use `wght` and `wdth`. #credits - Ported from [Fancy Components Breathing Text](https://fancycomponents.dev/docs/components/text/breathing-text){rel=""nofollow""}. :: # Colourful Text ::component-viewer --- component-files: - ColourfulText.vue component-id: colourful-text config: ColourfulTextConfig demo-file: ColourfulTextDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `text` | `string` | `"black"` | The text string to be rendered with colorful animated characters. Each character will be individually animated with color transitions and motion effects. | | `colors` | `string[]` | `[ "rgb(131, 179, 32)", "rgb(47, 195, 106)", "rgb(42, 169, 210)", "rgb(4, 112, 202)", "rgb(107, 10, 255)", "rgb(183, 0, 218)", "rgb(218, 0, 171)", "rgb(230, 64, 92)", "rgb(232, 98, 63)", "rgb(249, 129, 47)", ]` | The text use colors. | | `startColor` | `string` | `"rgb(255,255,255)"` | The char start color. | | `duration` | `number` | `5` | The animation duration time in seconds. | #credits - Credits to [Whbbit1999](https://github.com/Whbbit1999){rel=""nofollow""} for this component. - Ported from [Aceternity UI Colourful Text](https://ui.aceternity.com/components/colourful-text){rel=""nofollow""} :: # Container Text Flip ::component-viewer --- component-files: - ContainerTextFlip.vue component-id: container-text-flip config: ContainerTextFlipConfig demo-file: ContainerTextFlipDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ------------------- | ---------- | ---------------------------------------------- | ---------------------------------------------------- | | `words` | `string[]` | `["better", "modern", "beautiful", "awesome"]` | Array of words to cycle through in the animation | | `interval` | `number` | `3000` | Time in milliseconds between word transitions | | `animationDuration` | `number` | `700` | Duration of the transition animation in milliseconds | | `class` | `string` | \`\` | Additional CSS classes to apply to the container | | `textClass` | `string` | \`\` | Additional CSS classes to apply to the text | #credits - Credits to [Whbbit1999](https://github.com/Whbbit1999){rel=""nofollow""} for this component. - Ported from [Aceternity UI Container Text Flip](https://ui.aceternity.com/components/container-text-flip){rel=""nofollow""}. :: # Encrypted Text ::component-viewer --- component-files: - EncryptedText.vue component-id: encrypted-text config: EncryptedTextConfig demo-file: EncryptedTextDemo.vue --- #api ## API | Prop Name | Type | Default | Description | | ---------------- | -------- | ---------------------------------------- | ------------------------------------------------------------ | | `text` | `string` | **required** | The text to render and reveal. | | `class` | `string` | `""` | Base class applied to the wrapper element. | | `revealDelayMs` | `number` | `50` | Delay (in ms) between revealing each next character. | | `flipDelayMs` | `number` | `50` | Delay (in ms) between re-scrambling unrevealed characters. | | `charset` | `string` | `A–Z a–z 0–9 !@#$%^&*()_+-={}[];:,.<>/?` | Character set used for the scrambled glyphs. | | `encryptedClass` | `string` | `""` | Class applied to characters while still encrypted/scrambled. | | `revealedClass` | `string` | `""` | Class applied to characters once revealed. | #credits - Ported from [Aceternity UI Encrypted Text](https://ui.aceternity.com/components/encrypted-text){rel=""nofollow""}. - Animation powered by `motion-v`. :: # 适甹äșŽ Vue 撌 Nuxt 的抚画组件。 # ć…„é—šæŒ‡ć— æŹąèżŽæ„ćˆ° [**Inspira UI**](https://inspira-ui.com){rel=""nofollow""}䞀äžȘäžș [Vue](https://vuejs.org){rel=""nofollow""} ćŒ€ć‘çš„ç€ŸćŒș驱抚éĄčç›źïŒ èż™äžȘé›†ćˆæäŸ›äș†çČŸçŸŽèźŸèźĄçš„ćŻć€ç”šç»„ä»¶ïŒŒç”æ„Ÿæ„è‡Ș [Aceternity UI](https://ui.aceternity.com){rel=""nofollow""} 撌 [Magic UI](https://magicui.design){rel=""nofollow""} æ‰€ćšçš„ä»€äșșæƒŠè‰łçš„ć·„äœœă€‚è™œç„¶æˆ‘ä»ŹäžŽèż™äș›éĄč盼æČĄæœ‰ć꘿–čè”çł»ïŒŒäœ†æˆ‘ä»Źć·ČèŽ·ćŸ— Aceternity UI 戛ć»șè€…çš„èźžćŻæ„äžș Vue ç”Ÿæ€çł»ç»Ÿè°ƒæ•Žé‚Łäș›ćŸˆæŁ’çš„èźŸèźĄă€‚æ­€ć€–ïŒŒInspira UI èż˜ćŒ…æ‹Źæˆ‘ä»ŹćŒ€ć‘çš„è‡Ș漚äč‰ç»„ä»¶ć’Œç€ŸćŒșèŽĄçŒźçš„ç»„ä»¶ă€‚ ### 慳äșŽ Inspira UI Inspira UI **äžæ˜Ż** 䌠统的组件ćș“ă€‚ç›žćïŒŒćꃿ˜Żäž€äžȘç»èż‡çČŸćżƒç­–ćˆ’çš„äŒ˜é›…ç»„ä»¶é›†ćˆïŒŒæ‚šćŻä»„èœ»æŸé›†æˆćˆ°æ‚šçš„ćș”甚皋ćșäž­ă€‚ćȘéœ€é€‰æ‹©æ‚šéœ€èŠçš„ć†…ćźčïŒŒć€ćˆ¶ä»Łç ïŒŒćč¶æ čæźæ‚šçš„éĄčç›źèż›èĄŒè‡Ș漚äč‰ă€‚ä»Łç æ˜Żæ‚šćŻä»„éšæ„äœżç”šć’Œäżźæ”č的 ### äžș什äčˆé€‰æ‹© Inspira UI èż™äžȘéĄčç›źè”·æșäșŽćĄ«èĄ„ Vue 瀟ćŒșäž­çŒșć°‘çš„ç±»äŒŒç»„ä»¶é›†ćˆçš„ç©șçŒș。Inspira UI 氆 Aceternity UI、Magic UI 撌è‡Ș漚äč‰èŽĄçŒźçš„çŸŽæ„Ÿć’ŒćŠŸèƒœćžŠç»™ VueïŒŒäœżćŒ€ć‘äșșć‘˜æ›Žćźč易构ć»ș什äșșæƒŠè‰łçš„ćș”甚皋ćșă€‚ ### 䞻芁ç‰č性 - 漌慹 [慍èŽčć’ŒćŒ€æș](https://github.com/unovue/inspira-ui){rel=""nofollow""} - 高ćșŠ [ćŻé…çœź](https://inspira-ui.com/cn/components) ä»„æ»Ąè¶łæ‚šçš„èźŸèźĄéœ€æ±‚ - èŒƒć›Žćčżæł›çš„ [组件](https://inspira-ui.com/cn/components) ćŻäŸ›é€‰æ‹© - äžșç§»ćŠšäœżç”šäŒ˜ćŒ– - 侎 Nuxt ćźŒć…šć…Œćźč ### è‡Žè°ą ç‰čćˆ«æ„Ÿè°ąïŒš - [Aceternity UI](https://ui.aceternity.com){rel=""nofollow""} 搯揑äș†èż™äžȘ Vue 适配。 - [Magic UI](https://magicui.design){rel=""nofollow""} 提䟛äș†èźŸèźĄç”æ„Ÿă€‚ - [shadcn-vue](https://www.shadcn-vue.com/){rel=""nofollow""} 提䟛äș† shadcn-ui 的 Vue ç«ŻćŁćč¶äžșæ–‡æĄŁèŽĄçŒźäș†äž€äș›ç»„件。 - [shadcn-docs-nuxt](https://github.com/ZTL-UwU/shadcn-docs-nuxt){rel=""nofollow""} çČŸćżƒæ‰“é€ çš„ Nuxt æ–‡æĄŁçœ‘ç«™ă€‚ ### 慳äșŽæˆ‘ ć—šïŒŒæˆ‘æ˜Ż [Rahul Vashishtha](https://rahulv.dev){rel=""nofollow""}ă€‚æˆ‘ćˆ›ć»șäș† Inspira UI ä»„ć°†ç±»äŒŒçš„äœ“éȘŒćžŠç»™ Vue ç”Ÿæ€çł»ç»ŸïŒŒç”æ„Ÿæ„è‡Ș Aceternity UI、Magic UI ć’Œç€ŸćŒșèŽĄçŒźă€‚æˆ‘äž€ç›ŽćœšćŠȘ抛æ”čèż›ćźƒă€‚æŹąèżŽæŸ„çœ‹æˆ‘ćœš [GitHub](https://github.com/rahul-vashishtha){rel=""nofollow""} äžŠçš„ć·„äœœïŒŒćč¶ćœš [èż™é‡Œ](https://github.com/unovue/inspira-ui){rel=""nofollow""} ćŠ ć…„æˆ‘çš„æ—…çš‹ïŒ èŻ·éšæ„æŽąçŽąćč¶äș«ć—äœżç”š Inspira UI èż›èĄŒæž„ć»ș的äčè¶ŁïŒ # ćź‰èŁ… æœŹæŒ‡ć—ć°†ćžźćŠ©äœ ćœš Vue 或 Nuxt ćș”ç”šäž­ćź‰èŁ…ćč¶é…çœź Inspira UI 组件。 ::warning ćŠ‚æžœäœ æ­Łćœšäœżç”š Tailwind CSS v3 **[èŻ·ćœšèż™é‡ŒæŸ„çœ‹ Inspira UI v1](https://v1.inspira-ui.com){rel=""nofollow""}。** :: ## ćŒ€ć§‹äœżç”š Inspira UI ::steps ### é…çœź `tailwindcss` éŠ–ć…ˆïŒŒèŻ·æŒ‰ç…§ [æ­€æŒ‡ć—](https://tailwindcss.com/docs/installation){rel=""nofollow""} ćź‰èŁ… `tailwindcss`。 ### æ·»ćŠ äŸè”– ćź‰èŁ…ä»„äž‹æ‰€éœ€çš„èŸ…ćŠ©ćș“。 :::code-group ```bash [npm] npm install @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ```bash [pnpm] pnpm install @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ```bash [bun] bun add @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ```bash [yarn] yarn add @vueuse/core motion-v tw-animate-css @inspira-ui/plugins ``` ::: èŻ·ć‚è€ƒæ­€æŒ‡ć—ïŒŒćœš [Vue 或 Nuxt](https://motion.dev/docs/vue){rel=""nofollow""} äž­é…çœź `motion-v`。 ### 曎新䜠的 `main.css` 文件 :::tip ćŠ‚æžœäœ æ­Łćœšäœżç”š `shadcn-vue` 或 ïŒŒćŻä»„è·łèż‡æ­€æ­„éȘ€ ::: ć°†ä»„äž‹ä»Łç æ·»ćŠ ćˆ°äœ çš„ `main.css` 文件䞭甚äșŽé…çœźç»„ä»¶æ‰€éœ€çš„ć˜é‡ïŒš :::tabs{.w-full} ::::tabs-item{icon="simple-icons:nuxt" label="Nuxt UI"} :::::code-collapse ```css [main.css] @import "tailwindcss"; @import "@nuxt/ui"; @theme static { --color-background: var(--ui-bg); --color-foreground: var(--ui-text); --color-card: var(--ui-bg-elevated); --color-card-foreground: var(--ui-text); --color-popover: var(--ui-bg-elevated); --color-popover-foreground: var(--ui-text); --color-muted: var(--ui-bg-muted); --color-muted-foreground: var(--ui-text-muted); --color-accent: var(--ui-bg-accented); --color-accent-foreground: var(--ui-text); --color-border: var(--ui-border); --color-input: var(--ui-border); --color-primary: var(--ui-primary); --color-primary-foreground: var(--ui-text-inverted); --color-secondary: var(--ui-secondary); --color-secondary-foreground: var(--ui-text-inverted); --color-destructive: var(--ui-error); --color-destructive-foreground: var(--ui-text-inverted); --color-ring: var(--ui-primary); --radius: var(--ui-radius); } :root { --background: var(--ui-bg); --foreground: var(--ui-text); --card: var(--ui-bg-elevated); --card-foreground: var(--ui-text); --popover: var(--ui-bg-elevated); --popover-foreground: var(--ui-text); --muted: var(--ui-bg-muted); --muted-foreground: var(--ui-text-muted); --accent: var(--ui-bg-accented); --accent-foreground: var(--ui-text); --border: var(--ui-border); --input: var(--ui-border); --primary: var(--ui-primary); --primary-foreground: var(--ui-text-inverted); --secondary: var(--ui-secondary); --secondary-foreground: var(--ui-text-inverted); --destructive: var(--ui-error); --destructive-foreground: var(--ui-text-inverted); --ring: var(--ui-primary); } ``` ::::: :::: ::::tabs-item{icon="simple-icons:tailwindcss" label="Other TailwindCSS Kit"} :::::code-collapse ```css [main.css] @import "tailwindcss"; @import "tw-animate-css"; @custom-variant dark (&:is(.dark *)); :root { --card: oklch(1 0 0); --card-foreground: oklch(0.141 0.005 285.823); --popover: oklch(1 0 0); --popover-foreground: oklch(0.141 0.005 285.823); --primary: oklch(0.21 0.006 285.885); --primary-foreground: oklch(0.985 0 0); --secondary: oklch(0.967 0.001 286.375); --secondary-foreground: oklch(0.21 0.006 285.885); --muted: oklch(0.967 0.001 286.375); --muted-foreground: oklch(0.552 0.016 285.938); --accent: oklch(0.967 0.001 286.375); --accent-foreground: oklch(0.21 0.006 285.885); --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: oklch(0.577 0.245 27.325); --border: oklch(0.92 0.004 286.32); --input: oklch(0.92 0.004 286.32); --ring: oklch(0.705 0.015 286.067); --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.141 0.005 285.823); } .dark { --background: oklch(0.141 0.005 285.823); --foreground: oklch(0.985 0 0); --card: oklch(0.141 0.005 285.823); --card-foreground: oklch(0.985 0 0); --popover: oklch(0.141 0.005 285.823); --popover-foreground: oklch(0.985 0 0); --primary: oklch(0.985 0 0); --primary-foreground: oklch(0.21 0.006 285.885); --secondary: oklch(0.274 0.006 286.033); --secondary-foreground: oklch(0.985 0 0); --muted: oklch(0.274 0.006 286.033); --muted-foreground: oklch(0.705 0.015 286.067); --accent: oklch(0.274 0.006 286.033); --accent-foreground: oklch(0.985 0 0); --destructive: oklch(0.396 0.141 25.723); --destructive-foreground: oklch(0.637 0.237 25.331); --border: oklch(0.274 0.006 286.033); --input: oklch(0.274 0.006 286.033); --ring: oklch(0.442 0.017 285.786); } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); } @layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } } html { color-scheme: light dark; } html.dark { color-scheme: dark; } html.light { color-scheme: light; } ``` ::::: :::: ::: :: ::tip{.mt-12 icon="tabler:check"} ć€ȘæŁ’äș†ïŒäœ çš„éĄč盼现朹ć·Čç»é…çœźćźŒæˆïŒŒćŻä»„äœżç”š Inspira UI äș†ă€‚ :: ### ćŻé€‰ïŒšæ·»ćŠ ć›Ÿæ ‡æ”ŻæŒ èźžć€š Inspira UI ç»„ä»¶ć’Œç€șäŸ‹äŒšäœżç”š `` ç»„ä»¶ć’Œ Iconify ć›Ÿæ ‡ă€‚è™œç„¶èż™æ˜ŻćŻé€‰çš„ïŒŒäœ†æˆ‘ä»ŹćŒșçƒˆæŽšèćź‰èŁ…ïŒŒä»„èŽ·ćŸ—æ›Žć„œçš„äœżç”šäœ“éȘŒă€‚ èŠćœšäœ çš„ Vue.js 或 Nuxt.js éĄčç›źäž­æ·»ćŠ ć›Ÿæ ‡æ”ŻæŒïŒŒèŻ·ć‚è€ƒ [Iconify Vue æŒ‡ć—](https://iconify.design/docs/icon-components/vue/){rel=""nofollow""}。 ### ćŒ€ć§‹äœżç”š Inspira UI 🚀 çŽ°ćœšïŒŒäœ ćŻä»„ćœšéĄčç›źäž­ćŒ€ć§‹äœżç”š Inspira UI 组件äș†ă€‚é€‰æ‹©äœ éœ€èŠçš„ç»„ä»¶ïŒŒć€ćˆ¶ä»Łç ïŒŒćč¶ć°†ć…¶é›†æˆćˆ°äœ çš„ćș”甚䞭。 # ćŠ‚äœ•èŽĄçŒź æ„Ÿè°ąæ‚šæœ‰ć…Žè¶Łäžș **Inspira UI** éĄč盼恚ć‡șèŽĄçŒźïŒæ‚šçš„èŽĄçŒźćžźćŠ©äœżèż™äžȘéĄč盼ćŻčæŻäžȘäșșéƒœæ›Žć„œă€‚èŻ·èŠ±äž€ç‚čæ—¶é—Žé˜…èŻ»èż™äș›æŒ‡ć—仄硼保éĄșç•…çš„ćäœœă€‚ ## ç›źćœ• 1. [ć…„é—š](https://inspira-ui.com/#%E5%85%A5%E9%97%A8) 2. [èĄŒäžș懆戙](https://inspira-ui.com/#%E8%A1%8C%E4%B8%BA%E5%87%86%E5%88%99) 3. [ćŠ‚äœ•èŽĄçŒź](https://inspira-ui.com/#%E5%A6%82%E4%BD%95%E8%B4%A1%E7%8C%AE) - [æŠ„ć‘Š Bug](https://inspira-ui.com/#%E6%8A%A5%E5%91%8A-bug) - [ć»șèźźæ”čèż›](https://inspira-ui.com/#%E5%BB%BA%E8%AE%AE%E6%94%B9%E8%BF%9B) - [æ·»ćŠ æ–°ç»„ä»¶](https://inspira-ui.com/#%E6%B7%BB%E5%8A%A0%E6%96%B0%E7%BB%84%E4%BB%B6) 4. [éĄčç›źç»“æž„](https://inspira-ui.com/#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84) 5. [éŁŽæ ŒæŒ‡ć—](https://inspira-ui.com/#%E9%A3%8E%E6%A0%BC%E6%8C%87%E5%8D%97) - [çŒ–ç æ ‡ć‡†](https://inspira-ui.com/#%E7%BC%96%E7%A0%81%E6%A0%87%E5%87%86) - [ç»„ä»¶æ ŒćŒ](https://inspira-ui.com/#%E7%BB%84%E4%BB%B6%E6%A0%BC%E5%BC%8F) - [提äș€æ¶ˆæŻ](https://inspira-ui.com/#%E6%8F%90%E4%BA%A4%E6%B6%88%E6%81%AF) 6. [æ–‡æĄŁæŒ‡ć—](https://inspira-ui.com/#%E6%96%87%E6%A1%A3%E6%8C%87%E5%8D%97) - [ć•æ–‡ä»¶ç»„ä»¶](https://inspira-ui.com/#%E5%8D%95%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6) - [ć€šæ–‡ä»¶ç»„ä»¶](https://inspira-ui.com/#%E5%A4%9A%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6) 7. [æ”‹èŻ•](https://inspira-ui.com/#%E6%B5%8B%E8%AF%95) 8. [èźžćŻèŻ](https://inspira-ui.com/#%E8%AE%B8%E5%8F%AF%E8%AF%81) --- ## ć…„é—š - **Fork 仓ćș“**ïŒšćœš GitHub 侊戛ć»șéĄč盼的äžȘäșșć‰ŻæœŹă€‚ - **態隆 Fork**ïŒšć°†æ‚šçš„ fork 仓ćș“ć…‹éš†ćˆ°æœŹćœ°æœș晹。 - **戛ć»șćˆ†æ”Ż**äžșæ‚šçš„èŽĄçŒźćˆ›ć»șæ–°ćˆ†æ”Ż (`git checkout -b feature/YourFeatureName`)。 - **ćź‰èŁ…äŸè”–**ïŒšèżèĄŒ `pnpm install` ä»„ćź‰èŁ…æ‰€æœ‰ćż…èŠçš„äŸè”–ă€‚ ## èĄŒäžș懆戙 é€šèż‡ć‚äžŽæ­€éĄčç›źïŒŒæ‚šćŒæ„é”ćźˆ [èĄŒäžș懆戙](https://inspira-ui.com/code-of-conduct)ïŒŒèŻ„ć‡†ćˆ™æ—šćœšè„é€ ćŒ€æ”Ÿć’ŒæŹąèżŽçš„çŽŻćąƒă€‚ ## ćŠ‚äœ•èŽĄçŒź ### æŠ„ć‘Š Bug ćŠ‚æžœæ‚šć‘çŽ° bugïŒŒèŻ·æ‰“ćŒ€äž€äžȘ [issue](https://github.com/unovue/inspira-ui/issues){:target="\_blank" rel=""nofollow""} ćč¶ćŒ…æ‹ŹïŒš - æž…æ™°è€Œæèż°æ€§çš„æ ‡éą˜ă€‚ - é‡çŽ°é—źéą˜çš„æ­„éȘ€ă€‚ - éą„æœŸć’Œćźžé™…ç»“æžœă€‚ - æˆȘć›Ÿæˆ–ä»Łç ç‰‡æź”ïŒˆćŠ‚é€‚ç”šïŒ‰ă€‚ ### ć»șèźźæ”čèż› æˆ‘ä»ŹæŹąèżŽæ–°ćŠŸèƒœæˆ–æ”čèż›çš„ć»șèźźă€‚èŻ·æ‰“ćŒ€äž€äžȘ [issue](https://github.com/unovue/inspira-ui/issues){:target="\_blank" rel=""nofollow""} ćč¶ćŒ…æ‹ŹïŒš - æž…æ™°è€Œæèż°æ€§çš„æ ‡éą˜ă€‚ - æ”čèż›çš„èŻŠç»†èŻŽæ˜Žă€‚ - ä»»äœ•ç›žć…łçš„ç€șäŸ‹æˆ–æšĄćž‹ă€‚ ### æ·»ćŠ æ–°ç»„ä»¶ æˆ‘ä»Źæ„Ÿè°ąäžșćș“æ·»ćŠ æ–°ç»„ä»¶çš„èŽĄçŒźă€‚èŻ·çĄźäżïŒš - èŻ„ç»„ä»¶é€šćžžæœ‰ç”šïŒŒćč¶äžŽéĄčç›źç›źæ ‡äž€è‡Žă€‚ - èŻ„ç»„ä»¶äžŽ **Nuxt** 撌 **Vue** ć…Œćźč。 - 悚達ćŸȘ例靱戗ć‡șçš„çŒ–ç ć’Œæ–‡æĄŁæŒ‡ć—ă€‚ - 悚äžșæ‚šçš„ç»„ä»¶ćŒ…æ‹Źć•ć…ƒæ”‹èŻ•ă€‚ #### ç»„ä»¶æŒ‡ć— 1. **戛ć»ș或曎新 `index.ts`**:br`components/content/inspira/ui//` äž‹çš„æŻäžȘ文件ć€č郜ćș”èŻ„æœ‰äž€äžȘ `index.ts`ïŒŒćŻŒć‡ș所有 Vue æ–‡ä»¶ă€‚äŸ‹ćŠ‚ïŒš ```ts // index.ts export { default as Book } from "./Book.vue"; export { default as BookDescription } from "./BookDescription.vue"; export { default as BookHeader } from "./BookHeader.vue"; export { default as BookTitle } from "./BookTitle.vue"; ``` 2. **æłšć†ŒèĄšäŸè”–éĄč** ćŠ‚æžœæ‚šçš„æ–°ç»„ä»¶äŸè”–ïŒˆæˆ–äœżç”šïŒ‰ć…¶ä»– Inspira UI ç»„ä»¶ïŒŒæ‚šćż…éĄ»æ›Žæ–° `~/scripts/crawl-content.ts` 侭的 `COMPONENT_DEPENDENCIES` æ˜ ć°„ä»„ćæ˜ èż™äș›ć…łçł»ă€‚èż™ćžźćŠ©ćș“ç†è§Łćœ“ç”šæˆ·é€šèż‡ CLI æ·»ćŠ ç»„ä»¶æ—¶ćș”èŻ„äž€è”·ćź‰èŁ…ć“Șäș›ç»„件。 3. **仅限 Nuxt çš„ćŠŸèƒœïŒš** ćŠ‚æžœæ‚šçš„æ–°ç»„ä»¶æˆ–ć…¶ç€șäŸ‹äœżç”šä»…é™ Nuxt çš„ćŠŸèƒœïŒˆćŠ‚ ``ïŒ‰ïŒŒèŻ·ćœšæ–‡æĄŁäž­æćŠă€‚èż™çĄźäżç”šæˆ·çŸ„é“ćœš Nuxt ć€–éƒšäœżç”šèŻ„ç»„ä»¶æ—¶ćŻèƒœć­˜ćœšé™ćˆ¶æˆ–éąć€–æ­„éȘ€ă€‚ :br èż™çĄźäżç”šæˆ·ćŻä»„é€šèż‡ CLI ćź‰èŁ…èŻ„ç»„ä»¶ïŒŒćč¶äž”所有䟝蔖éĄčéƒœæ­ŁçĄźćŁ°æ˜Žă€‚ 4. **éżć…ć€–éƒšç»„ä»¶ïŒš** 戛ć»șç»„ä»¶æ—¶ïŒŒéżć…äœżç”šäžć±žäșŽæ žćżƒ Vue.js ç”Ÿæ€çł»ç»Ÿçš„ć€–éƒš UI ç»„ä»¶ïŒˆćŠ‚ `` æˆ–ç±»äŒŒïŒ‰ă€‚ 5. **æ˜ŸćŒćŻŒć…„ïŒš** ćłäœżæ‚šćœšćŒ€ć‘èż‡çš‹äž­äœżç”š Nuxt 的è‡ȘćŠšćŻŒć…„ćŠŸèƒœïŒŒäčŸć§‹ç»ˆćœšç»„ä»¶ä»Łç äž­ćŒ…ć«æ˜ŸćŒćŻŒć…„ă€‚èż™çĄźäżäžŽæČĄæœ‰è‡ȘćŠšćŻŒć…„çš„ Vue.js ç”šæˆ·çš„ć…Œćźčæ€§ă€‚äŸ‹ćŠ‚ïŒš ```vue