shadcn-vue
repository·dev·Indexed 27 days ago
https://github.com/unovue/shadcn-vueA set of customizable and extensible UI components for Vue and Nuxt developers, serving as a port of shadcn/ui. Powered by headless libraries like Reka UI, it includes a CLI for scaffolding projects via `shadcn-vue create` and initializing existing ones via `shadcn-vue init`. It offers multiple visual styles (Vega, Nova, Maia, Lyra, Mira) and a dedicated Nuxt module called `shadcn-nuxt`.
What's inside shadcn-vue
- shadcn-vue is a Vue and Nuxt port of the original shadcn/ui. It provides a collection of reusable components designed for the Vue ecosystem, powered by headless component libraries like Reka UI. It is maintained by the unovue organization.
Overview of shadcn-vue with Tailwind v4
devshadcn-vue now supports Tailwind v4. Key updates include:
- CLI Support: The CLI can initialize projects directly with Tailwind v4.
- Theme Support: Full support for the
@themedirective and@theme inlineoption. - Component Updates: All components are updated for Tailwind v4, featuring a
data-slotattribute on every primitive for easier styling. - Styling Improvements: Component styles have been cleaned up, and HSL colors are now converted to OKLCH.
- Deprecations:
- The
toastcomponent is being deprecated in favor ofsonner. - The
defaultstyle is being deprecated; new projects will use thenew-yorkstyle.
- The
- Behavioral Changes: Buttons now use the default cursor.
Note: This is a non-breaking update. Existing apps using Tailwind v3 will continue to work. New components added to a v3 project will remain in v3 until the project is upgraded.
Build forms with VeeValidate and Zod
devThe Form component is an abstraction over
vee-validate. While the<Form />component is available, it is recommended to use theuseFormcomposable fromvee-validatebecause it provides automatic type safety for form values.Note: The Form component is no longer actively being developed. For future implementations, it is recommended to use the
<Field />component directly.Use shadcn MCP Tools for Registry Operations
devThe MCP server provides several tools for interacting with component registries.
Note: MCP tools are specifically for registry operations (search, view, install). For project configuration tasks like checking aliases, framework, or Tailwind version, use the CLI command
npx shadcn-vue@latest infoinstead, as there is no MCP equivalent for configuration inspection.Understand the shadcn-vue approach
devshadcn-vue is not a traditional NPM component library. Instead, it is a code distribution platform and a method for building your own component library. Unlike standard libraries where you import pre-packaged components, shadcn-vue provides you with the actual component source code. This allows for:
- Full Customization: You can edit the component code directly to fit your design system instead of using workarounds or wrappers.
- Transparency: You have full visibility into how every component is constructed.
- Predictable Composition: Components share a common, composable interface, making them predictable for developers and AI models.
- AI-Readiness: Because the code is open and follows a consistent pattern, LLMs can easily read, understand, and generate or improve components within your project.
Understand the Sidebar component structure
devThe
Sidebarcomponent is built using a composition pattern. It consists of the following sub-components:SidebarProvider: Manages the collapsible state and context.Sidebar: The main container.SidebarHeader: Sticky top section.SidebarFooter: Sticky bottom section.SidebarContent: The scrollable area for content.SidebarGroup: A logical section withinSidebarContent.SidebarTrigger: The component used to toggle the sidebar visibility.SidebarRail: A component for interaction/visuals (often used for resizing or visual cues).
Understand the shadcn-vue styling architecture
devStyles in this repository are implemented using a token-based system. A 'style' is defined in a single CSS file (e.g.,
apps/v4/registry/styles/style-{name}.css) that mapscn-*placeholder tokens to expanded Tailwind utility classes. These tokens are authored in the base component set (e.g.,apps/v4/registry/bases/reka/ui/**).How styles are applied:
- Build Time: The
buildStyles()script transforms base components by replacingcn-*tokens with their actual Tailwind expansions. This produces build artifacts inapps/v4/styles/reka-{name}/ui/**and registry JSON files inapps/v4/public/r/styles/reka-{name}/*.jsonfor CLI installation. - Runtime: The
assets/css/main.cssfile imports style files underlayer(base). Applying a class like.style-{name}to a DOM element allows it to render that specific style live (used by the customizer preview).
- Build Time: The
Understand the shadcn-vue Skill capabilities
devThe shadcn-vue skill provides AI assistants with several layers of project knowledge:
- Project Context: Automatically retrieves configuration via
shadcn-vue info --json(framework, Tailwind version, aliases, base library likereka, icon library, and installed components). - CLI Command Reference: Knowledge of all commands including
init,add,search,view,docs,diff,info, andbuild, including flags and presets. - Theming and Customization: Guidance on CSS variables, OKLCH colors, dark mode, custom colors, border radius, and component variants for both Tailwind v3 and v4.
- Registry Authoring: Instructions for building and publishing custom registries using the
registry.jsonformat. - MCP Server: Tools for AI assistants to search, browse, and install components directly from registries.
- Project Context: Automatically retrieves configuration via
Run your own shadcn-vue code registry
devTheshadcn-vueCLI supports running custom code registries. This allows you to distribute your own custom components, hooks, pages, configurations, and rules to any project you are working on.Understand shadcn-vue Theming Architecture
devshadcn-vue uses a three-layer system for theming:
- CSS Variables: Defined in
:root(light mode) and.dark(dark mode). - Tailwind Utilities: Tailwind maps these variables to utility classes like
bg-primaryortext-muted-foreground. - Components: Components consume these Tailwind utilities. Changing a CSS variable automatically updates all components referencing it.
Colors use the OKLCH format:
--variable: oklch(lightness chroma hue)(e.g.,--primary: oklch(0.205 0 0)).- CSS Variables: Defined in
Configure Field orientation and responsiveness
devThe
Fieldcomponent supports three orientation modes via theorientationprop:vertical(default): Stacks label, control, and helper text vertically.horizontal: Aligns the label and control side-by-side. UseFieldContentto keep descriptions aligned when using this mode.responsive: Automatically switches layouts based on container size.
Note for Responsive Layouts: If using Tailwind CSS v3, you must install
@tailwindcss/container-queries. To enable responsive switching, apply@container/field-groupclasses to theFieldGroupcomponent.<Field orientation="horizontal"> <FieldLabel for="remember">Remember me</FieldLabel> <Switch id="remember" /> </Field> <template> <FieldGroup class="@container/field-group flex flex-col gap-6"> <Field><!-- Fields --></Field> </FieldGroup> </template>Use the MessageScroller component
devThe
MessageScrolleris a headless scroll container designed for chat transcripts. It manages complex scrolling behaviors like anchoring turns, following streamed replies, and preserving position when history is prepended.Note: The
MessageScrollerProvidermust have a constrained height (or a height-bounded parent) so the viewport can scroll.Composition Structure:
MessageScrollerProvider └── MessageScroller ├── MessageScrollerViewport │ └── MessageScrollerContent │ └── MessageScrollerItem └── MessageScrollerButton<script setup lang="ts"> import { MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, } from '@/components/ui/message-scroller' </script> <template> <MessageScrollerProvider auto-scroll default-scroll-position="last-anchor"> <MessageScroller> <MessageScrollerViewport> <MessageScrollerContent> <MessageScrollerItem v-for="message in messages" :key="message.id" :message-id="message.id" :scroll-anchor="message.role === 'user'" > <!-- Message / Bubble / Marker goes here --> </MessageScrollerItem> </MessageScrollerContent> </MessageScrollerViewport> <MessageScrollerButton direction="end" /> </MessageScroller> </MessageScrollerProvider> </template>