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.
git checkout -b feature/YourFeatureName).pnpm install to install all necessary dependencies.By participating in this project, you agree to abide by the Code of Conduct, which aims to foster an open and welcoming environment.
If you find a bug, please open an issue and include:
We welcome suggestions for new features or improvements. Please open an issue and include:
We appreciate contributions that add new components to the library. Please ensure that:
index.tscomponents/content/inspira/ui/<component-folder-name>/ should have an index.ts that exports all Vue files. For example:// 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";
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.<ClientOnly>, please mention this in the documentation. This ensures users know there may be limitations or additional steps when using the component outside of Nuxt.This ensures that users can install the component through the CLI and that all dependencies are properly declared.
<UiButton> or similar) that are not part of the core Vue.js ecosystem.<script setup lang="ts">
import { useWindowSize } from "@vueuse/core";
import { onMounted, ref } from "vue";
// Include all imports explicitly
</script>
<Icon> component rather than pasting raw SVGs into your templates.Understanding the project structure is crucial for effective contribution:
components/content/inspira/ui/<component-folder-name>/.
index.ts file to export each component within that folder.components/content/inspira/examples/<component-folder-name>/.content/2.components/<category>/ directory.PascalCase for component names and filenames.Your Vue components should adhere to the following structure:
<!-- Template -->
<script lang="ts" setup>
// Your script code goes here
</script>
<!-- Script (if required) -->
<template>
<!-- Your template code goes here -->
</template>
<!-- Styles (if required) -->
<style scoped>
/* Your styles go here */
</style>
Props typing and code style
Refer to this Vue.js documentation page -> https://vuejs.org/api/sfc-script-setup#type-only-props-emit-declarations
<script lang="ts" setup>
const { msg = "hello", labels = ["one", "two"] } = defineProps<Props>();
// DON'T ⛔️
const props = defineProps({
whatever: { type: String, required: true },
optional: { type: String, default: "default" },
});
const props = withDefaults(defineProps<Props>(), { optional: "default" });
// DO ✅
interface Props {
whatever: string;
optional?: string;
}
// Or DO ✅ Props destructure (v3.5+)
interface Props {
msg?: string;
labels?: string[];
}
</script>
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. 😘
// 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<typeof COMPONENT_NAME_DIRECTION>;
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:
<script lang="ts" setup> for TypeScript and the Composition API.feat, fix, docs, etc.) followed by a short description.feat: add TextHoverEffect componentProper documentation is crucial for users to understand and effectively use the components. Follow these guidelines when adding documentation for new components.
components/content/inspira/ui/<component-folder-name>/.components/content/inspira/examples/<component-folder-name>/.content/2.components/<category>/ for your component's documentation.For components that are contained within a single .vue file, use the following template:
Begin with YAML front matter that includes the title and description:
---
title: Your Component Title
description: A brief description of what your component does.
---
Use the ComponentLoader to display a live preview of the component. The id should be set to the folder name of your component in components/content/inspira/examples/. In case, there is no folder, then id is not required.
::ComponentLoader{label="Preview" componentName="YourComponentDemo" type="examples" id="your-component-folder-name"}
::
If your component has special requirements or dependencies, add an alert section before the installation instructions:
::alert{type="info"}
**Note:** This component requires `package-name` as a dependency.
::
::alert{type="warning"}
**Note:** This component uses the `nuxt-only` syntax with the `<ClientOnly>`. If you are not using Nuxt, you can simply remove it.
::
Include both CLI and manual installation instructions. If additional setup is required (e.g., dependencies, Tailwind config updates), use a stepper to list all needed steps.
## Install using CLI
::InstallationCli{componentId="your-component-folder-name"}
::
## Install Manually
Copy and paste the following code
::CodeViewer{filename="YourComponent.vue" language="vue" componentName="YourComponent" type="ui" id="your-component-folder-name"}
::
Provide a table listing all props:
## API
| Prop Name | Type | Default | Description |
| --------- | --------- | ------- | ------------------------------ |
| `prop1` | `string` | `''` | Description of prop1. |
| `prop2` | `number` | `0` | Description of prop2. |
| `prop2` | `?number` | `0` | Description of prop2 optional. |
Example:
---
title: Text Hover Effect
description: A text hover effect that animates and outlines gradient on hover, as seen on x.ai
---
::ComponentLoader{label="Preview" componentName="TextHoverEffectDemo" type="examples"}
::
::alert{type="warning"}
This component uses the `nuxt-only` syntax with the `<ClientOnly>`. If you are not using Nuxt, you can simply remove it.
::
## Install using CLI
::InstallationCli{componentId="text-hover-effect"}
::
## Install Manually
Copy and paste the following code
::CodeViewer{filename="TextHoverEffect.vue" language="vue" componentName="TextHoverEffect" type="ui" id="text-hover-effect"}
::
## API
| Prop Name | Type | Default | Description |
| ------------- | -------- | -------- | --------------------------------------------------------- |
| `text` | `string` | Required | The text to be displayed with the hover effect. |
| `duration` | `number` | `200` | The duration of the mask transition animation in seconds. |
| `strokeWidth` | `number` | `0.75` | The width of the text stroke. |
| `opacity` | `number` | `null` | The opacity of the text. |
In this example, the id used in both ComponentLoader, CodeViewer and InstallationCli is text-hover-effect, which matches the folder name where the component and its demo are stored.
For components that consist of multiple files, such as a main component and several sub-components or variants, use the following template:
Begin with YAML front matter:
---
title: Your Components Group Title
description: A brief description of what this group of components does.
---
Include multiple ComponentLoader sections for each example or variant. The id should be set to the folder name of your component in components/content/inspira/examples/.
::ComponentLoader{label="Preview" componentName="ComponentVariantDemo" type="examples" id="your-component-folder-name"}
::
If your component has special requirements or dependencies, add an alert section before the installation instructions:
::alert{type="info"}
**Note:** This component requires `package-name` as a dependency.
::
::alert{type="warning"}
**Note:** This component uses the `nuxt-only` syntax with the `<ClientOnly>`. If you are not using Nuxt, you can simply remove it.
::
Include both CLI and manual installation instructions. If additional setup is required (e.g., dependencies, Tailwind config updates), use a stepper to list all needed steps.
## Install using CLI
::InstallationCli{componentId="your-component-folder-name"}
::
## Install Manually
Copy and paste the following code in the same folder
::code-group
:CodeViewerTab{label="YourComponent.vue" language="vue" componentName="YourComponent" type="ui" id="your-component-folder-name"}
:CodeViewerTab{filename="YourComponent2.vue" language="vue" componentName="YourComponent2" type="ui" id="your-component-folder-name"}
::
Provide comprehensive API documentation covering all components:
## API
| Prop Name | Type | Default | Description |
| --------- | -------- | ------- | --------------------------------------- |
| `prop1` | `string` | `''` | Description applicable to all variants. |
Example:
---
title: Pattern Background
description: Simple animated pattern background to make your sections stand out.
---
Grid background with dot
::ComponentLoader{label="Preview" componentName="PatternBackgroundDotDemo" type="examples" id="pattern-background"}
::
## Install using CLI
::InstallationCli{componentId="pattern-background"}
::
## Install Manually
Copy and paste the following code in the same folder
::code-group
:CodeViewerTab{label="PatternBackground.vue" language="vue" componentName="PatternBackground" type="ui" id="pattern-background"}
:CodeViewerTab{filename="index.ts" language="typescript" componentName="index" type="ui" id="pattern-background" extension="ts"}
::
## Examples
Grid background with big dot and ellipse on top
::ComponentLoader{label="Preview" componentName="PatternBackgroundBigDotDemo" type="examples" id="pattern-background"}
::
Grid background without animation
::ComponentLoader{label="Preview" componentName="PatternBackgroundGridDemo" type="examples" id="pattern-background"}
::
Small grid background with animation
::ComponentLoader{label="Preview" componentName="PatternBackgroundGridSmallDemo" type="examples" id="pattern-background"}
::
## API
| Prop Name | Type | Default | Description |
| ----------- | ------------------------------------------------------------------------------------------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `animate` | `boolean` | `false` | Set `true` if you want to animate the background. |
| `direction` | `top` \| `bottom` \| `left` \| `right` \| `top-left` \| `top-right` \| `bottom-left` \| `bottom-right` | `top` | Direction of the animation movement. You can use the const `PATTERN_BACKGROUND_DIRECTION.` |
| `direction` | `grid` \| `dot` | `grid` | Type of pattern. You can use the const `PATTERN_BACKGROUND_VARIANT.` |
| `size` | `xs` \| `sm` \| `md` \| `lg` | `md` | Size of the background pattern. |
| `mask` | `ellipse` \| `ellipse-top` | `ellipse` | Add a mask over the background pattern. You can use the const `PATTERN_BACKGROUND_MASK.` |
| `speed` | `number` | `10000` | Duration of the animation in `ms`, the bigger it is, the slower the animation. (`20000` slower than `5000`). You can use the const `PATTERN_BACKGROUND_SPEED.` |
### Custom variants, values and constants
You can customize your needs directly within the `index.ts` file. See code below.
## Credits
- Inspired by [Magic UI's Dot Pattern](https://magicui.design/docs/components/dot-pattern) component.
- Inspired by [Magic UI's Grid Pattern](https://magicui.design/docs/components/grid-pattern) component.
- Inspired by [Magic UI's Animated Grid Pattern](https://magicui.design/docs/components/animated-grid-pattern) component.
- Credits to [Nathan De Pachtere](https://nathandepachtere.com/) for porting this component.
pnpm build:registry, test the component installation in a separate project by referencing the local registry URL. For example:
npx shadcn-vue@latest add "https://localhost:3000/r/<component-name>"
PascalCase for component filenames and names.CodeViewer, CodeViewerTab, and ComponentLoader, the id parameter should be set to the folder name where the component is stored in components/content/inspira/ui/<component-folder-name>/ and components/content/inspira/examples/<component-folder-name>/. This helps in correctly linking the code and examples in the documentation.Demo component used in the ComponentLoader for previews, and place it in components/content/inspira/examples/<component-folder-name>/.By contributing, you agree that your contributions will be licensed under the MIT License.