# UI Thing Documentation > **Note:** This documentation corresponds to **UI Thing CLI v0.2.0** (major update). # Introduction **UI Thing** is a collection of beautifully designed, reusable UI components built specifically for **Nuxt**, powered by Reka UI and Tailwind CSS. This project is inspired by **shadcn/ui**, with adaptations to fit Nuxt's framework and developer ecosystem. > **Note:** This is *not* a traditional component library you install via npm. Instead, it hands you open, editable code-so you can pick the components you need, copy them into your app, and customize as you see fit. ## Why "UI Thing" for Nuxt? - **Open Code Philosophy**:br Every component is fully visible and editable-no wrappers or opaque abstractions. This gives you full control to adapt the UI to your design system. This makes it especially AI-friendly, letting models read, understand, and even generate new components. - **Nuxt-Native**:br Created with the Nuxt ecosystem at heart, UI Thing respects Nuxt's conventions-whether you're on Nuxt 3 or upgrading to Nuxt 4-and integrates smoothly with your app's structure and tooling. - **DIY, Your Way**:br Rather than bundling code you can't touch, UI Thing encourages you to copy, paste, and personalize any component. The code becomes entirely yours-no extra layers, no wrappers. - **Learn & Build**:br This project started as an experiment-and a fun one at that. I wanted to explore building an entire component reference for Nuxt, and along the way, I created a CLI to streamline the dev experience. --- ## Comparison Table | Feature | UI Thing (for Nuxt) | Traditional Component Library | | ------------------ | -------------------------- | -------------------------------- | | Distribution | Copy-paste + CLI | Publish to npm, import as a dep | | Customization | Directly edit code | Override or wrap components | | Nuxt Compatibility | Built for Nuxt conventions | Generic (may require adaptation) | | CLI Support | Yes | Sometimes minimal or none | | Ideal Use Case | Highly customizable UIs | Quick plug-and-play UIs | --- ## How to Use It 1. **Browse** [component](https://uithing.com/components/accordion) docs and [examples](https://uithing.com/examples/cards). 2. **Use the CLI** (`npx ui-thing@latest add `) to scaffold components into your project, or copy-paste code manually. 3. **Customize** each component freely-tweak styles, logic, responsive behavior, or layout as needed. # Setup So you want to use UI Thing in your Nuxt project? Great! This guide will walk you through the steps to get started. ## Prerequisites Before you can use UI Thing, you need to have a Nuxt project. If you don't have one yet, you can create one with the following command: ::prose-pm-x{command="nuxi@latest init my-app"} :: This will create a new Nuxt project in the `my-app` directory. You can then navigate to that directory and start the development server: ```bash cd my-app && npm run dev ``` ## Initialization Once you have a Nuxt project, you can initialize UI Thing with the following command: ::prose-pm-x{command="ui-thing@latest init"} :: This command will ask you a bunch of question the first time you run it ```bash ✔ Which theme do you want to start with? › Violet ✔ Where is your tailwind.css file located? … app/assets/css/tailwind.css ✔ Where should your components be stored? … app/components/Ui ✔ Where should your composables be stored? … app/composables ✔ Where should your plugins be stored? … app/plugins ✔ Where should your utils be stored? … app/utils ✔ Should we just replace component files if they already exist? … yes ✔ Would you like to use the default filename when adding components? … yes ✔ Which package manager do you use? › Npm ``` ## Adding components Once initialized, add components by running: ::prose-pm-x{command="ui-thing@latest add"} :: You'll be prompted to select the components you want. **UI Thing** will then: - Copy the selected components into your components directory - Add any required composables, utils, and plugins - Install missing dependencies - Update `nuxt.config` with necessary configuration ## Adding themes UI Thing ships with several pre-made themes. Add one to your project with: ::prose-pm-x{command="ui-thing@latest theme"} :: This will ask you to select the theme you want to add to your project. Once you have selected a theme, UI Thing will ask you if you want to overwrite your `tailwind.css` file. If you answer yes, it will overwrite your `tailwind.css` file with the theme you selected. ⚠️ Please note that this will overwrite your `tailwind.css` file. If you have made any changes to this file, you will lose them. ### Theme source The themes included in this cli all come from [shadcn/ui theme page](https://ui.shadcn.com/themes){rel="nofollow"}. So if you don't want to use this CLI to add themes, you can just customize your theme on that page and copy the code into your `tailwind.css` file. > Thanks shadcn for making these themes available for free! 🙏 # CLI ::prose-pm-x{command="ui-thing@latest"} :: ```sh Usage: ui-thing [options] [command] CLI for adding ui-thing components to your Nuxt application Options: -V, --version output the version number -h, --help display help for command Commands: init [options] Initialize UI Thing in your Nuxt project. add [options] [componentNames...] Add a list of components to your project. theme Add a new theme to your project. shortcuts Add the shortcuts composable to your project. prettier Add prettier config to your project. help [command] display help for command ``` ## init ::prose-pm-x{command="ui-thing@latest init"} :: This command will initialize UI Thing in your Nuxt project. This will: - Update your `nuxt.config` file - Add the necessary dependencies - Create a `ui-thing.config.ts` file with the default configuration It is recommended that you run this command in a new Nuxt project before adding any components. ```sh Usage: ui-thing init [options] Initialize UI Thing in your Nuxt project. ✅ Add tailwindcss to your project ✅ Update your nuxt.config file ✅ Add the necessary dependencies ✅ Create a ui-thing.config file with the default configuration Options: -f --force Overwrite config file if it exists. (default: false) -y --yes Skip prompts and use default values. (default: false) -n --nuxtVersion Specify the Nuxt version you are using. -h, --help display help for command ``` ## add ::prose-pm-x{command="ui-thing@latest add"} :: This command will add a list of components to your project. If no argument is passed, it will ask you to select from a list of available components. ```sh ? Select the components you want to add > Instructions: ↑/↓: Highlight option ←/→/[space]: Toggle selection [a,b,c]/delete: Filter choices enter/return: Complete answer Filtered results for: Enter something to filter ◯ Accordion ◯ Alert ◯ Alert Dialog ◯ ApexCharts ◯ Apexcharts ◯ Aspect Ratio ◯ Autocomplete ◯ Avatar ◯ Badge ◯ Border Beam ``` ## theme The theme command allows you to add a new theme to your project. You can visit the [themes page](https://ui.shadcn.com/themes){rel="nofollow"} on shadcn to see the available themes. ::prose-pm-x{command="ui-thing@latest theme"} :: Running this command allows you to select a theme from the list ```sh ? Which theme do you want to add? » > Zinc Slate Stone Gray Neutral Red Rose Orange Green ↓ Blue ``` ## prettier The prettier command allows you to add an opinionated prettier config to your project. ::prose-pm-x{command="ui-thing@latest prettier"} :: This will create a `.prettierrc` file that looks like this ```json { "arrowParens": "always", "endOfLine": "lf", "plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"], "printWidth": 100, "semi": true, "singleQuote": false, "tabWidth": 2, "trailingComma": "es5", "useTabs": false, "vueIndentScriptAndStyle": true, "tailwindFunctions": ["tv"], "importOrder": ["", "", "", "", "^[.]"] } ``` It will then instal the necessary dependencies and format your code. ## shortcuts The shortcuts command allows you to add the `shortcuts` composables to your project. ::prose-pm-x{command="ui-thing@latest shortcuts"} :: This will create a `shortcuts.ts` file in your `composables` directory. # Starters ## Counter ![Counter Starter Image](https://ui-thing-starter.behonbaker.com/__og-image__/image/og.png){.border} [Live Demo](https://ui-thing-starter.behonbaker.com/){rel="nofollow"} • [Github Repo](https://github.com/BayBreezy/ui-thing-starter){rel="nofollow"} The counter starter is a Nuxt app with UI Thing already initialized. ### Features - **Pinia** - A state management library for Vue/Nuxt - **Es Lint** - Nuxt eslint installed and configured - **Prettier** - Code formatter for consistent style - **Commit Lint** - Lint your commit messages - **Husky** - Git hooks for linting - **Lint Staged** - Lint staged files before commit # Shortcuts ## Credits I just want to say that this composable is coming directly from [Nuxt UI](https://ui.nuxt.com/){rel="nofollow"}. I am not the creator of this composable, I just wanted to share it with you because I think it's a really cool feature to have in your project. You can find the original docs here: [Nuxt UI - Shortcuts](https://ui.nuxt.com/composables/define-shortcuts){rel="nofollow"}. > Thanks Nuxt UI ♥ ## `defineShortcuts` The `defineShortcuts` composable allows you to define keyboard shortcuts in your app really easily. Try it out by pressing `Ctrl + v` ::shortcuts-ex-one :: ```vue [ShortcutsExOne.vue] ``` ## API ### `defineShortcuts(config: ShortcutsConfig, options?: ShortcutsOptions)` Define keyboard shortcuts for your application. - `config`: An object where keys are shortcut definitions and values are either handler functions or shortcut configuration objects. - `options`: Optional configuration for the shortcuts behavior. - `chainDelay`: The delay between key presses to consider the shortcut as chained. Default is `250`. Shortcuts keys are written as the literal keyboard key value. For a complete list of available shortcut keys, refer to the [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values){rel="nofollow"} API documentation. Note that the key should be written in lowercase. #### Shortcut Definition Shortcuts are defined using the following format: - Single key: `a`, `b`, `1`, `?`, etc. - Key combinations: Use `_` to separate keys, e.g., `meta_k`, `ctrl_shift_f` - Key sequences: Use `-` to define a sequence, e.g., `g-d` #### Modifiers - `meta`: Represents `⌘ Command` on macOS and `Ctrl` on other platforms - `ctrl`: Represents `Ctrl` on all platforms - `shift`: Used for alphabetic keys when Shift is required #### Special Keys - `escape`: Triggers on Esc key - `enter`: Triggers on Enter key - `arrowleft`, `arrowright`, `arrowup`, `arrowdown`: Trigger on respective arrow keys Examples of keys: - `escape`: will trigger by hitting `Esc` - `meta_k`: will trigger by hitting `⌘` and `K` at the same time on MacOS, and `Ctrl` and `K` on Windows and Linux - `ctrl_k`: will trigger by hitting `Ctrl` and `K` at the same time on MacOS, Windows and Linux - `shift_e`: will trigger by hitting `Shift` and `E` at the same time on MacOS, Windows and Linux - `?`: will trigger by hitting ? on some keyboard layouts, or for example Shift and /, which results in ? on US Mac keyboards - `g-d`: will trigger by hitting `g` then `d` with a maximum delay of 800ms by default - `arrowleft`: will trigger by hitting `←` (also: `arrowright`, `arrowup`, `arrowdown`) ### Shortcut Configuration Each shortcut can be defined as a function or an object with the following properties: ```ts interface ShortcutConfig { handler: () => void; usingInput?: boolean | string; } ``` - `handler`: Function to be executed when the shortcut is triggered - `usingInput`: - `false` (default): Shortcut only triggers when no input is focused - `true`: Shortcut triggers even when any input is focused - `string`: Shortcut only triggers when the specified input (by name) is focused ### `usingInput` Prop: `usingInput?: string | boolean` By default, `usingInput` is `false`, meaning it will only trigger when no input is focused. When set to `true`, the shortcut will also trigger when any input is focused. For a more advanced behavior, `usingInput` can be set to the name of an input, so it only triggers when focusing this specific input. ::show-case :::shortcuts-ex-two ::: #code ```vue [ShortcutsExTwo.vue] ``` :: ### Simple shortcut In case the shortcut does not need any config, it can be written as a function. ::shortcuts-ex-three :: ```vue [ShortcutsExThree.vue] ``` ## `useKbd` To get the OS specific meta key symbol, you can use the `useKbd` composable. ```vue ``` *`metaSymbol` will display either `⌘` on MacOS or `Ctrl` on any other OS* # Changelog ## October 31, 2025 ### New Field Components Added new interactive field components to enhance user input experiences: - **DocsFieldHear** - A hearing-style interactive field component - **DocsFieldNotionPrompt** - Notion-style prompt field with mentions and context ### Home Page Refactor Refactored the home page layout and added new HomeCards components for improved visual presentation. ### Utilities Added `no-scrollbar` utility class for improved user experience on scrollable elements. ## October 20, 2025 ### Prose Components Added a comprehensive collection of prose components for enhanced content rendering and documentation: #### Typography Components - **ProseH1-H6** - Heading components with anchor link support and customizable styles - **ProseP** - Paragraph component with customizable classes - **ProseLead** - Lead paragraph component for introductory text - **ProseStrong** - Strong text rendering component - **ProseEm** - Emphasized text component - **ProseBlockquote** - Styled blockquote component - **ProseA** - Customizable anchor links with styling - **ProseHr** - Horizontal rule component #### List Components - **ProseUl, ProseOl, ProseLi** - List components with customizable styles - **ProseIconList** - Lists with icons and multiple variants #### Table Components - Added complete table prose components for documentation tables #### Code Components - **ProseCodeGroup** - Tabbed interface for multiple code snippets - **ProseCodeSnippet** - Dynamic code imports with syntax highlighting - **ProsePre** - Enhanced code blocks with file name display and meta parsing - **ProseCodeTree** - Interactive file navigation component - Code collapse functionality - Copy button for code blocks #### Documentation Components - **ProseField & ProseFieldGroup** - Enhanced documentation for component props - **ProseCallout** - Callout component with various styles and variants - **ProseCard** - Card component with animated border effects - **ProseCollapsible** - Collapsible content with customizable icons - **ProseTabs** - Tabbed content for documentation - **ProseImage** - Custom image with zoom functionality - **ProseColorModeImage** - Adaptive images for light/dark modes - **ProseSmartIcon** - Smart icon component #### Package Manager Components - **ProsePmInstall** - Package installation commands - **ProsePmRun** - Package manager script execution - **ProsePmX** - Package manager command execution - Added `usePm` composable for package manager integration #### Typography Documentation Added comprehensive typography documentation showcasing all prose components and their usage. ## October 30, 2025 ### New Block Components Expanded the blocks section with multiple new component categories: #### Testimonial Blocks Added 8 new testimonial block variations featuring: - Carousel sliders with auto-rotation - Grid layouts with customer avatars - Star ratings and company logos - Masonry/Pinterest-style layouts #### Sign Up Blocks Added 4 new sign up page designs: - Two-column layouts with feature showcases - Password confirmation fields - Social authentication options - Compact and minimal card designs #### Pricing Blocks Added 4 new pricing section layouts: - Interactive annual/monthly toggles - Feature comparison grids - Popular plan badges - Four-tier pricing with custom options #### Login Blocks Added 4 new login page designs: - Two-column layouts with security messages - Minimal card designs with icon headers - Social-first authentication layouts - Compact designs with terms notices #### Metric Blocks Added 6 new metric display styles: - Icon-based compact layouts - Card-based designs with badges - Two-column contextual sections - Business metrics with growth indicators #### Newsletter Blocks Created 5 new newsletter signup blocks: - Centered layouts with badges - Card-based split designs - Multi-field forms with checkboxes - Feature showcase grids ### Documentation Updates Enhanced documentation across multiple sections: - Updated sidebar documentation with detailed descriptions - Improved navigation documentation - Enhanced header section documentation with style descriptions ### Component Updates - **Tiptap Editor**: Added new Tiptap editor block with toolbar and formatting options - **Nav Component**: Removed client-only wrapper for better performance - **Animated Tooltip**: Added new component with mouse tracking and animations ## October 27, 2025 ### New Block Components #### Password Recovery & Reset Implemented password recovery and reset components with enhanced layouts and validation. #### Footer Components Enhanced footer components with multiple layouts and styles. #### Feature Blocks Added multiple feature blocks with animations and responsive design. #### FAQ Components Enhanced FAQ components with multiple layouts and animations. #### Error Pages Added custom error pages (404, 500, etc.) with animations and helpful suggestions. #### CTA Components Enhanced call-to-action components with animations and new styles. ### Infrastructure - Added Dockerfile for building and running the application - Updated to Nuxt v4.2 ## September 4, 2023 ### UI Thing V2 Launch 🚀 Launched version 2 of UI Thing with a complete rebuild featuring: - Modern component architecture - Enhanced documentation - Improved developer experience - New component library built on Reka UI - Update to Tailwind CSS v4 - Comprehensive examples and blocks ## February 27, 2025 ### Timeline In this update, the [`Timeline`](https://uithing.com/components/timeline) component was added. You can add it by running ```bash npx ui-thing@latest add timeline ``` ## February 9, 2025 ### Progress In this update, the [`Progress`](https://uithing.com/components/progress) component was updated. There was an issue with how the transform value was being calculated. You can update it by running ```bash npx ui-thing@latest add progress ``` ### Description List The [`Description List`](https://uithing.com/components/description-list) component was added. You can try it out by running ```bash npx ui-thing@latest add description-list ``` ### Native Checkbox The [`Native Checkbox`](https://uithing.com/forms/veecheckbox-native) component was added. It was added because of some array issues I had with the Checkbox from Radix Vue. You can try it out by running ```bash npx ui-thing@latest add vee-native-checkbox ``` ## February 7, 2025 ### Loader In this update, I added the [`Loader`](https://uithing.com/components/loader) component. It was recommended in this [issue](https://github.com/BayBreezy/ui-thing/issues/77){rel="nofollow"}. You can try it out by running ```bash npx ui-thing@latest add loader ``` ## February 2, 2025 ### Form Builder In this update, I added the [`Form Builder`](https://uithing.com/forms/form-builder) component. I stumbled across an example in the Vee Validate docs and thought it would be nice to have something like this at hand. You can try it out by running ```bash npx ui-thing@latest add vee-form-builder ``` ## January 15, 2025 ### Tabs Im this update, I added some examples for the [`Tabs`](https://uithing.com/components/tabs) component. The examples are taken from the [Origin UI](https://originui.com/){rel="nofollow"} library. Thanks to the team over there for all the great free examples ❤️. You can run this command to add the updated tabs component to your project ```bash npx ui-thing@latest add tabs ``` ## January 15, 2025 ### Datatables Im this update, I added some examples for the [`Datatables`](https://uithing.com/components/datatable) component. The examples are taken from the [Origin UI](https://originui.com/){rel="nofollow"} library. Thanks to the team over there for all the great free examples ❤️. You can run this command to add the updated table component to your project ```bash npx ui-thing@latest add datatable ``` ## January 14, 2025 ### Table Im this update, I added some examples for the [`Table`](https://uithing.com/components/table) component. The examples are taken from the [Origin UI](https://originui.com/){rel="nofollow"} library. Thanks to the team over there for all the great free examples ❤️. You can run this command to add the updated table component to your project ```bash npx ui-thing@latest add table ``` ## December 28, 2024 ### Avatar Im this update, I added some examples for the [`Avatar`](https://uithing.com/components/avatar) component. The examples are taken from the [Origin UI](https://originui.com/){rel="nofollow"} library. Thanks to the team over there for all the great free examples ❤️. ## December 27, 2024 ### Input & Textarea In this update, the [`Input`](https://uithing.com/components/input) and [`Textarea`](https://uithing.com/components/textarea) components were updated. A new `pattern` & `maxlength` props was added to them both. Thanks to [arshx86](https://github.com/arshx86){rel="nofollow"}. You can try them out by running ```bash npx ui-thing@latest add input textarea ``` ## December 23, 2024 ### Breadcrumbs & Pagination In this update the [`Breadcrumbs`](https://uithing.com/components/breadcrumbs) component got a little update. You can now pass a `slot` in the array of items & customize what is displayed in that slot. ```html ``` You can try it out by running ```bash npx ui-thing@latest add breadcrumbs ``` ### Pagination The [`Pagination`](https://uithing.com/components/pagination) component got a little update too. For the core components, only an additional import statement was added from the Vue Use library. Some nice examples were copied over from the [Origin UI](https://originui.com/){rel="nofollow"} library. You can try it out by running ```bash npx ui-thing@latest add pagination ``` ## December 21, 2024 ### Carousel In this update, the `Carousel` component was added. Thanks to the [Shadcn Vue](https://www.shadcn-vue.com/){rel="nofollow"} team for doing the heavy lifting. You can try it out by running ```bash npx ui-thing@latest add carousel ``` ## December 17, 2024 ### Alert In this update, the `Alert` component was updated. Some cool examples were added from the [Origin UI](https://originui.com/){rel="nofollow"} library. To update just run this command in your project ```bash npx ui-thing@latest add alert ``` ### Vue Tippy The Goodies section was updated with the [Vue Tippy](https://uithing.com/goodies/vue-tippy) package. You can create cool tooltips with it. The `Tooltip` component still works so now you have two options to choose from 🎉. ## December 15, 2024 ### Sliders In this update, the `Slider` component was updated to accommodate `vertical` orientation. While adding some examples from the [Origin UI](https://originui.com/){rel="nofollow"} library, I noticed that the `Slider` component was missing the necessary classes that would make it work in a vertical orientation. ### Vertical Slider You can check out all the awesome examples here: [Sliders](https://uithing.com/components/slider#origin-ui-examples). ### Checkboxes? I also add some examples of checkboxes from the [Origin UI](https://originui.com/){rel="nofollow"} library. You can check them out here: [Checkboxes](https://uithing.com/forms/veecheckbox#origin-ui-examples). ## December 11, 2024 - More Examples & Refactor ### Refactor In this update, I made some minor fixes to some components that were using `className` instead of `class`. Some of the code examples were also updated: - [Dropdown Menu](https://uithing.com/components/dropdownmenu) - [Navigation Menu](https://uithing.com/components/navigationmenu) - [Sidebar](https://uithing.com/components/sidebar) - [Stepper](https://uithing.com/components/stepper) ### Button Examples I added more button examples to the [Button](https://uithing.com/components/button) page. Shoutout to the [Origin UI](https://originui.com/){rel="nofollow"} team for providing these examples 🙏. ### Dialogs Some dialog examples were added to the [Dialog](https://uithing.com/components/dialog) page. These examples are taken from the [Origin UI](https://originui.com/){rel="nofollow"} library as well. I hope to add some more examples soon. ## December 1, 2024 ### VueForm Slider Let me start by giving credit to the [VueForm Slider](https://github.com/vueform/slider){rel="nofollow"} creators ❤️. In this release, I added the [`VeeVueFormSlider`](https://uithing.com/forms/vee-vueformslider) component to the forms section. Yes, there is an existing `Slider` component provided [here](https://uithing.com/components/slider). The problem with this component is that the `v-model` directive returns an array. ALWAYS! This is coming from the implementation provided by Reka UI. Based on the issue raised here [#38](https://github.com/BayBreezy/ui-thing/issues/38){rel="nofollow"}, I decided to create a new slider component that returns a single value. This is the [`VeeVueFormSlider`](https://uithing.com/forms/vee-vueformslider) component. The cool thing is that this one has built in support for `vee-validate` 🙂. You can try it out by running ```bash npx ui-thing@latest add vee-vue-form-slider ``` ## November 20, 2024 ### Sidebar & Placeholder In this release, the [`Sidebar`](https://uithing.com/components/sidebar) component was added to the components section. Thanks to this issue here [#32](https://github.com/BayBreezy/ui-thing/issues/32){rel="nofollow"}, I saw that shadcn-ui added a [`Sidebar`](https://uithing.com/components/sidebar) component to their library. The guys at shadcn-vue had already created a port of this, so I used most of that code to create the [`Sidebar`](https://uithing.com/components/sidebar) component. Thanks to all the great devs that made this component possible ❤️. As for the [`Placeholder`](https://uithing.com/components/placeholder) component, this one was taken from the guys at [Nuxt UI](https://ui.nuxt.com/){rel="nofollow"} 🙏. ### Sidebar Blocks If you want to copy and paste some Sidebar blocks, you can check out the [Sidebar Blocks](https://uithing.com/blocks/sidebar) page. The examples are taken from the shadcn-ui library 🙂. ## November 14, 2024 ### Input Examples In this update, a tonne of Input examples were added to the [Vee Input](https://uithing.com/forms/veeinput) page. Thanks to the maintainers of the [Origin UI](https://originui.com/){rel="nofollow"} library for providing these examples 🙏. Check them out & let me know what you think. The [`Password Strength`](https://uithing.com/forms/veeinput#input-with-password-strength-indicator) example is really cool 😎. ## October 31, 2024 ### Button Styles In this release, I added a few button styles to the [Button](https://uithing.com/components/button) page. The examples are taken from [Enhanced Button](https://enhanced-button.vercel.app/){rel="nofollow"} ❤️. Check them out & let me know what you think. # Cards ::page-ex-cards :: # Dashboard ::page-ex-dashboard :: # Schema Visualizer ::page-ex-schema-visualizer :: # Accordion ## Source code Click :source-code-link{component="Accordion"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Anatomy Pass a list of `items` to the component. ```vue [Accordion Anatomy.vue] lines ``` Or use each part individually ```vue [Accordion Anatomy.vue] lines ``` ## Installation ::prose-pm-x{command="ui-thing@latest add accordion"} :: ## Usage ### Basic The most common way to use the accordion is by just passing an array of items to the `items` prop. Each item should have a `value`, `title`, and `content`. ::show-case :::docs-accordion ::: #code ```vue [DocsAccordion.vue] ``` :: ### Custom styling If you want to change the way that the items look, you can do so by using the different components that the accordion is composed of. ::show-case :::docs-accordion-variant ::: #code ```vue [DocsAccordionVariant.vue] ``` :: ### Custom icon You can change the `icon` that is displayed based on the open state of an item. Just override the the `trigger` slot and then override the `icon` slot. ::show-case :::docs-accordion-icon ::: #code ```vue [DocsAccordionIcon.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/accordions){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### With Chevron ::show-case :::docs-accordion-with-chevron ::: #code ```vue [DocsAccordionWithChevron.vue] ``` :: ### With Chevron Left ::show-case :::docs-accordion-with-chevron-left ::: #code ```vue [DocsAccordionWithChevronLeft.vue] ``` :: ### With Chevron & Icon ::show-case :::docs-accordion-with-chevron-icon ::: #code ```vue [DocsAccordionWithChevronIcon.vue] ``` :: ### With Sub-Header & Chevron ::show-case :::docs-accordion-with-chevron-sub-header ::: #code ```vue [DocsAccordionWithChevronSubHeader.vue] ``` :: ### With Icon, Sub-Header & Chevron ::show-case :::docs-accordion-with-chevron-sub-header-icon ::: #code ```vue [DocsAccordionWithChevronSubHeaderIcon.vue] ``` :: ### Tabs with Chevron ::show-case :::docs-accordion-tabs-with-chevron ::: #code ```vue [DocsAccordionTabsWithChevron.vue] ``` :: ### Tabs with Left Chevron ::show-case :::docs-accordion-tabs-with-chevron-left ::: #code ```vue [DocsAccordionTabsWithChevronLeft.vue] ``` :: ### Table with Chevron ::show-case :::docs-accordion-table-with-chevron ::: #code ```vue [DocsAccordionTableWithChevron.vue] ``` :: ### Table with Left Chevron ::show-case :::docs-accordion-table-with-chevron-left ::: #code ```vue [DocsAccordionTableWithChevronLeft.vue] ``` :: ### Multi-Level ::show-case :::docs-accordion-multi-level ::: #code ```vue [DocsAccordionMultiLevel.vue] ``` :: # Alert ## Source code Click :source-code-link{component="Alert"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add alert"} :: ## Usage ### Basic ::show-case :::docs-alert ::: #code ```vue [DocsAlert.vue] ``` :: ### Destructive ::show-case :::docs-alert-destructive ::: #code ```vue [DocsAlertDestructive.vue] ``` :: ### Border ::show-case :::docs-alert-border ::: #code ```vue [DocsAlertBorder.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/alerts-notifications-banners){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Warning ::show-case :::docs-alert-warning ::: #code ```vue [DocsAlertWarning.vue] ``` :: ### Warning Outline ::show-case :::docs-alert-warning-outline ::: #code ```vue [DocsAlertWarningOutline.vue] ``` :: ### Error ::show-case :::docs-alert-error ::: #code ```vue [DocsAlertError.vue] ``` :: ### Error Outline ::show-case :::docs-alert-error-outline ::: #code ```vue [DocsAlertErrorOutline.vue] ``` :: ### Info ::show-case :::docs-alert-info ::: #code ```vue [DocsAlertInfo.vue] ``` :: ### Info Outline ::show-case :::docs-alert-info-outline ::: #code ```vue [DocsAlertInfoOutline.vue] ``` :: ### Success ::show-case :::docs-alert-success ::: #code ```vue [DocsAlertSuccess.vue] ``` :: ### Success Outline ::show-case :::docs-alert-success-outline ::: #code ```vue [DocsAlertSuccessOutline.vue] ``` :: ### End Link ::show-case :::docs-alert-end-link ::: #code ```vue [DocsAlertEndLink.vue] ``` :: ### Sub Data ::show-case :::docs-alert-sub-data ::: #code ```vue [DocsAlertSubData.vue] ``` :: ### Close Button ::show-case :::docs-alert-close-button ::: #code ```vue [DocsAlertCloseButton.vue] ``` :: ## Notifications ### Close Button w/ Undo ::show-case :::docs-alert-notification-single-button ::: #code ```vue [DocsAlertNotificationSingleButton.vue] ``` :: ### Double Button ::show-case :::docs-alert-notification-double-button ::: #code ```vue [DocsAlertNotificationDoubleButton.vue] ``` :: ### Success Learn More ::show-case :::docs-alert-notification-success-more ::: #code ```vue [DocsAlertNotificationSuccessMore.vue] ``` :: ### Privacy ::show-case :::docs-alert-notification-privacy ::: #code ```vue [DocsAlertNotificationPrivacy.vue] ``` :: ### Version Update ::show-case :::docs-alert-notification-version ::: #code ```vue [DocsAlertNotificationVersion.vue] ``` :: ### Mentioned ::show-case :::docs-alert-notification-mention ::: #code ```vue [DocsAlertNotificationMention.vue] ``` :: # Alert Dialog ## Source code Click :source-code-link{component="AlertDialog"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add alert-dialog"} :: ## Usage ### Simple ::show-case :::docs-alert-dialog ::: #code ```vue [DocsAlertDialog.vue] ``` :: ### Stacked Left ::show-case :::docs-alert-dialog-stacked-left ::: #code ```vue [DocsAlertDialogStackedLeft.vue] ``` :: ### Media ::show-case :::docs-alert-dialog-media ::: #code ```vue [DocsAlertDialogMedia.vue] ``` :: ### Alert w/ Icon ::show-case :::docs-alert-dialog-with-icon ::: #code ```vue [DocsAlertDialogWithIcon.vue] ``` :: # Aspect Ratio ## Source code Click :source-code-link{component="AspectRatio"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add aspect-ratio"} :: ## Usage Right click the image to perform different actions. ::show-case :::docs-aspect-ratio ::: #code ```vue [DocsAspectRatio.vue] ``` :: # Autocomplete ## Source code Click :source-code-link{component="Autocomplete"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add autocomplete"} :: ## Usage ### Basic ::show-case :::docs-auto-complete-basic ::: #code ```vue [DocsAutoCompleteBasic.vue] ``` :: ### Objects ::show-case :::docs-auto-complete-objects ::: #code ```vue [DocsAutoCompleteObjects.vue] ``` :: ### Multiple ::show-case :::docs-auto-complete-multiple ::: #code ```vue [DocsAutoCompleteMultiple.vue] ``` :: ### Async This example shows how you can search for a value and make a call to your API for the results. ::show-case :::docs-auto-complete-async ::: #code ```vue [DocsAutoCompleteAsync.vue] ``` :: # Avatar ## Source code Click :source-code-link{component="Avatar"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add avatar"} :: ## Usage ::show-case :::docs-avatar ::: #code ```vue [DocsAvatar.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/avatars-badges){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Simple ::show-case :::docs-avatar-simple ::: #code ```vue [DocsAvatarSimple.vue] ``` :: ### Initials Only ::show-case :::docs-avatar-initial-only ::: #code ```vue [DocsAvatarInitialOnly.vue] ``` :: ### Icon Only ::show-case :::docs-avatar-icon-only ::: #code ```vue [DocsAvatarIconOnly.vue] ``` :: ### Chip ::show-case :::docs-avatar-chip ::: #code ```vue [DocsAvatarChip.vue] ``` :: ### Badge ::show-case :::docs-avatar-badge ::: #code ```vue [DocsAvatarBadge.vue] ``` :: ### Group ::show-case :::docs-avatar-group ::: #code ```vue [DocsAvatarGroup.vue] ``` :: ### Badge Group ::show-case :::docs-avatar-badge-group ::: #code ```vue [DocsAvatarBadgeGroup.vue] ``` :: # Badge ## Source code Click :source-code-link{component="Badge.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add badge"} :: ## Variants ### Default ::show-case :::docs-badge-default ::: #code ```vue [DocsBadgeDefault.vue] ``` :: ### Destructive ::show-case :::docs-badge-destructive ::: #code ```vue [DocsBadgeDestructive.vue] ``` :: ### Outline ::show-case :::docs-badge-outline ::: #code ```vue [DocsBadgeOutline.vue] ``` :: ### Secondary ::show-case :::docs-badge-secondary ::: #code ```vue [DocsBadgeSecondary.vue] ``` :: ### Shadcn ::show-case :::docs-badge-shadcn ::: #code ```vue [DocsBadgeShadcn.vue] ``` :: ### Origin UI ::show-case :::docs-badge-origin-u-i ::: #code ```vue [DocsBadgeOriginUI.vue] ``` :: ## Sizes Three sizes are available for badges: `sm`, `md`, and `lg`. ::show-case :::docs-badge-sizes ::: #code ```vue [DocsBadgeSizes.vue] ``` :: # Breadcrumbs ## Source code Click :source-code-link{component="Breadcrumbs.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add breadcrumbs"} :: ## Usage ### Basic ::show-case :::docs-breadcrumbs ::: #code ```vue [DocsBreadcrumbs.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/breadcrumbs-paginations){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Dots Dropdown ::show-case :::docs-breadcrumbs-dot-dropdown ::: #code ```vue [DocsBreadcrumbsDotDropdown.vue] ``` :: ### Icon Dropdown ::show-case :::docs-breadcrumbs-icon-dropdown ::: #code ```vue [DocsBreadcrumbsIconDropdown.vue] ``` :: ### Icons ::show-case :::docs-breadcrumbs-icons ::: #code ```vue [DocsBreadcrumbsIcons.vue] ``` :: ### Separator ::show-case :::docs-breadcrumbs-separator ::: #code ```vue [DocsBreadcrumbsSeparator.vue] ``` :: ### Bordered ::show-case :::docs-breadcrumbs-bordered ::: #code ```vue [DocsBreadcrumbsBordered.vue] ``` :: ### Select ::show-case :::docs-breadcrumbs-select ::: #code ```vue [DocsBreadcrumbsSelect.vue] ``` :: # Button ## Source code Click :source-code-link{component="Button.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add button"} :: ## Plain Buttons Here we have a few examples of the plain buttons. ### Default Button ::show-case :::docs-button-default ::: #code ```vue [DocsButtonDefault.vue] ``` :: ### Secondary Button ::show-case :::docs-button-secondary ::: #code ```vue [DocsButtonSecondary.vue] ``` :: ### With Icon ::show-case :::docs-button-with-icon ::: #code ```vue [DocsButtonWithIcon.vue] ``` :: ### Loading ::show-case :::docs-button-loading ::: #code ```vue [DocsButtonLoading.vue] ``` :: ### Outline ::show-case :::docs-button-outline ::: #code ```vue [DocsButtonOutline.vue] ``` :: ### Destructive ::show-case :::docs-button-destructive ::: #code ```vue [DocsButtonDestructive.vue] ``` :: ### Ghost ::show-case :::docs-button-ghost ::: #code ```vue [DocsButtonGhost.vue] ``` :: ### Link ::show-case :::docs-button-link ::: #code ```vue [DocsButtonLink.vue] ``` :: ### Icon ::show-case :::docs-button-icon-only ::: #code ```vue [DocsButtonIconOnly.vue] ``` :: ## Sizes Here are the different sizes that are available for the buttons. ### Regular Button Sizes ::show-case :::docs-button-sizes ::: #code ```vue [DocsButtonSizes.vue] ``` :: ### Icon Button Sizes ::show-case :::docs-button-icon-sizes ::: #code ```vue [DocsButtonIconSizes.vue] ``` :: ## Enhanced Buttons These are some buttons that I found today over here [Enhanced Buttons](https://enhanced-button.vercel.app/){rel="nofollow"}. I think they are cool. ### Expand Icon - Right ::show-case :::docs-button-expand-icon-right ::: #code ```vue [DocsButtonExpandIconRight.vue] ``` :: ### Expand Icon - Left ::show-case :::docs-button-expand-icon-left ::: #code ```vue [DocsButtonExpandIconLeft.vue] ``` :: ### Gooey - Left ::show-case :::docs-button-gooey-left ::: #code ```vue [DocsButtonGooeyLeft.vue] ``` :: ### Gooey - Right ::show-case :::docs-button-gooey-right ::: #code ```vue [DocsButtonGooeyRight.vue] ``` :: ### Shine ::show-case :::docs-button-shine ::: #code ```vue [DocsButtonShine.vue] ``` :: ### Shine on Hover ::show-case :::docs-button-shine-hover ::: #code ```vue [DocsButtonShineHover.vue] ``` :: ### Gradient Slideshow ::show-case :::docs-button-gradient-flow ::: #code ```vue [DocsButtonGradientFlow.vue] ``` :: ### Ring Hover ::show-case :::docs-button-ring-hover ::: #code ```vue [DocsButtonRingHover.vue] ``` :: ### Link Hover 1 ::show-case :::docs-button-link-hover1 ::: #code ```vue [DocsButtonLinkHover1.vue] ``` :: ### Link Hover 2 ::show-case :::docs-button-link-hover2 ::: #code ```vue [DocsButtonLinkHover2.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/buttons){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Animated Close Button ::show-case :::docs-button-animated-menu ::: #code ```vue [DocsButtonAnimatedMenu.vue] ``` :: ### Animated Rotate Plus ::show-case :::docs-button-rotate-plus ::: #code ```vue [DocsButtonRotatePlus.vue] ``` :: ### Group Outline Counter ::show-case :::docs-button-group-outline-counter ::: #code ```vue [DocsButtonGroupOutlineCounter.vue] ``` :: ### Volume Control ::show-case :::docs-button-volume ::: #code ```vue [DocsButtonVolume.vue] ``` :: ### Animated Copy ::show-case :::docs-button-animated-copy ::: #code ```vue [DocsButtonAnimatedCopy.vue] ``` :: ### Upload Button w/ Icon ::show-case :::docs-button-upload ::: #code ```vue [DocsButtonUpload.vue] ``` :: ### Arrows ::show-case :::docs-button-arrows ::: #code ```vue [DocsButtonArrows.vue] ``` :: # Button Group ## Source code Click :source-code-link{component="ButtonGroup"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add button-group"} :: ## Usage ### Basic ::show-case :::docs-button-group ::: #code ```vue [DocsButtonGroup.vue] ``` :: ### Orientation ::show-case :::docs-button-group-orientation ::: #code ```vue [DocsButtonGroupOrientation.vue] ``` :: ### Size ::show-case :::docs-button-group-size ::: #code ```vue [DocsButtonGroupSize.vue] ``` :: ### Nested ::show-case :::docs-button-group-nested ::: #code ```vue [DocsButtonGroupNested.vue] ``` :: ### Separator The `ButtonGroupSeparator` component visually divides buttons within a group. Buttons with variant `outline` do not need a separator since they have a border. For other variants, a separator is recommended to improve the visual hierarchy. ::show-case :::docs-button-group-separator ::: #code ```vue [DocsButtonGroupSeparator.vue] ``` :: ### Split ::show-case :::docs-button-group-split ::: #code ```vue [DocsButtonGroupSplit.vue] ``` :: ### Input ::show-case :::docs-button-group-input ::: #code ```vue [DocsButtonGroupInput.vue] ``` :: ### Input Group ::show-case :::docs-button-group-input-group ::: #code ```vue [DocsButtonGroupInputGroup.vue] ``` :: ### Dropdown ::show-case :::docs-button-group-dropdown ::: #code ```vue [DocsButtonGroupDropdown.vue] ``` :: ### Select ::show-case :::docs-button-group-select ::: #code ```vue [DocsButtonGroupSelect.vue] ``` :: ### Popover ::show-case :::docs-button-group-popover ::: #code ```vue [DocsButtonGroupPopover.vue] ``` :: # Calendar ## Source code Click :source-code-link{component="Calendar.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add calendar"} :: You can optionally configure the vcalendar module in your `nuxt.config.js` file: ```ts vcalendar: { calendarOptions: { masks: { weekdays: "WW", }, }, }, ``` ## Usage ### Attributes Attributes are visual decorators that can be applied to specific calendar dates. Learn more about them [here](https://vcalendar.io/calendar/attributes.html). ::show-case :::docs-calendar-attributes ::: #code ```vue [DocsCalendarAttributes.vue] ``` :: ### Right Title - Left Nav ::show-case :::docs-calendar-right-title ::: #code ```vue [DocsCalendarRightTitle.vue] ``` :: ### Header Slot ::show-case :::docs-calendar-header-slot ::: #code ```vue [DocsCalendarHeaderSlot.vue] ``` :: ### Date Range ::show-case :::docs-calendar-range ::: #code ```vue [DocsCalendarRange.vue] ``` :: ### Disabled Dates ::show-case :::docs-calendar-disabled-date ::: #code ```vue [DocsCalendarDisabledDate.vue] ``` :: ### Footer Slot ::show-case :::docs-calendar-footer-slot ::: #code ```vue [DocsCalendarFooterSlot.vue] ``` :: ### Week View ::show-case :::docs-calendar-week-view ::: #code ```vue [DocsCalendarWeekView.vue] ``` :: # Card ## Source code Click :source-code-link{component="Card"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add card"} :: ## Usage ::show-case :::docs-card ::: #code ```vue [DocsCard.vue] ``` :: ## Example ::show-case :::docs-card-example ::: #code ```vue [DocsCardExample.vue] ``` :: # Carousel ## Source code Click :source-code-link{component="Carousel"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## About The carousel component is built using the [Embla Carousel](https://www.embla-carousel.com/){rel="nofollow"} library. ## Installation ::prose-pm-x{command="ui-thing@latest add carousel"} :: ## Usage ```vue [DocsCarouselUsage.vue] ``` ## Examples ### Sizes To set the size of the items, you can use the `basis` utility class on the ``. ::show-case :::docs-carousel-sizes ::: #code ```vue [DocsCarouselSizes.vue] ``` :: Other Size Example ```html [DocsCarouselSizesExample.vue] ``` Responsive ```html [DocsCarouselSizesResponsive.vue] ``` ### Spacing To set the spacing between the items, we use a `pl-[VALUE]` utility on the `` and a negative `-ml-[VALUE]` on the ``. ::prose-callout{.my-6} **Why:** I tried to use the `gap` property or a `grid` layout on the `CarouselContent` but it required a lot of math and mental effort to get the spacing right. I found `pl-[VALUE]` and `-ml-[VALUE]` utilities much easier to use. :br:br You can always adjust this in your own project if you need to. :: ::show-case :::docs-carousel-spacing ::: #code ```vue [DocsCarouselSpacing.vue] ``` :: Other Spacing Example ```html [DocsCarouselSpacingExample.vue] ``` Responsive ```html [DocsCarouselSpacingResponsive.vue] ``` ### Orientation Use the `orientation` prop to set the orientation of the carousel. ::show-case :::docs-carousel-orientation ::: #code ```vue [DocsCarouselOrientation.vue] ``` :: ### Thumbnail ::show-case :::docs-carousel-thumbnail ::: #code ```vue [DocsCarouselThumbnail.vue] ``` :: ## Options You can pass options to the carousel using the `opts` prop. See the [Embla Carousel docs](https://www.embla-carousel.com/api/options/){rel="nofollow"} for more information. ```vue ``` ## API ### Method 1 Use the `@init-api` emit method on `` component to set the instance of the API. ::show-case :::docs-carousel-method1 ::: #code ```vue [DocsCarouselMethod1.vue] ``` :: ### Method 2 You can access it through setting a template ref on the `` component. ```vue ``` ## Events You can listen to events using the API. To get the API instance use the `@init-api` emit method on the `` component ```vue ``` See the [Embla Carousel docs](https://www.embla-carousel.com/api/events/){rel="nofollow"} for more information on using events. ## Slot Props You can get the reactive slot props like `carouselRef, canScrollNext..Prev, scrollNext..Prev` using the `v-slot` directive in the `` component to extend the functionality. ```vue ``` ## Plugins You can use the `plugins` prop to add plugins to the carousel. ```bash npm i embla-carousel-autoplay ``` ```vue ``` ::show-case :::docs-carousel-plugin ::: #code ```vue [DocsCarouselPlugin.vue] ``` :: See the [Embla Carousel docs](https://www.embla-carousel.com/api/plugins/){rel="nofollow"} for more information on using plugins. # Checkbox ## Source code Click :source-code-link{component="Checkbox"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add checkbox"} :: ## Usage ### Basic ::show-case :::docs-checkbox ::: #code ```vue [DocsCheckbox.vue] ``` :: ### Default ::show-case :::docs-checkbox-default-values ::: #code ```vue [DocsCheckboxDefaultValues.vue] ``` :: ### Shadcn ::show-case :::docs-checkbox-shadcn ::: #code ```vue [DocsCheckboxShadcn.vue] ``` :: ## Origin UI ### Simple ::show-case :::docs-checkbox-origin-simple ::: #code ```vue [DocsCheckboxOriginSimple.vue] ``` :: ### Indeterminate ::show-case :::docs-checkbox-origin-indeterminate ::: #code ```vue [DocsCheckboxOriginIndeterminate.vue] ``` :: ### Colored ::show-case :::docs-checkbox-origin-colored ::: #code ```vue [DocsCheckboxOriginColored.vue] ``` :: ### Disabled ::show-case :::docs-checkbox-origin-disabled ::: #code ```vue [DocsCheckboxOriginDisabled.vue] ``` :: ### Line Through ::show-case :::docs-checkbox-origin-line-through ::: #code ```vue [DocsCheckboxOriginLineThrough.vue] ``` :: ### Fancy Todo ::show-case :::docs-checkbox-origin-fancy-todo ::: #code ```vue [DocsCheckboxOriginFancyTodo.vue] ``` :: ### Frameworks (Group Checkbox) ::show-case :::docs-checkbox-origin-group-frameworks ::: #code ```vue [DocsCheckboxOriginGroupFrameworks.vue] ``` :: ### Frameworks (Group Checkbox - Vertical) ::show-case :::docs-checkbox-origin-group-vertical ::: #code ```vue [DocsCheckboxOriginGroupVertical.vue] ``` :: ### Checkbox with Description ::show-case :::docs-checkbox-origin-description ::: #code ```vue [DocsCheckboxOriginDescription.vue] ``` :: ### Selections ::show-case :::docs-checkbox-origin-options ::: #code ```vue [DocsCheckboxOriginOptions.vue] ``` :: # Chip ## Source code Click :source-code-link{component="Chip.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add chip"} :: ## Usage ### Basic ::show-case :::docs-chip ::: #code ```vue [DocsChip.vue] ``` :: ### Size Pass a size to the `size` prop to change the size of the chip. ::show-case :::docs-chip-size ::: #code ```vue [DocsChipSize.vue] ``` :: ### Color You can change the color of the chip by passing any tailwind color `bg` class to the `color` prop. ::show-case :::docs-chip-color ::: #code ```vue [DocsChipColor.vue] ``` :: ### Text You can display a text inside the chip by passing a `string` to the `text` prop. ::show-case :::docs-chip-text ::: #code ```vue [DocsChipText.vue] ``` :: ### Inset The `inset` prop can be used to move the indicator closer to the element. ::show-case :::docs-chip-inset ::: #code ```vue [DocsChipInset.vue] ``` :: # Collapsible ## Source code Click :source-code-link{component="Collapsible"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add collapsible"} :: ## Usage ::show-case :::docs-collapsible ::: #code ```vue [DocsCollapsible.vue] ``` :: # Combobox ## Installation The Combobox is built using a composition of the `` and the `` components. See installation instructions for the [Popover](https://uithing.com/components/popover) and the [Command](https://uithing.com/components/command) components. ## Usage ```vue ``` ### Combobox ::show-case :::docs-combobox ::: #code ```vue [DocsCombobox.vue] ``` :: ### Origin UI ::show-case :::docs-combobox-origin ::: #code ```vue [DocsComboboxOrigin.vue] ``` :: # Command ## Source code Click :source-code-link{component="Command"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add command"} :: ## Usage ### Basic ::show-case :::docs-command ::: #code ```vue [DocsCommand.vue] ``` :: ### Dialog ::show-case :::docs-command-shortcut ::: #code ```vue [DocsCommandShortcut.vue] ``` :: ### Popover ::show-case :::docs-command-popover ::: #code ```vue [DocsCommandPopover.vue] ``` :: ### Dropdown Menu ::show-case :::docs-command-dropdown ::: #code ```vue [DocsCommandDropdown.vue] ``` :: ### Responsive You can create a responsive combobox by using the `` on desktop and the `` components on mobile. ::show-case :::docs-command-responsive ::: #code ```vue [DocsCommandResponsive.vue] ``` :: # Container ## Source code Click :source-code-link{component="Container.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add container"} :: ## Usage ### Basic ::show-case :::docs-container ::: #code ```vue [DocsContainer.vue] ``` :: # Context Menu ## Source code Click :source-code-link{component="ContextMenu"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add context-menu"} :: ## Usage ### Basic ::show-case :::docs-context-menu-basic ::: #code ```vue [DocsContextMenuBasic.vue] ``` :: ### Checkbox Items ::show-case :::docs-context-menu-check-items ::: #code ```vue [DocsContextMenuCheckItems.vue] ``` :: ### Radio Items ::show-case :::docs-context-menu-radio-items ::: #code ```vue [DocsContextMenuRadioItems.vue] ``` :: # Currency Input ## Source code Click :source-code-link{component="CurrencyInput.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add currency-input"} :: Adding this component will also install the `vue-currency-input` package. ## Usage ### Default Configuration The default configuration for the currency input component is as follows: ```json { "currency": "USD", "locale": "en-US", "hideCurrencySymbolOnFocus": false, "hideGroupingSeparatorOnFocus": false } ``` ### Basic ::show-case :::docs-currency-input-basic ::: #code ```vue [DocsCurrencyInputBasic.vue] ``` :: ### Options You can change the configuration by passing the `options` prop. ::show-case :::docs-currency-input-options ::: #code ```vue [DocsCurrencyInputOptions.vue] ``` :: ### Form ::show-case :::docs-currency-input-form ::: #code ```vue [DocsCurrencyInputForm.vue] ``` :: # DataTable ## Source code Click :source-code-link{component="Datatable.client.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add datatable"} :: ## Usage ### Dom Take note of how the [`dom`](https://datatables.net/reference/option/dom){rel="nofollow"} option is configured in the code. We use it to structure the layout of the table. ::show-case :::docs-datatable-basic ::: #code ```vue [DocsDatatableBasic.vue] ``` :: ### Custom component With the new version of DataTables.net, you can now use custom Vue components in your table. ::show-case :::docs-datatable-component ::: #code ```vue [DocsDatatableComponent.vue] ``` :: ### Layout The new version of DataTables.net also allows you to use custom layouts for your table. You can read more about it [here](https://datatables.net/reference/option/layout){rel="nofollow"} For this, you will actually need to add some custom classes for things to look how you want. ::show-case :::docs-datatable-layout ::: #code ```vue [DocsDatatableLayout.vue] ``` :: ### Simple ::show-case :::docs-datatable-simple ::: #code ```vue [DocsDatatableSimple.vue] ``` :: ### Image ::show-case :::docs-datatable-images ::: #code ```vue [DocsDatatableImages.vue] ``` :: ### No Horizontal ::show-case :::docs-datatable-no-horizontal ::: #code ```vue [DocsDatatableNoHorizontal.vue] ``` :: ### Striped ::show-case :::docs-datatable-striped ::: #code ```vue [DocsDatatableStriped.vue] ``` :: ### Vertical Lines ::show-case :::docs-datatable-vertical-lines ::: #code ```vue [DocsDatatableVerticalLines.vue] ``` :: ### Dense ::show-case :::docs-datatable-dense ::: #code ```vue [DocsDatatableDense.vue] ``` :: ### Row Selection ::show-case :::docs-datatable-row-selection ::: #code ```vue [DocsDatatableRowSelection.vue] ``` :: ### Card ::show-case :::docs-datatable-card ::: #code ```vue [DocsDatatableCard.vue] ``` :: ### Scroll with Sticky Header ::show-case :::docs-datatable-scroll-y ::: #code ```vue [DocsDatatableScrollY.vue] ``` :: ### Badge & Icons ::show-case :::docs-datatable-badge ::: #code ```vue [DocsDatatableBadge.vue] ``` :: ### Search & Sort ::show-case :::docs-datatable-search-sort ::: #code ```vue [DocsDatatableSearchSort.vue] ``` :: ### Fixed Columns ::show-case :::docs-datatable-fixed-column ::: #code ```vue [DocsDatatableFixedColumn.vue] ``` :: ### Column ReOrder This requires the `fixedColumns` plugin to be installed. ```bash npm install --save datatables.net-colreorder-dt ``` Then add the following to your `datatables` plugin file ```ts import "datatables.net-colreorder-dt"; import "datatables.net-colreorder-dt/css/colReorder.dataTables.css"; ``` ::show-case :::docs-datatable-column-re-order ::: #code ```vue [DocsDatatableColumnReOrder.vue] ``` :: ### Pagination ::show-case :::docs-datatable-pagination ::: #code ```vue [DocsDatatablePagination.vue] ``` :: # Date Field ## Source code Click :source-code-link{component="DateField.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add date-field"} :: ## Usage ::show-case :::docs-date-field ::: #code ```vue [DocsDateField.vue] ``` :: # Datepicker ## Source code Click :source-code-link{component="Datepicker.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add datepicker"} :: You can optionally configure the vcalendar module in your `nuxt.config.js` file: ```ts vcalendar: { calendarOptions: { masks: { weekdays: "WW", }, }, }, ``` ## Usage ### Datetime Mode ::show-case :::docs-datepicker-mode ::: #code ```vue [DocsDatepickerMode.vue] ``` :: ### Custom Title ::show-case :::docs-datepicker-title ::: #code ```vue [DocsDatepickerTitle.vue] ``` :: ### Button Slot ::show-case :::docs-datepicker-button ::: #code ```vue [DocsDatepickerButton.vue] ``` :: ### Input Slot ::show-case :::docs-datepicker-input ::: #code ```vue [DocsDatepickerInput.vue] ``` :: ### Responsive Layout One a mobile screen, the `Datepicker` will expand to full width and display only one column. On larger screens, it will display two columns. ::show-case :::docs-datepicker-responsive ::: #code ```vue [DocsDatepickerResponsive.vue] ``` :: ### Time Rules Limit the time selection by setting [Time Rules](https://vcalendar.io/datepicker/time-rules.html){rel="nofollow"} on the `Datepicker`. Here the user can set an appointment between 9 AM and 5 PM, with a 30-minute interval. Weekends are disabled. ::show-case :::docs-datepicker-time-rules ::: #code ```vue [DocsDatepickerTimeRules.vue] ``` :: ### Presets ::show-case :::docs-datepicker-presets ::: #code ```vue [DocsDatepickerPresets.vue] ``` :: ### Custom Day Content ::show-case :::docs-datepicker-custom-day-content ::: #code ```vue [DocsDatepickerCustomDayContent.vue] ``` :: # Description List ## Source code Click :source-code-link{component="Description"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add description-list"} :: ## Usage ### Basic ::show-case :::docs-description-list-basic ::: #code ```vue [DocsDescriptionListBasic.vue] ``` :: ### With Card ::show-case :::docs-description-list-card ::: #code ```vue [DocsDescriptionListCard.vue] ``` :: # Dialog ## Source code Click :source-code-link{component="Dialog"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add dialog"} :: ## Usage ### Profile Dialog ::show-case :::docs-dialog ::: #code ```vue [DocsDialog.vue] ``` :: ### Custom Close Button ::show-case :::docs-dialog-custom-close ::: #code ```vue [DocsDialogCustomClose.vue] ``` :: ## Origin UI Dialogs Here are some of the dialog examples from the [Origin UI](https://originui.com){rel="nofollow"} documentation. Hats off to the Origin UI team ❤️. I just made them work with my setup. ### Scrollable (native scrollbar) ::show-case :::docs-dialog-scroll-native ::: #code ```vue [DocsDialogScrollNative.vue] ``` :: ### Scrollable (custom scrollbar) ::show-case :::docs-dialog-scroll-custom ::: #code ```vue [DocsDialogScrollCustom.vue] ``` :: ### Scrollable (sticky header) ::show-case :::docs-dialog-scroll-sticky-header ::: #code ```vue [DocsDialogScrollStickyHeader.vue] ``` :: ### Scrollable (sticky footer) ::show-case :::docs-dialog-scroll-sticky-footer ::: #code ```vue [DocsDialogScrollStickyFooter.vue] ``` :: ### Terms & Condition ::show-case :::docs-dialog-terms-condition ::: #code ```vue [DocsDialogTermsCondition.vue] ``` :: ### Newsletter ::show-case :::docs-dialog-newsletter ::: #code ```vue [DocsDialogNewsletter.vue] ``` :: ### Feedback ::show-case :::docs-dialog-feedback ::: #code ```vue [DocsDialogFeedback.vue] ``` :: ### Rating ::show-case :::docs-dialog-rating ::: #code ```vue [DocsDialogRating.vue] ``` :: ### OTP Code ::show-case :::docs-dialog-otp-code ::: #code ```vue [DocsDialogOtpCode.vue] ``` :: ### Sign Up ::show-case :::docs-dialog-sign-up ::: #code ```vue [DocsDialogSignUp.vue] ``` :: ### Sign In ::show-case :::docs-dialog-sign-in ::: #code ```vue [DocsDialogSignIn.vue] ``` :: ### Invite Members ::show-case :::docs-dialog-invite-members ::: #code ```vue [DocsDialogInviteMembers.vue] ``` :: ### Card Details This implementation requires the use of [Maska](https://beholdr.github.io/maska/v3/#/install){rel="nofollow"} ::show-case :::docs-dialog-card-details ::: #code ```vue [DocsDialogCardDetails.vue] ``` :: ### Checkout This implementation requires the use of [Maska](https://beholdr.github.io/maska/v3/#/install){rel="nofollow"} ::show-case :::docs-dialog-checkout ::: #code ```vue [DocsDialogCheckout.vue] ``` :: ### Change Plan ::show-case :::docs-dialog-change-plan ::: #code ```vue [DocsDialogChangePlan.vue] ``` :: ### Edit Profile ::show-case :::docs-dialog-edit-profile ::: #code ```vue [DocsDialogEditProfile.vue] ``` :: ### Onboarding ::show-case :::docs-dialog-onboarding ::: #code ```vue [DocsDialogOnboarding.vue] ``` :: ### Command Pallette Search ::show-case :::docs-dialog-search ::: #code ```vue [DocsDialogSearch.vue] ``` :: # Divider ## Source code Click :source-code-link{component="Divider.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add divider"} :: ## Usage ### Basic ::show-case :::docs-divider ::: #code ```vue [DocsDivider.vue] ``` :: ### Label ::show-case :::docs-divider-label ::: #code ```vue [DocsDividerLabel.vue] ``` :: ### Icon ::show-case :::docs-divider-icon ::: #code ```vue [DocsDividerIcon.vue] ``` :: ### Avatar ::show-case :::docs-divider-avatar ::: #code ```vue [DocsDividerAvatar.vue] ``` :: ### Vertical ::show-case :::docs-divider-vertical ::: #code ```vue [DocsDividerVertical.vue] ``` :: # Draggable ## Source code Click :source-code-link{component="Draggable.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add draggable"} :: ## Usage ### Simple ::show-case :::docs-draggable-simple ::: #code ```vue [DocsDraggableSimple.vue] ``` :: ### Two Lists ::show-case :::docs-draggable-two-lists ::: #code ```vue [DocsDraggableTwoLists.vue] ``` :: ### Clone ::show-case :::docs-draggable-clone ::: #code ```vue [DocsDraggableClone.vue] ``` :: ### Custom Clone ::show-case :::docs-draggable-custom-clone ::: #code ```vue [DocsDraggableCustomClone.vue] ``` :: ### Clone on `Meta` key Press the `Meta` key (Command on Mac, Windows key on Windows) while dragging to clone an item. ::show-case :::docs-draggable-clone-on-meta ::: #code ```vue [DocsDraggableCloneOnMeta.vue] ``` :: ### Handle ::show-case :::docs-draggable-handle ::: #code ```vue [DocsDraggableHandle.vue] ``` :: ### Table ::show-case :::docs-draggable-table ::: #code ```vue [DocsDraggableTable.vue] ``` :: ### Slots ::show-case :::docs-draggable-slots ::: #code ```vue [DocsDraggableSlots.vue] ``` :: ### Nested ::show-case :::docs-draggable-nested ::: #code ```vue [DocsDraggableNested.vue] ``` :: # Drawer ## Source code Click :source-code-link{component="Drawer"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add drawer"} :: ## Usage ### Basic Form We can bring the different components together to make a simple drawer. ::show-case :::docs-drawer-basic ::: #code ```vue [DocsDrawerBasic.vue] ``` :: ### With Image We can add an image inside as well. ::show-case :::docs-drawer-image ::: #code ```vue [DocsDrawerImage.vue] ``` :: ### Responsive Dialog You can combine the `Dialog` and `Drawer` components to create a responsive dialog. This renders a `Dialog` component on desktop and a `Drawer` on mobile. ::show-case :::docs-drawer-responsive-dialog ::: #code ```vue [DocsDrawerResponsiveDialog.vue] ``` :: # Dropdown Menu ## Source code Click :source-code-link{component="DropdownMenu"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add dropdown-menu"} :: ## Usage ### Menu Items w/ Submenu ::show-case :::docs-dropdown-menu-basic ::: #code ```vue [DocsDropdownMenuBasic.vue] ``` :: ### Checkbox Menu Items ::show-case :::docs-dropdown-menu-check-items ::: #code ```vue [DocsDropdownMenuCheckItems.vue] ``` :: ### Radio Menu Items ::show-case :::docs-dropdown-menu-radio-items ::: #code ```vue [DocsDropdownMenuRadioItems.vue] ``` :: ### Origin UI Examples ::show-case :::docs-dropdown-menu-origin-u-i ::: #code ```vue [DocsDropdownMenuOriginUI.vue] ``` :: # Dropfile ## Source code Click :source-code-link{component="Dropfile.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add dropfile"} :: ## Usage ### Placeholder ::show-case :::docs-dropfile ::: #code ```vue [DocsDropfile.vue] ``` :: # Editable ## Source code Click :source-code-link{component="Editable"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add editable"} :: ## Usage The `Editable` component is one that will be used differently in different parts of your app. Since we already have styled buttons and inputs, it kinda makes no sense to force a specific style on the `Editable` component when we can just use the `asChild` prop to pass in the children we want to use. ::show-case :::docs-editable ::: #code ```vue [DocsEditable.vue] ``` :: # Empty ## Source code Click :source-code-link{component="Empty"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add empty"} :: ## Usage ```vue ``` ## Examples ### Basic ::show-case :::docs-empty ::: #code ```vue [DocsEmpty.vue] ``` :: ### Outline ::show-case :::docs-empty-outline ::: #code ```vue [DocsEmptyOutline.vue] ``` :: ### Background ::show-case :::docs-empty-background ::: #code ```vue [DocsEmptyBackground.vue] ``` :: ### Avatar ::show-case :::docs-empty-avatar ::: #code ```vue [DocsEmptyAvatar.vue] ``` :: ### Avatar Group ::show-case :::docs-empty-avatar-group ::: #code ```vue [DocsEmptyAvatarGroup.vue] ``` :: ### Input Group ::show-case :::docs-empty-input-group ::: #code ```vue [DocsEmptyInputGroup.vue] ``` :: # Fancy Icon ## Source code Click :source-code-link{component="FancyIcon"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add fancy-icon"} :: ## Usage ### Basic ::show-case :::docs-fancy-icon ::: #code ```vue [DocsFancyIcon.vue] ``` :: ### Colors For the colors to show, you have to change the type from `modern`. ::show-case :::docs-fancy-icon-color ::: #code ```vue [DocsFancyIconColor.vue] ``` :: ### Types ::show-case :::docs-fancy-icon-type ::: #code ```vue [DocsFancyIconType.vue] ``` :: ### Sizes ::show-case :::docs-fancy-icon-size ::: #code ```vue [DocsFancyIconSize.vue] ``` :: ### Circle prop ::show-case :::docs-fancy-icon-circle ::: #code ```vue [DocsFancyIconCircle.vue] ``` :: # Field ## Source code Click :source-code-link{component="Field"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add field"} :: ## Usage ```vue ``` ## Anatomy The `Field` family is designed for composing accessible forms. A typical field is structured as follows: ```vue ``` - `Field` is the core wrapper for a single field. - `FieldContent` is a flex column that groups label and description. Not required if you have no description. - Wrap related fields with `FieldGroup`, and use `FieldSet` with `FieldLegend` for semantic grouping. ## Examples ### Basic ::show-case :::docs-field-basic ::: #code ```vue [DocsFieldBasic.vue] ``` :: ### Input ::show-case :::docs-field-input ::: #code ```vue [DocsFieldInput.vue] ``` :: ### Textarea ::show-case :::docs-field-textarea ::: #code ```vue [DocsFieldTextarea.vue] ``` :: ### Select ::show-case :::docs-field-select ::: #code ```vue [DocsFieldSelect.vue] ``` :: ### Slider ::show-case :::docs-field-slider ::: #code ```vue [DocsFieldSlider.vue] ``` :: ### FieldSet ::show-case :::docs-field-field-set ::: #code ```vue [DocsFieldFieldSet.vue] ``` :: ### Checkbox ::show-case :::docs-field-checkbox ::: #code ```vue [DocsFieldCheckbox.vue] ``` :: ### Radio ::show-case :::docs-field-radio ::: #code ```vue [DocsFieldRadio.vue] ``` :: ### Switch ::show-case :::docs-field-switch ::: #code ```vue [DocsFieldSwitch.vue] ``` :: ## Notion Prompt ::show-case :::docs-field-notion-prompt ::: #code ```vue [DocsFieldNotionPrompt.vue] ``` :: ### How did you hear about us? ::show-case :::docs-field-hear ::: #code ```vue [DocsFieldHear.vue] ``` :: ### Choice Card Wrap `Field` components inside `FieldLabel` to create selectable field groups. This works with `RadioItem`, `Checkbox` and `Switch` components. ::show-case :::docs-field-choice-card ::: #code ```vue [DocsFieldChoiceCard.vue] ``` :: ### Field Group Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them. ::show-case :::docs-field-field-group ::: #code ```vue [DocsFieldFieldGroup.vue] ``` :: ### Responsive Layout - **Vertical fields:** Default orientation stacks label, control, and helper text—ideal for mobile-first layouts. - **Horizontal fields:** Set `orientation="horizontal"` on `Field` to align the label and control side-by-side. Pair with `FieldContent` to keep descriptions aligned. - **Responsive fields:** Set `orientation="responsive"` for automatic column layouts inside container-aware parents. Apply `@container/field-group` classes on `FieldGroup` to switch orientations at specific breakpoints. ::show-case :::docs-field-responsive-layout ::: #code ```vue [DocsFieldResponsiveLayout.vue] ``` :: ## Validation and Errors - Add `data-invalid` to `Field` to switch the entire block into an error state. - Add `aria-invalid` on the input itself for assistive technologies. - Render `FieldError` immediately after the control or inside `FieldContent` to keep error messages aligned with the field. ```vue ``` ## Accessibility - `FieldSet` and `FieldLegend` keep related controls grouped for keyboard and assistive tech users. - `Field` outputs `role="group"` so nested controls inherit labeling from `FieldLabel` and `FieldLegend` when combined. - Apply `FieldSeparator` sparingly to ensure screen readers encounter clear section boundaries. # Form Forms are tricky. They are one of the most common things you'll build in a web application, but also one of the most complex. Well-designed HTML forms are: - Well-structured and semantically correct. - Easy to use and navigate (keyboard). - Accessible with ARIA attributes and proper labels. - Has support for client and server side validation. - Well-styled and consistent with the rest of the application. In this guide, we will take a look at building forms with :prose-a[vee-validate]{href="https://vee-validate.logaretm.com/v4/" target="\_blank"} and :prose-a[zod]{href="https://zod.dev/" target="\_blank"}. We're going to use a `` component to compose accessible forms using Radix Vue components. ## Features The `
` component is a wrapper around the `vee-validate` library. It provides a few things: - Composable components for building forms. - A `` component for building controlled form fields. - Form validation using `zod`. - Applies the correct `aria` attributes to form fields based on states, handle unqiue IDs - Built to work with all Radix Vue components. - Bring your own schema library. We use `zod` but you can use any other supported schema validation you want, like `yup` or `valibot`. - You have full control over the markup and styling. :prose-a[vee-validate]{href="https://vee-validate.logaretm.com/v4/" target="\_blank"} makes use of two flavors to add validation to your forms. - Composition API - Higher-order components (HOC) ## Anatomy ```html ``` The `` component is auto-imported by the `@vee-validate/nuxt` module. You can change the name of the impported components in your `nuxt.config .ts` file. You can visit :prose-a[here]{href="https://vee-validate.logaretm.com/v4/integrations/nuxt/" target="\_blank"} for more information. ## Source code Click :source-code-link{component="Form"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add form"} :: ## Usage ### User profile form ::show-case :::docs-form-user ::: #code ```vue [DocsFormUser.vue] ``` :: # Gradient Divider ## Source code Click :source-code-link{component="GradientDivider.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add gradient-divider"} :: ## Usage ::show-case :::docs-gradient-divider ::: #code ```vue [DocsGradientDivider.vue] ``` :: # Heading ## Source code Click :source-code-link{component="Heading.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add heading"} :: ## Usage ### Basic example ::show-case :::docs-heading-basic ::: #code ```vue [DocsHeadingBasic.vue] ``` :: # Hover Card ## Source code Click :source-code-link{component="HoverCard"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add hover-card"} :: ## Usage ### Basic ::show-case :::docs-hover-card ::: #code ```vue [DocsHoverCard.vue] ``` :: ### Vue ::show-case :::docs-hover-card-vue ::: #code ```vue [DocsHoverCardVue.vue] ``` :: # Input ## Source code Click :source-code-link{component="Input.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add input"} :: ## Usage ### Email ::show-case :::docs-input-email ::: #code ```vue [DocsInputEmail.vue] ``` :: ### Disabled ::show-case :::docs-input-disabled ::: #code ```vue [DocsInputDisabled.vue] ``` :: ### Label ::show-case :::docs-input-label ::: #code ```vue [DocsInputLabel.vue] ``` :: ### Form ::show-case :::docs-input-form ::: #code ```vue [DocsInputForm.vue] ``` :: ### Max Length Restrict the number of characters that can be entered into the input field. ::show-case :::docs-input-max-length ::: #code ```vue [DocsInputMaxLength.vue] ``` :: ### Pattern Restrict the type of characters that can be entered into the input field. You don't need to use `/` at the beginning and end of the pattern as the RegExp is being created internally with the `new RegExp()` constructor. ::show-case :::docs-input-pattern ::: #code ```vue [DocsInputPattern.vue] ``` :: # Input Group ## Source code Click :source-code-link{component="InputGroup"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add input-group"} :: ## Usage ### Basic ::show-case :::docs-input-group ::: #code ```vue [DocsInputGroup.vue] ``` :: ### Icon ::show-case :::docs-input-group-icon ::: #code ```vue [DocsInputGroupIcon.vue] ``` :: ### Text ::show-case :::docs-input-group-text ::: #code ```vue [DocsInputGroupText.vue] ``` :: ### Button ::show-case :::docs-input-group-button ::: #code ```vue [DocsInputGroupButton.vue] ``` :: ### Tooltip ::show-case :::docs-input-group-tooltip ::: #code ```vue [DocsInputGroupTooltip.vue] ``` :: ### Textarea ::show-case :::docs-input-group-textarea ::: #code ```vue [DocsInputGroupTextarea.vue] ``` :: ### Loader ::show-case :::docs-input-group-loader ::: #code ```vue [DocsInputGroupLoader.vue] ``` :: ### Label ::show-case :::docs-input-group-label ::: #code ```vue [DocsInputGroupLabel.vue] ``` :: ### Dropdown ::show-case :::docs-input-group-dropdown ::: #code ```vue [DocsInputGroupDropdown.vue] ``` :: # Item The `Item` component is a straightforward flex container that can house nearly any type of content. Use it to display a title, description, and actions. Group it with the `ItemGroup` component to create a list of items. ## Source code Click :source-code-link{component="Item"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add item"} :: ## Usage ```vue ``` ## Item vs Field Use `Field` if you need to display a form input such as a checkbox, input, radio, or select. If you only need to display content such as a title, description, and actions, use `Item`. ## Examples ### Basic ::show-case :::docs-item ::: #code ```vue [DocsItem.vue] ``` :: ### Variants ::show-case :::docs-item-variants ::: #code ```vue [DocsItemVariants.vue] ``` :: ### Size The `Item` component has different sizes for different use cases. For example, you can use the `sm` size for a compact item or the `default` size for a standard item. ::show-case :::docs-item-size ::: #code ```vue [DocsItemSize.vue] ``` :: ### Icon ::show-case :::docs-item-icon ::: #code ```vue [DocsItemIcon.vue] ``` :: ### Avatar ::show-case :::docs-item-avatar ::: #code ```vue [DocsItemAvatar.vue] ``` :: ### Image ::show-case :::docs-item-image ::: #code ```vue [DocsItemImage.vue] ``` :: ### Group ::show-case :::docs-item-group ::: #code ```vue [DocsItemGroup.vue] ``` :: ### Header ::show-case :::docs-item-header ::: #code ```vue [DocsItemHeader.vue] ``` :: ### Link To render an item as a link, use the `as-child` prop. The hover and focus states will be applied to the anchor element. ::show-case :::docs-item-link ::: #code ```vue [DocsItemLink.vue] ``` :: ### Dropdown ::show-case :::docs-item-dropdown ::: #code ```vue [DocsItemDropdown.vue] ``` :: # Keyboard Key ## Source code Click :source-code-link{component="Kbd.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add kbd"} :: ## Usage ```vue ``` ## Examples ### Basic ::show-case :::docs-kbd ::: #code ```vue [DocsKbd.vue] ``` :: ### Group Use the `KbdGroup` component to group keyboard keys together. ::show-case :::docs-kbd-group ::: #code ```vue [DocsKbdGroup.vue] ``` :: ### Button Use the `Kbd` component inside a `Button` component to display a keyboard key inside a button. ::show-case :::docs-kbd-button ::: #code ```vue [DocsKbdButton.vue] ``` :: ### Tooltip You can use the `Kbd` component inside a `Tooltip` component to display a tooltip with a keyboard key. ::show-case :::docs-kbd-tooltip ::: #code ```vue [DocsKbdTooltip.vue] ``` :: ### Input Group You can use the `Kbd` component inside a `InputGroupAddon` component to display a keyboard key inside an input group. ::show-case :::docs-kbd-input-group ::: #code ```vue [DocsKbdInputGroup.vue] ``` :: ### Sizes ::show-case :::docs-kbd-sizes ::: #code ```vue [DocsKbdSizes.vue] ``` :: ### Variants ::show-case :::docs-kbd-variants ::: #code ```vue [DocsKbdVariants.vue] ``` :: # Label ## Source code Click :source-code-link{component="Label.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add label"} :: ## Usage ### Input ::show-case :::docs-input-label ::: #code ```vue [DocsInputLabel.vue] ``` :: # List ## Source code Click :source-code-link{component="List"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add list"} :: ## Usage ### Basic ::show-case :::docs-list-basic ::: #code ```vue [DocsListBasic.vue] ``` :: ### Mini cart ::show-case :::docs-list-products ::: #code ```vue [DocsListProducts.vue] ``` :: ### Navigation list ::show-case :::docs-list-nav ::: #code ```vue [DocsListNav.vue] ``` :: # Listbox ## Source code Click :source-code-link{component="Listbox"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add listbox"} :: ## Usage ### Basic ::show-case :::docs-listbox-basic ::: #code ```vue [DocsListboxBasic.vue] ``` :: ### Objects ::show-case :::docs-listbox-objects ::: #code ```vue [DocsListboxObjects.vue] ``` :: ### Multiple - Strings ::show-case :::docs-listbox-string-multiple ::: #code ```vue [DocsListboxStringMultiple.vue] ``` :: ### Multiple - Objects ::show-case :::docs-listbox-objects-multiple ::: #code ```vue [DocsListboxObjectsMultiple.vue] ``` :: ### Virtualizer - Strings ::show-case :::docs-listbox-string-virtualizer ::: #code ```vue [DocsListboxStringVirtualizer.vue] ``` :: ### Origin UI ::show-case :::docs-listbox-origin ::: #code ```vue [DocsListboxOrigin.vue] ``` :: ### Transfer ::show-case :::docs-listbox-transfer ::: #code ```vue [DocsListboxTransfer.vue] ``` :: # Loader ## Source code Click :source-code-link{component="Loader.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add loader"} :: ## Usage ### Basic ::show-case :::docs-loader-basic ::: #code ```vue [DocsLoaderBasic.vue] ``` :: ### Variants So you can use any of the loaders located on the [Iconify Website](https://icones.js.org/collection/svg-spinners){rel="nofollow"}. Simply copy the name of the loader and paste it into the `icon` prop. ::show-case :::docs-loader-variants ::: #code ```vue [DocsLoaderVariants.vue] ``` :: ### Sizes You can adjust the size of the loader by passing a CSS class to the `class` prop. ::show-case :::docs-loader-sizes ::: #code ```vue [DocsLoaderSizes.vue] ``` :: ### Colors You can adjust the color of the loader by passing a CSS class to the `class` prop. ::show-case :::docs-loader-colors ::: #code ```vue [DocsLoaderColors.vue] ``` :: ### Full Page Loader The loader can operate as a full page loader by passing the `full-page` prop. When the `full-page` prop is passed, the loader will take up the entire screen. It can be closed manually or by pressing the `esc` key. ::show-case :::docs-loader-backdrop ::: #code ```vue [DocsLoaderBackdrop.vue] ``` :: # Menubar ## Source code Click :source-code-link{component="Menubar"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add menubar"} :: ## Usage ### Full example ::show-case :::docs-menubar ::: #code ```vue [DocsMenubar.vue] ``` :: # Nav ## Credits This component is a port of the one created by [Intent UI](https://intentui.com/docs/components/layouts/navbar){rel="nofollow"}. Thanks to them for their work! ## Source code Click :source-code-link{component="Nav"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add nav"} :: ## Usage ### Default ::show-case :::docs-nav1 ::: #code ```vue [DocsNav1.vue] ``` :: ### Inset ::show-case :::docs-nav-inset ::: #code ```vue [DocsNavInset.vue] ``` :: ### Floating ::show-case :::docs-nav-floating ::: #code ```vue [DocsNavFloating.vue] ``` :: # Navbar ## Source code Click :source-code-link{component="Navbar.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add navbar"} :: ## Usage ### Basic ::show-case :::docs-navbar ::: #code ```vue [DocsNavbar.vue] ``` :: ## Origin UI ### One ::show-case :::docs-origin-navbar1 ::: #code ```vue [DocsOriginNavbar1.vue] ``` :: ### Two ::show-case :::docs-origin-navbar2 ::: #code ```vue [DocsOriginNavbar2.vue] ``` :: ### Three ::show-case :::docs-origin-navbar3 ::: #code ```vue [DocsOriginNavbar3.vue] ``` :: # Navigation Menu ## Source code Click :source-code-link{component="NavigationMenu"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add navigation-menu"} :: ## Anatomy ```vue ``` ## Usage ### Horizontal Navigation Menu The default orientation of the Navigation Menu is horizontal. ::show-case :::docs-navigation-menu ::: #code ```vue [DocsNavigationMenu.vue] ``` :: ### Shadcn UI The default orientation of the Navigation Menu is horizontal. ::show-case :::docs-navigation-menu-shadcn ::: #code ```vue [DocsNavigationMenuShadcn.vue] ``` :: # Number Field ## Source code Click :source-code-link{component="NumberField"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add number-field"} :: ## Usage ### Basic ::show-case :::docs-number-field ::: #code ```vue [DocsNumberField.vue] ``` :: ### Disabled ::show-case :::docs-number-field-disabled ::: #code ```vue [DocsNumberFieldDisabled.vue] ``` :: ### Decimal ::show-case :::docs-number-field-decimal ::: #code ```vue [DocsNumberFieldDecimal.vue] ``` :: ### Percent ::show-case :::docs-number-field-percent ::: #code ```vue [DocsNumberFieldPercent.vue] ``` :: ### Currency ::show-case :::docs-number-field-currency ::: #code ```vue [DocsNumberFieldCurrency.vue] ``` :: ### Custom ::show-case :::docs-number-field-custom ::: #code ```vue [DocsNumberFieldCustom.vue] ``` :: # Pagination ## Source code Click :source-code-link{component="Pagination"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add pagination"} :: ## Anatomy ```vue ``` ## Usage ### Full example ::show-case :::docs-pagination ::: #code ```vue [DocsPagination.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/breadcrumbs-paginations){rel="nofollow"} ❤️. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Apart ::show-case :::docs-pagination-apart ::: #code ```vue [DocsPaginationApart.vue] ``` :: ### Info Center ::show-case :::docs-pagination-info-center ::: #code ```vue [DocsPaginationInfoCenter.vue] ``` :: ### Info Start & End ::show-case :::docs-pagination-info-start-end ::: #code ```vue [DocsPaginationInfoStartEnd.vue] ``` :: ### Bootstrap ::show-case :::docs-pagination-bootstrap ::: #code ```vue [DocsPaginationBootstrap.vue] ``` :: ### Table ::show-case :::docs-pagination-table ::: #code ```vue [DocsPaginationTable.vue] ``` :: # Pin Input ## Source code Click :source-code-link{component="PinInput"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add pin-input"} :: ## Usage ### Placeholder Passing a value to the placeholder prop will render a placeholder character in each input. ::show-case :::docs-pin-input ::: #code ```vue [DocsPinInput.vue] ``` :: ### Separator Passing a value to the separator prop will render a separator character between each input. ::show-case :::docs-pin-input-separator ::: #code ```vue [DocsPinInputSeparator.vue] ``` :: ### Complete event The complete event is emitted when the user has entered a value in all inputs. ::show-case :::docs-pin-input-complete ::: #code ```vue [DocsPinInputComplete.vue] ``` :: ### Origin UI ::show-case :::docs-pin-input-origin ::: #code ```vue [DocsPinInputOrigin.vue] ``` :: # Placeholder ## Source code Click :source-code-link{component="Placeholder.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add placeholder"} :: ## Usage ::show-case :::docs-placeholder ::: #code ```vue [DocsPlaceholder.vue] ``` :: # Popover ## Source code Click :source-code-link{component="Popover"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add popover"} :: ## Anatomy ```vue ``` ## Usage ### Full example ::show-case :::docs-popover ::: #code ```vue [DocsPopover.vue] ``` :: ### Origin UI ::show-case :::docs-popover-origin ::: #code ```vue [DocsPopoverOrigin.vue] ``` :: # Progress ## Source code Click :source-code-link{component="Progress"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add progress"} :: ## Anatomy ```vue ``` ## Usage ### Full example ::show-case :::docs-progress ::: #code ```vue [DocsProgress.vue] ``` :: ### Loader ::show-case :::docs-progress-loading ::: #code ```vue [DocsProgressLoading.vue] ``` :: # Radio Group ## Source code Click :source-code-link{component="RadioGroup"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add radio-group"} :: ## Anatomy ```vue ``` ## Usage ### Default value ::show-case :::docs-radio-group ::: #code ```vue [DocsRadioGroup.vue] ``` :: ### Form ::show-case :::docs-radio-group-form ::: #code ```vue [DocsRadioGroupForm.vue] ``` :: # Rating ## Source code Click :source-code-link{component="Rating.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add rating"} :: ## Usage ### Basic ::show-case :::docs-rating ::: #code ```vue [DocsRating.vue] ``` :: ### Decimal ::show-case :::docs-rating-decimal ::: #code ```vue [DocsRatingDecimal.vue] ``` :: ### Show Rating ::show-case :::docs-rating-show-value ::: #code ```vue [DocsRatingShowValue.vue] ``` :: ### Editable ::show-case :::docs-rating-editable ::: #code ```vue [DocsRatingEditable.vue] ``` :: ### Size ::show-case :::docs-rating-size ::: #code ```vue [DocsRatingSize.vue] ``` :: ### Icons ::show-case :::docs-rating-icons ::: #code ```vue [DocsRatingIcons.vue] ``` :: ### Statistics ::show-case :::docs-rating-statistics ::: #code ```vue [DocsRatingStatistics.vue] ``` :: # Scroll Area ## Source code Click :source-code-link{component="ScrollArea"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add scroll-area"} :: ## Usage ```vue ``` ### Basic example ::show-case :::docs-scroll-area ::: #code ```vue [DocsScrollArea.vue] ``` :: ### Horizontal scroll ::show-case :::docs-scroll-area-horizontal ::: #code ```vue [DocsScrollAreaHorizontal.vue] ``` :: # Scrollspy ## Source code Click :source-code-link{component="Scrollspy.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add scrollspy"} :: ## Usage ### Component ::show-case :::docs-scrollspy ::: #code ```vue [DocsScrollspy.vue] ``` :: ### Composable ::show-case :::docs-scrollspy-composable ::: #code ```vue [DocsScrollspyComposable.vue] ``` :: ### Horizontal ::show-case :::docs-scrollspy-horizontal ::: #code ```vue [DocsScrollspyHorizontal.vue] ``` :: # Select ## Source code Click :source-code-link{component="Select"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add select"} :: ## Usage ### Basic example ::show-case :::docs-select ::: #code ```vue [DocsSelect.vue] ``` :: ### Scrollable ::show-case :::docs-select-scrollable ::: #code ```vue [DocsSelectScrollable.vue] ``` :: ### Form ::show-case :::docs-select-form ::: #code ```vue [DocsSelectForm.vue] ``` :: ### Origin UI ::show-case :::docs-select-origin ::: #code ```vue [DocsSelectOrigin.vue] ``` :: # Select - Native ## Source code Click :source-code-link{component="NativeSelect.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add native-select"} :: ## Origin UI Examples ::show-case :::docs-native-select-origin ::: #code ```vue [DocsNativeSelectOrigin.vue] ``` :: # Separator ## Source code Click :source-code-link{component="Separator.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add separator"} :: ## Usage ### Basic example ::show-case :::docs-separator ::: #code ```vue [DocsSeparator.vue] ``` :: # Sheet ## Source code Click :source-code-link{component="Sheet"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add sheet"} :: ## Usage ### Basic example ::show-case :::docs-sheet ::: #code ```vue [DocsSheet.vue] ``` :: # Sidebar ## Source code Click :source-code-link{component="Sidebar"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add sidebar"} :: ## Usage You should always ensure that you have all parts of the `Sidebar` components wrapped in a `UiSidebarProvider` component. This is to ensure that the sidebar can be toggled on and off. ```vue [app.vue] ``` ### First Sidebar Let's start with the most basic sidebar. A collapsible sidebar with a menu. ::block-showcase --- block-path: Sidebar/BlockSidebarFirstSidebar component: BlockSidebarFirstSidebar container-class: h-screen iframe-height: 600px --- :: The code. Take note of the `UiSidebarTrigger` component. This is what toggles the sidebar. Also, the `UiSidebarInset` component! When I just started using this component, I was confused as to where the page content should go. ```vue [BlockSidebarFirstSidebar.vue] ``` ## SidebarHeader Use the `UiSidebarHeader` component to add a sticky header to the sidebar. The following example adds a `` to the `UiSidebarHeader`. ::block-showcase --- block-path: Sidebar/BlockSidebarHeader component: BlockSidebarHeader container-class: h-screen iframe-height: 600px --- :: ## SidebarFooter Use the `UiSidebarFooter` component to add a sticky footer to the sidebar. The following example adds a `` to the `UiSidebarFooter`. ::block-showcase --- block-path: Sidebar/BlockSidebarFooter component: BlockSidebarFooter container-class: h-screen iframe-height: 600px --- :: ## Collapsible SidebarGroup To make a `UiSidebarGroup` collapsible, wrap it in a `UiCollapsible`. ::block-showcase --- block-path: Sidebar/BlockSidebarCollapsibleSideGroup component: BlockSidebarCollapsibleSideGroup container-class: h-screen iframe-height: 600px --- :: We wrap the `UiCollapsibleTrigger` in a `UiSidebarGroupLabel` to render a button. ## SidebarGroupAction Use the `UiSidebarGroupAction` component to add an action button to the `UiSidebarGroup`. ::block-showcase --- block-path: Sidebar/BlockSidebarSidebarGroupAction component: BlockSidebarSidebarGroupAction container-class: h-screen iframe-height: 600px --- :: ## SidebarMenuAction The `UiSidebarMenuAction` component is used to render a menu action within a `UiSidebarMenuItem`. This button works independently of the `UiSidebarMenuButton` i.e you can have the `` as a clickable link and the `` as a button. ::block-showcase --- block-path: Sidebar/BlockSidebarSidebarMenuAction component: BlockSidebarSidebarMenuAction container-class: h-screen iframe-height: 600px --- :: ## SidebarMenuSub The `UiSidebarMenuSub` component is used to render a submenu within a `UiSidebarMenu`. Use `` and `` to render a submenu item. ::block-showcase --- block-path: Sidebar/BlockSidebarSidebarMenuSub component: BlockSidebarSidebarMenuSub container-class: h-screen iframe-height: 600px --- :: ## Collapsible SidebarMenu To make a `UiSidebarMenu` component collapsible, wrap it and the `UiSidebarMenuSub` components in a `UiCollapsible`. ::block-showcase --- block-path: Sidebar/BlockSidebarSidebarMenuSubCollapsible component: BlockSidebarSidebarMenuSubCollapsible container-class: h-screen iframe-height: 600px --- :: ## SidebarMenuBadge The `UiSidebarMenuBadge` component is used to render a badge within a `UiSidebarMenuItem`. ::block-showcase --- block-path: Sidebar/BlockSidebarSidebarMenuBadge component: BlockSidebarSidebarMenuBadge container-class: h-screen iframe-height: 600px --- :: ## SidebarRail The `UiSidebarRail` component is used to render a rail within a `UiSidebar`. This rail can be used to toggle the sidebar. ::block-showcase --- block-path: Sidebar/BlockSidebarSidebarRail component: BlockSidebarSidebarRail container-class: h-screen iframe-height: 600px --- :: ## Controlled Sidebar Use the `v-model:open` directive to control the visibility of the sidebar. This should be added to the `UiSidebarProvider` component. You can even model this to local storage with the help of [useStorage](https://vueuse.org/core/useStorage/){rel="nofollow"} from VueUse. You can even use Pinia to store the state of the sidebar & make it global. ::block-showcase --- block-path: Sidebar/BlockSidebarControlled component: BlockSidebarControlled container-class: h-screen iframe-height: 600px --- :: # Skeleton ## Source code Click :source-code-link{component="Skeleton.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add skeleton"} :: ## Usage ### Basic example ::show-case :::docs-skeleton ::: #code ```vue [DocsSkeleton.vue] ``` :: # Slider ## Source code Click :source-code-link{component="Slider"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add slider"} :: ## Usage ### Basic example ::show-case :::docs-slider ::: #code ```vue [DocsSlider.vue] ``` :: ### Multiple thumbs ::show-case :::docs-slider-multiple ::: #code ```vue [DocsSliderMultiple.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/sliders){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Square Thumb ::show-case :::docs-slider-square-thumb ::: #code ```vue [DocsSliderSquareThumb.vue] ``` :: ### Solid Thumb ::show-case :::docs-slider-solid-thumb ::: #code ```vue [DocsSliderSolidThumb.vue] ``` :: ### Tiny Thumb ::show-case :::docs-slider-tiny-thumb ::: #code ```vue [DocsSliderTinyThumb.vue] ``` :: ### Reference Labels ::show-case :::docs-slider-reference-labels ::: #code ```vue [DocsSliderReferenceLabels.vue] ``` :: ### Ticks ::show-case :::docs-slider-ticks ::: #code ```vue [DocsSliderTicks.vue] ``` :: ### Slider w/ Output ::show-case :::docs-slider-output ::: #code ```vue [DocsSliderOutput.vue] ``` :: ### Slider w/ Labels ::show-case :::docs-slider-labels ::: #code ```vue [DocsSliderLabels.vue] ``` :: ### Slider w/ Labels & Tooltip ::show-case :::docs-slider-labels-tooltips ::: #code ```vue [DocsSliderLabelsTooltips.vue] ``` :: ### Dual Range ::show-case :::docs-slider-dual-range ::: #code ```vue [DocsSliderDualRange.vue] ``` :: ### Dual Range w/ Output ::show-case :::docs-slider-dual-range-output ::: #code ```vue [DocsSliderDualRangeOutput.vue] ``` :: ### Volume ::show-case :::docs-slider-volume ::: #code ```vue [DocsSliderVolume.vue] ``` :: ### Temperature ::show-case :::docs-slider-temperature ::: #code ```vue [DocsSliderTemperature.vue] ``` :: ### Input ::show-case :::docs-slider-input ::: #code ```vue [DocsSliderInput.vue] ``` :: ### Rate your experience ::show-case :::docs-slider-rate-exp1 ::: #code ```vue [DocsSliderRateExp1.vue] ``` :: ### Rate your experience (tooltip) ::show-case :::docs-slider-rate-exp-tooltip ::: #code ```vue [DocsSliderRateExpTooltip.vue] ``` :: ### Dual Range w/ Input ::show-case :::docs-slider-dual-range-input ::: #code ```vue [DocsSliderDualRangeInput.vue] ``` :: ### Credits per Month ::show-case :::docs-slider-credits-per-month ::: #code ```vue [DocsSliderCreditsPerMonth.vue] ``` :: ### Money Range ::show-case :::docs-slider-money-range ::: #code ```vue [DocsSliderMoneyRange.vue] ``` :: ### Vertical ::show-case :::docs-slider-vertical ::: #code ```vue [DocsSliderVertical.vue] ``` :: ### Vertical Input ::show-case :::docs-slider-vertical-input ::: #code ```vue [DocsSliderVerticalInput.vue] ``` :: ### Vertical Dual Range w/ Tooltip ::show-case :::docs-slider-vertical-dual-tooltip ::: #code ```vue [DocsSliderVerticalDualTooltip.vue] ``` :: ### Object Position ::show-case :::docs-slider-object-position ::: #code ```vue [DocsSliderObjectPosition.vue] ``` :: ### Price ::show-case :::docs-slider-price ::: #code ```vue [DocsSliderPrice.vue] ``` :: ### Equalizer ::show-case :::docs-slider-equalizer ::: #code ```vue [DocsSliderEqualizer.vue] ``` :: # Sonner ## Source code Click :source-code-link{component="Sonner.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add sonner"} :: Add the `` component to your `app.vue` file: ```vue [app.vue] noFormat ``` ## Usage ### Full example ::show-case :::docs-sonner ::: #code ```vue [DocsSonner.vue] ``` :: For the custom element, this is what the code looks like ```vue [DocsSonnerHeadless.vue] ``` # Splitter ## Source code Click :source-code-link{component="Splitter"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add splitter"} :: ## Usage ### Basic We can put the parts together to build a simple layout with a resizable sidebar. ::show-case :::docs-splitter-basic ::: #code ```vue [DocsSplitterBasic.vue] ``` :: ### Handle We can pass teh `withHandle` prop to the `UiSplitterHandle` component to show a handle. We can even pass in a custom icon to display for the handle. Do note that the handle will be rotated because of this class that is added to it `[&[data-orientation=vertical]>div]:rotate-90`. ::show-case :::docs-splitter-handle ::: #code ```vue [DocsSplitterHandle.vue] ``` :: ### Collapsible We can use the `collapsible` prop to make the panels go down to the `collapsedSize` when the `minSize` is reached. ::show-case :::docs-splitter-collapsible ::: #code ```vue [DocsSplitterCollapsible.vue] ``` :: ### Persist Layout with SSR We can use the `autoSaveId` prop to persist the layout data into the local storage. Try changing the layout and then refresh the page to see the layout persist. ::show-case :::docs-splitter-persist ::: #code ```vue [DocsSplitterPersist.vue] ``` :: # Stepper ## Source code Click :source-code-link{component="Stepper"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add stepper"} :: ### Origin UI ::show-case :::docs-stepper-origin ::: #code ```vue [DocsStepperOrigin.vue] ``` :: # Switch ## Source code Click :source-code-link{component="Switch"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add switch"} :: ## Usage ### Basic example ::show-case :::docs-switch ::: #code ```vue [DocsSwitch.vue] ``` :: ### Form ::show-case :::docs-switch-form ::: #code ```vue [DocsSwitchForm.vue] ``` :: ### Origin UI ::show-case :::docs-switch-origin ::: #code ```vue [DocsSwitchOrigin.vue] ``` :: # Table ## Source code Click :source-code-link{component="Table"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add table"} :: ## Usage ### Basic example ::show-case :::docs-table ::: #code ```vue [DocsTable.vue] ``` :: ### Simple ::show-case :::docs-table-simple ::: #code ```vue [DocsTableSimple.vue] ``` :: ### Stacked on mobile ::show-case :::docs-table-stacked-mobile ::: #code ```vue [DocsTableStackedMobile.vue] ``` :: ### Sticky header ::show-case :::docs-table-sticky-header ::: #code ```vue [DocsTableStickyHeader.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/tables){rel="nofollow"} ❤️. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Basic Table ::show-case :::docs-table-basic ::: #code ```vue [DocsTableBasic.vue] ``` :: ### Table with Images ::show-case :::docs-table-images ::: #code ```vue [DocsTableImages.vue] ``` :: ### Table No Horizontal Lines ::show-case :::docs-table-no-horizontal-lines ::: #code ```vue [DocsTableNoHorizontalLines.vue] ``` :: ### Striped Tabled ::show-case :::docs-table-striped ::: #code ```vue [DocsTableStriped.vue] ``` :: ### Vertical Lines ::show-case :::docs-table-vertical-lines ::: #code ```vue [DocsTableVerticalLines.vue] ``` :: ### Dense Table ::show-case :::docs-table-dense ::: #code ```vue [DocsTableDense.vue] ``` :: ### Row Selection ::show-case :::docs-table-basic-row-selection ::: #code ```vue [DocsTableBasicRowSelection.vue] ``` :: ### Card Table ::show-case :::docs-table-card-table ::: #code ```vue [DocsTableCardTable.vue] ``` :: ### Vertical Table ::show-case :::docs-table-vertical ::: #code ```vue [DocsTableVertical.vue] ``` :: ### Sticky Header 2 ::show-case :::docs-table-sticky-header2 ::: #code ```vue [DocsTableStickyHeader2.vue] ``` :: ### Browser Support ::show-case :::docs-table-browser-support ::: #code ```vue [DocsTableBrowserSupport.vue] ``` :: # Tabs ## Source code Click :source-code-link{component="Tabs"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add tabs"} :: ## Usage ### Basic example ::show-case :::docs-tabs ::: #code ```vue [DocsTabs.vue] ``` :: ### With Indicator Passing `:pill="false"` to the List and Trigger components will remove the background color from both components. This allows us to use the Indicator component to create a custom indicator. ::show-case :::docs-tabs-indicator ::: #code ```vue [DocsTabsIndicator.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/tabs){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### One ::show-case :::docs-tabs1 ::: #code ```vue [DocsTabs1.vue] ``` :: ### Two ::show-case :::docs-tabs2 ::: #code ```vue [DocsTabs2.vue] ``` :: ### Three ::show-case :::docs-tabs3 ::: #code ```vue [DocsTabs3.vue] ``` :: ### Four ::show-case :::docs-tabs4 ::: #code ```vue [DocsTabs4.vue] ``` :: ### Five ::show-case :::docs-tabs5 ::: #code ```vue [DocsTabs5.vue] ``` :: ### Six ::show-case :::docs-tabs6 ::: #code ```vue [DocsTabs6.vue] ``` :: ### Seven ::show-case :::docs-tabs7 ::: #code ```vue [DocsTabs7.vue] ``` :: ### Eight ::show-case :::docs-tabs8 ::: #code ```vue [DocsTabs8.vue] ``` :: ### Nine ::show-case :::docs-tabs9 ::: #code ```vue [DocsTabs9.vue] ``` :: ### Ten ::show-case :::docs-tabs10 ::: #code ```vue [DocsTabs10.vue] ``` :: ### Eleven ::show-case :::docs-tabs11 ::: #code ```vue [DocsTabs11.vue] ``` :: ### Twelve ::show-case :::docs-tabs12 ::: #code ```vue [DocsTabs12.vue] ``` :: ### Thirteen ::show-case :::docs-tabs13 ::: #code ```vue [DocsTabs13.vue] ``` :: ### Fourteen ::show-case :::docs-tabs14 ::: #code ```vue [DocsTabs14.vue] ``` :: ### Fifteen ::show-case :::docs-tabs15 ::: #code ```vue [DocsTabs15.vue] ``` :: ### Sixteen ::show-case :::docs-tabs16 ::: #code ```vue [DocsTabs16.vue] ``` :: ### Seventeen ::show-case :::docs-tabs17 ::: #code ```vue [DocsTabs17.vue] ``` :: ### Eighteen ::show-case :::docs-tabs18 ::: #code ```vue [DocsTabs18.vue] ``` :: ### Nineteen ::show-case :::docs-tabs19 ::: #code ```vue [DocsTabs19.vue] ``` :: ### Twenty ::show-case :::docs-tabs20 ::: #code ```vue [DocsTabs20.vue] ``` :: # Tags Input ## Source code Click :source-code-link{component="TagsInput"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add tags-input"} :: ## Usage ### Basic example ::show-case :::docs-tags-input ::: #code ```vue [DocsTagsInput.vue] ``` :: # Tanstack Table ## Source code Click :source-code-link{component="TanStackTable.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add tanstacktable"} :: ## Usage ### Regular ::show-case :::docs-tan-stack-table ::: #code ```vue [DocsTanStackTable.vue] ``` :: ### Basic ::show-case :::docs-tan-stack-basic ::: #code ```vue [DocsTanStackBasic.vue] ``` :: ### Filters ::show-case :::docs-tan-stack-filters ::: #code ```vue [DocsTanStackFilters.vue] ``` :: # Textarea ## Source code Click :source-code-link{component="Textarea.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add textarea"} :: ## Usage ### Basic example ::show-case :::docs-textarea ::: #code ```vue [DocsTextarea.vue] ``` :: ### Label ::show-case :::docs-textarea-label ::: #code ```vue [DocsTextareaLabel.vue] ``` :: ### Form ::show-case :::docs-textarea-form ::: #code ```vue [DocsTextareaForm.vue] ``` :: ### Max Length Restrict the number of characters that can be entered into the textarea. ::show-case :::docs-textarea-max-length ::: #code ```vue [DocsTextareaMaxLength.vue] ``` :: ### Pattern Restrict the type of characters that can be entered into the textarea. You don't need to use `/` at the beginning and end of the pattern as the RegExp is being created internally with the `new RegExp()` constructor. ::show-case :::docs-textarea-pattern ::: #code ```vue [DocsTextareaPattern.vue] ``` :: # Timeline ## Credits Thanks to the team at [Origin UI](https://originui.com/timeline){rel="nofollow"} for creating this component ❤️. I just made a vue version of it. ## Source code Click :source-code-link{component="Timeline"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add timeline"} :: ## Usage ### Basic ::show-case :::docs-timeline ::: #code ```vue [DocsTimeline.vue] ``` :: ### Date Left ::show-case :::docs-timeline-date-left ::: #code ```vue [DocsTimelineDateLeft.vue] ``` :: ### Date Top ::show-case :::docs-timeline-date-top ::: #code ```vue [DocsTimelineDateTop.vue] ``` :: ### Time Bottom ::show-case :::docs-timeline-time-bottom ::: #code ```vue [DocsTimelineTimeBottom.vue] ``` :: ### Check Icon ::show-case :::docs-timeline-check-icon ::: #code ```vue [DocsTimelineCheckIcon.vue] ``` :: ### Git ::show-case :::docs-timeline-git ::: #code ```vue [DocsTimelineGit.vue] ``` :: ### Card Content ::show-case :::docs-timeline-card-content ::: #code ```vue [DocsTimelineCardContent.vue] ``` :: ### Left & Right ::show-case :::docs-timeline-left-right ::: #code ```vue [DocsTimelineLeftRight.vue] ``` :: ### Card ::show-case :::docs-timeline-card ::: #code ```vue [DocsTimelineCard.vue] ``` :: ### Activity ::show-case :::docs-timeline-activity ::: #code ```vue [DocsTimelineActivity.vue] ``` :: ### Horizontal ::show-case :::docs-timeline-horizontal ::: #code ```vue [DocsTimelineHorizontal.vue] ``` :: ### Horizontal - Date Top ::show-case :::docs-timeline-horizontal-date-top ::: #code ```vue [DocsTimelineHorizontalDateTop.vue] ``` :: # Toggle ## Source code Click :source-code-link{component="Toggle.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add toggle"} :: ## Usage ### Basic example ::show-case :::docs-toggle ::: #code ```vue [DocsToggle.vue] ``` :: # Toggle Group ## Source code Click :source-code-link{component="ToggleGroup"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add toggle-group"} :: ## Usage ### Basic ::show-case :::docs-toggle-group-basic ::: #code ```vue [DocsToggleGroupBasic.vue] ``` :: ### Outline ::show-case :::docs-toggle-group-outline ::: #code ```vue [DocsToggleGroupOutline.vue] ``` :: ### Multiple ::show-case :::docs-toggle-group-multiple ::: #code ```vue [DocsToggleGroupMultiple.vue] ``` :: ### Sizes ::show-case :::docs-toggle-group-size ::: #code ```vue [DocsToggleGroupSize.vue] ``` :: # Tooltip ## Source code Click :source-code-link{component="Tooltip"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add tooltip"} :: ## Usage ### Basic example ::show-case :::docs-tooltip ::: #code ```vue [DocsTooltip.vue] ``` :: ### Origin UI ::show-case :::docs-tooltip-origin ::: #code ```vue [DocsTooltipOrigin.vue] ``` :: # Tree ## Source code Click :source-code-link{component="Tree"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add tree"} :: ## Usage ### Basic The `Tree` component can be styled to look like anything you want. For that reason, I decided to not style the tree component at all. Instead, I provide a basic example of how to use the tree component. ::show-case :::docs-tree ::: #code ```vue [DocsTree.vue] ``` :: ### Virtualizer We can render a large number of items using the `Virtualizer` component. Click on one of the items to see the details. ::show-case :::docs-tree-virtualizer ::: #code ```vue [DocsTreeVirtualizer.vue] ``` :: ### Origin UI ::show-case :::docs-tree-origin ::: #code ```vue [DocsTreeOrigin.vue] ``` :: # Border Beam ## Credits Shout out to [Magic UI](https://magicui.design/docs/components/border-beam){rel="nofollow"} for the inspiration. I actually discovered this package while browsing their website. ## Source code Click :source-code-link{component="BorderBeam.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ::prose-pm-x{command="ui-thing@latest add border-beam"} :: ## Usage ### Basic Just place the border beam component inside a div with relative positioning, width, and height. You will notice the beam automatically moves around the perimeter of it's container. ::show-case :::docs-border-beam ::: #code ```vue [DocsBorderBeam.vue] ``` :: ### 2 Border Beams ::show-case :::docs-border-beam-two ::: #code ```vue [DocsBorderBeamTwo.vue] ``` :: ### Reverse ::show-case :::docs-border-beam-reverse ::: #code ```vue [DocsBorderBeamReverse.vue] ``` :: ### Spring Animation ::show-case :::docs-border-beam-spring ::: #code ```vue [DocsBorderBeamSpring.vue] ``` :: # Confetti ## Credits Shout out to [Magic UI](https://magicui.design/docs/components/confetti){rel="nofollow"} for the inspiration. I actually discovered this package while browsing their website. ## Getting Started ::steps :::step ### Installation To get started, you will need to install the package. You can visit the [Canvas Confetti](https://github.com/catdad/canvas-confetti){rel="nofollow"} page for more details... All the details 🙂. ::::prose-pm-install{name="canvas-confetti"} :::: ::: :::step ### Create Composable Create a composable in your `composables` directory. You can name it `useConfetti.ts`. Add this to the file: ::::prose-code-snippet --- file: /composables/useConfetti.ts language: ts meta: noFormat title: useConfetti Composable --- :::: ::: :: ## Usage ### Basic We can just call the `useConfetti` method to trigger the confetti. ::show-case :::docs-confetti ::: #code ```vue [DocsConfetti.vue] ``` :: ### Random Direction This is how you can shoot confetti off in a random direction. ::show-case :::docs-confetti-random-direction ::: #code ```vue [DocsConfettiRandomDirection.vue] ``` :: ### Fireworks ::show-case :::docs-confetti-fireworks ::: #code ```vue [DocsConfettiFireworks.vue] ``` :: ### Stars ::show-case :::docs-confetti-stars ::: #code ```vue [DocsConfettiStars.vue] ``` :: ### Snow ::show-case :::docs-confetti-snow ::: #code ```vue [DocsConfettiSnow.vue] ``` :: ### Side Cannon ::show-case :::docs-confetti-side-cannon ::: #code ```vue [DocsConfettiSideCannon.vue] ``` :: ### Emoji ::show-case :::docs-confetti-emoji ::: #code ```vue [DocsConfettiEmoji.vue] ``` :: # File Upload ## Credits - [ReUI](https://reui.io/docs/file-upload){rel="nofollow"} - [Origin UI Vue](https://www.originui-vue.com/file-upload){rel="nofollow"} ## Getting Started ::steps :::step ### Installation Add the following packages to your project ::::prose-pm-install{name="@vueuse/core"} :::: ::: :::step ### Add Composable Add the following composable to your `composables` directory ::::prose-code-snippet --- file: /composables/useFileUpload.ts language: ts meta: noFormat title: useFileUpload Composable --- :::: ::: :: ## Usage ### Avatar Upload 1 ::show-case :::docs-file-upload-avatar-upload1 ::: #code ```vue [DocsFileUploadAvatarUpload1.vue] ``` :: ### Avatar Upload 2 ::show-case :::docs-file-upload-avatar-upload2 ::: #code ```vue [DocsFileUploadAvatarUpload2.vue] ``` :: ### Single Image Uploader ::show-case :::docs-file-upload-single-image-uploader ::: #code ```vue [DocsFileUploadSingleImageUploader.vue] ``` :: ### Single Image Uploader w/ Button ::show-case :::docs-file-upload-single-image-uploader-button ::: #code ```vue [DocsFileUploadSingleImageUploaderButton.vue] ``` :: ### Multiple Image Uploader w/ Grid ::show-case :::docs-file-upload-multiple-image-uploader-grid ::: #code ```vue [DocsFileUploadMultipleImageUploaderGrid.vue] ``` :: ### Multiple Image Uploader w/ List + Button ::show-case :::docs-file-upload-multiple-image-uploader-list-button ::: #code ```vue [DocsFileUploadMultipleImageUploaderListButton.vue] ``` :: ### Single File Uploader ::show-case :::docs-file-upload-single-file-uploader ::: #code ```vue [DocsFileUploadSingleFileUploader.vue] ``` :: ### Multiple File Uploader ::show-case :::docs-file-upload-multiple-file-uploader ::: #code ```vue [DocsFileUploadMultipleFileUploader.vue] ``` :: ### Multiple File Uploader w/ List Inside ::show-case :::docs-file-upload-multiple-file-uploader-list-inside ::: #code ```vue [DocsFileUploadMultipleFileUploaderListInside.vue] ``` :: ### Multiple File Uploader w/ Table ::show-case :::docs-file-upload-multiple-file-uploader-table ::: #code ```vue [DocsFileUploadMultipleFileUploaderTable.vue] ``` :: ### Mixed Content w/ Card ::show-case :::docs-file-upload-mixed-content-card ::: #code ```vue [DocsFileUploadMixedContentCard.vue] ``` :: # Full Calendar ## Getting Started ::steps :::step ### Installation To get started, you can install the package with the following command: ::::prose-pm-install{name="@fullcalendar/core @fullcalendar/vue3"} :::: ::: :::step ### Add Plugins You can also install the plugins for Full Calendar: ::::prose-pm-install --- name: "@fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/timegrid @fullcalendar/list @fullcalendar/multimonth @fullcalendar/scrollgrid" --- :::: ::: :::step ### Update CSS In order to make the calendar match the UI Thing theme, I had to create the `full-calendar.css` file and import it in the `nuxt.config.ts` file. ::::prose-code-snippet --- file: /assets/css/full-calendar.css language: css title: Full Calendar --- :::: ::: :: ## Usage ### Month View ::show-case :::docs-full-calendar ::: #code ```vue [DocsFullCalendar.vue] ``` :: ### List View ::show-case :::docs-full-calendar-list ::: #code ```vue [DocsFullCalendarList.vue] ``` :: ### TimeGrid View ::show-case :::docs-full-calendar-time-grid ::: #code ```vue [DocsFullCalendarTimeGrid.vue] ``` :: ### MultiMonth View ::show-case :::docs-full-calendar-multi-month ::: #code ```vue [DocsFullCalendarMultiMonth.vue] ``` :: # Gooey Menu ## Credits Shout out to [Julien Thibeaut](https://ibelick.com/){rel="nofollow"} for the source code. I discovered this gooey menu while browsing his website. ## Usage ### Basic This may not be a component that can be reused across multiple projects, but it's a fun one to have in your back pocket. ::show-case :::docs-gooey-menu ::: #code ```vue [DocsGooeyMenu.vue] ``` :: # Meteors ## Credits Shout out to [Magic UI](https://magicui.design/docs/components/meteors){rel="nofollow"} for the inspiration. I actually discovered this package while browsing their website. ## Getting Started ::steps :::step ### Add Animation You will need to add this to your `tailwind.css` file. ```css @theme inline { --animate-meteor: meteor 5s linear infinite; @keyframes meteor { 0% { transform: rotate(var(--angle)) translateX(0); opacity: 1; } 70% { opacity: 1; } 100% { transform: rotate(var(--angle)) translateX(-500px); opacity: 0; } } } ``` ::: :::step ### Create Component Create the component `Meteors.client.vue` in the `components` directory. ::::prose-code-snippet --- file: /components/Ui/Meteors.client.vue language: vue title: Meteors Component --- :::: ::: :: ## Usage ### Basic We can add the `UiMeteors` component to trigger the meteors. ::show-case :::docs-meteors ::: #code ```vue [DocsMeteors.vue] ``` :: # Neon Gradient Card ## Credits Shout out to [Magic UI](https://magicui.design/docs/components/neon-gradient-card){rel="nofollow"} for the implementation. I actually discovered this component while browsing their website. ## Getting Started ::steps :::step ### Create the Component Create the the `NeonGradientCard` component in the `components` directory. ```vue [NeonGradientCard.vue] ``` ::: :::step ### Add animation to `tailwind.css` file ```css @theme inline { --animate-background-position-spin: background-position-spin 3000ms infinite alternate; @keyframes background-position-spin { 0% { background-position: top center; } 100% { background-position: bottom center; } } } ``` ::: :: ## Usage ::show-case :::docs-neon-gradient-card ::: #code ```vue [DocsNeonGradientCard.vue] ``` :: # Quill ## Getting Started ::steps :::step ### Installation To get started, you can install the package with the following command: ::::prose-pm-install{name="@vueup/vue-quill"} :::: ::: :::step ## Create CSS File In order to make the editor match the design of this website (and the whole shadcn/ui theme), I had to add this css file: You should copy this and add it to your project. ::::prose-code-snippet --- file: /assets/css/quill.css language: css title: Quill CSS Overrides --- :::: ::: :: ## Usage ### Basic Here is a basic example of how to use the Quill component. We are using a technique called `Slot Forwarding` so that if the developer wants to create a component and pass through the `toolbar` slot, they can do so. ::show-case :::docs-quill ::: #code ```vue [DocsQuill.vue] ``` :: ### Toolbar We can add our custom toolbar configuration by using the `toolbar` prop. ::show-case :::docs-quill-toolbar ::: #code ```vue [DocsQuillToolbar.vue] ``` :: ### Slot - Toolbar Another way of customizing the toolbar is by using the `toolbar` slot. This way, we can create a custom toolbar with our own components. ::show-case :::docs-quill-toolbar2 ::: #code ```vue [DocsQuillToolbar2.vue] ``` :: ### Bubble Theme We can pass the `bubble` value to the `theme` prop to use the snow theme. You have to select something in the editor to see the toolbar. ::show-case :::docs-quill-bubble ::: #code ```vue [DocsQuillBubble.vue] ``` :: ### Module We can pass an object or an array of objects to the `module` prop to use any Quill module. Something like this: ```vue ``` Upload an image to see the module in action. ::show-case :::docs-quill-module ::: #code ```vue [DocsQuillModule.vue] ``` :: # Retro Grid ## Credits Shout out to [Magic UI](https://magicui.design/docs/components/retro-grid){rel="nofollow"} for the inspiration. I actually discovered this package while browsing their website. ## Getting Started ::steps :::step ### Add Animation You will need to add this to your `tailwind.css` file. ```css --animate-grid: grid 15s linear infinite; @keyframes grid { 0% { transform: translateY(-50%); } 100% { transform: translateY(0); } } ``` ::: :::step ### Create Component Create the component `RetroGrid.vue` in the `components` directory. ```vue [RetroGrid.vue] ``` ::: :: ## Usage ### Basic ::show-case :::docs-retro-grid ::: #code ```vue [DocsRetroGrid.vue] ``` :: # Terminal ## Credits Shout out to [Magic UI](https://magicui.design/docs/components/terminal){rel="nofollow"} for the inspiration. I actually discovered this component while browsing their website. ## Getting Started ::steps :::step ### Add Components This consists of three components #### Terminal ```vue [Terminal.vue] ``` #### AnimatedSpan ```vue [AnimatedSpan.vue] ``` #### TypingAnimation ```vue [TypingAnimation.vue] ``` ::: :: ## Anatomy ```html Hello, world! UI Thing is awesome! ``` ## Usage ::show-case :::docs-terminal ::: #code ```vue [DocsTerminal.vue] ``` :: # Tiptap ## Getting Started ::steps :::step ### Installation First wee need to install basic packages that we need. To make a great editor, you will need to install a whole lot more extensions. But for now, we will just install the basic packages. ::::prose-pm-install{name="@tiptap/vue-3 @tiptap/pm @tiptap/starter-kit"} :::: ::: :::step ### Create Editor Component Create the component `Tiptap.vue` in the `components` directory. The component has to be a client only component. The one used here looks like this. Like I said earlier, you have to install a lot of packages to get the functionality you want. ::::prose-code-snippet --- file: /components/Ui/Tiptap.vue language: vue title: TipTap --- :::: ::: :: ## Usage ### Basic In this example, we are just passing the model to the editor. We are also customizing the look and feel of this single instance of the editor. Feel free to customize it to your liking. ::show-case :::docs-tiptap ::: #code ```vue [DocsTiptap.vue] ``` :: # Vue Tippy ## Getting Started ::steps :::step ### Installation Run the command below to install the Vue Tippy package. ```bash npm install vue-tippy@v6 ``` ::: :::step ### Create Plugin Create a plugin to add Vue Tippy globally to your Nuxt application. Here I added some configurations to the plugin, like the default animation, delay, trigger, and touch. Feel free to change these configurations to fit your needs. ```ts [tippy.ts] import VueTippy from "vue-tippy"; import type { TippyPluginOptions } from "vue-tippy"; import "tippy.js/animations/scale.css"; import "tippy.js/animations/shift-away.css"; import "tippy.js/animations/shift-toward.css"; import "tippy.js/animations/perspective.css"; export default defineNuxtPlugin((nuxtApp) => { nuxtApp.vueApp.use(VueTippy, { component: "Tippy", directive: "tippy", defaultProps: { animation: "shift-away", delay: [200, 100], trigger: "mouseenter", touch: ["hold", 500], arrow: false, }, } satisfies TippyPluginOptions); }); ``` ::: :::step ### Add CSS Create a new CSS file and add the following code to it. ```css [tippy.css] @reference "./tailwind.css"; [data-tippy-root] { .tippy-box { @apply rounded-md bg-popover px-2 py-1 text-popover-foreground shadow ring-1 ring-border; .tippy-content { @apply text-[13px]; } } .tippy-box[data-theme~="error"] { @apply bg-destructive text-destructive-foreground ring-destructive; } } ``` ::: :: ## Usage There are three(3) ways in which you can use Vue Tippy: ### Directive We can add the `v-tippy` directive to any element to show a tooltip. The directive accepts a string with the content of the tooltip OR an object with the content and the options. Check out the [Directive Docs](https://vue-tippy.netlify.app/flavor/directive){rel="nofollow"} to learn more. ::show-case :::docs-tippy-usage-directive ::: #code ```vue [DocsTippyUsageDirective.vue] ``` :: ### Component We can use the `` component to show a tooltip. You can visit the [Component Docs](https://vue-tippy.netlify.app/flavor/component){rel="nofollow"} to see some more examples of how this component can be used. ::show-case :::docs-tippy-usage-component ::: #code ```vue [DocsTippyUsageComponent.vue] ``` :: #### Additional Props Do note that these additional props can be added to the component | Prop | Type | Default | Description | | --------------- | ----------------- | ------- | --------------------- | | `tag` | String | "span" | Trigger wrapper tag | | `content-tag` | String | "span" | Content wrapper tag | | `content-class` | String | null | Content wrapper class | | `to` | Element or String | null | Target selector | ### Composition API We can import nd use the `useTippy` composable to show a tooltip. This is a low-level, flexible composition, ideal for building tooltips with complex interactions. You can visit the [Composition API Docs](https://vue-tippy.netlify.app/flavor/composition-api){rel="nofollow"} to see some more examples of how this composition can be used. ::show-case :::docs-tippy-usage-composition ::: #code ```vue [DocsTippyUsageComposition.vue] ``` :: ## Vue Tippy Examples Here are some examples taken from the [Vue Tippy](https://vue-tippy.netlify.app/){rel="nofollow"} documentation. ### Follow Mouse This example shows how to create a tooltip that follows the mouse. ::show-case :::docs-tippy-follow-mouse ::: #code ```vue [DocsTippyFollowMouse.vue] ``` :: ### Context Menu This example shows how to create a context menu using Vue Tippy. ::show-case :::docs-tippy-context-menu ::: #code ```vue [DocsTippyContextMenu.vue] ``` :: ### Trigger Target This example shows how to create a tooltip that is triggered by another element. ::show-case :::docs-tippy-target-el ::: #code ```vue [DocsTippyTargetEl.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin Ui](https://originui.com/tooltips){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Title ::show-case :::docs-tippy-title ::: #code ```vue [DocsTippyTitle.vue] ``` :: ### Icon ::show-case :::docs-tippy-icon ::: #code ```vue [DocsTippyIcon.vue] ``` :: ### Image ::show-case :::docs-tippy-image ::: #code ```vue [DocsTippyImage.vue] ``` :: ### Pan ::show-case :::docs-tippy-pan ::: #code ```vue [DocsTippyPan.vue] ``` :: ### Stats ::show-case :::docs-tippy-stats ::: #code ```vue [DocsTippyStats.vue] ``` :: ### Chart ::show-case :::docs-tippy-chart ::: #code ```vue [DocsTippyChart.vue] ``` :: # V-Wave ## Getting Started ::steps :::step ### Installation To get started, you will need to install the package. You can visit the [V-Wave](https://github.com/justintaddei/v-wave){rel="nofollow"} page for more details... All the details 🙂. ```bash npm install v-wave ``` ::: :::step ### Add it to `nuxt.config.ts` Once installed, you can add it to your `nuxt.config.ts` file. ```ts modules: ["v-wave/nuxt"]; ``` ::: :: ## Usage ### Buttons You can add the `v-wave` directive to any button. Be sure to check out the available options in the repo. ::show-case :::docs-v-wave-button ::: #code ```vue [DocsVWaveButton.vue] ``` :: ### Options You can change the color of the ripple effect by passing a color to the directive. Even background images are allowed. ::show-case :::docs-v-wave-color ::: #code ```vue [DocsVWaveColor.vue] ``` :: # Forms Introduction So you may be wondering why I have 2 types of forms in this documentation... In all honesty, I was just following the guys that created shadcn-vue lol. The components created here is how I usually go about creating form elements to be used in my projects. I use the composition API provided by `vee-validate` to compose my reusable form elements and then use the `useForm` composable to do the validation with either `zod` or `yup` schemas. ## Getting Started ::steps :::step ### Installation In order to get this to work in your app, you will need to install the [Vee-Validate Nuxt Module](https://vee-validate.logaretm.com/v4/integrations/nuxt/){rel="nofollow"} ```bash npm i @vee-validate/nuxt ``` ::: :::step ### Add Validation Library You will also need a library that will be used to perform validation. Since `vee-validate` supports `zod`, `yup`, `valibot` and `joi`, you can choose any of these libraries to perform validation. #### Zod ```bash npm i zod @vee-validate/zod ``` #### Yup ```bash npm i yup @vee-validate/yup ``` #### Valibot ```bash npm i valibot @vee-validate/valibot ``` #### Joi ```bash npm i joi @vee-validate/joi ``` ::: :::step ### Update Nuxt Config After that, we will need to add the `@vee-validate/nuxt` module to our `nuxt.config.js` file. ```ts export default defineNuxtConfig({ //... modules: ["@vee-validate/nuxt"], //... }); ``` ::: :: # Form Builder We all know that building forms can be a pain in the butt. I stumbled on this form builder example in the vee-validate documentation and thought that it would be nice to have one of these here as well. ## Getting Started ::steps :::step ### Setup To get started, you need to setup Vee Validate in your Nuxt project. You can do so by following the instructions outline in the [Forms Introduction](https://uithing.com/forms) page. ::: :::step ### Installation Next, you can install the form builder component by running the following command. ```bash npx ui-thing@latest add vee-form-builder ``` ::: :::step ### Use the Form Builder Component Now you can use the form builder component in your project. ```vue ``` ::: :: ## Full Example Here is an example of the component in action. Do note that you can use the `renderIf` prop to conditionally render a field. Also, you can render your own markup by using the `name` of the prop on the object as the slot name. This is demonstrated in the `Conditional & Currency` section of the form. ::show-case :::docs-form-builder-full ::: #code ```vue [DocsFormBuilderFull.vue] ``` :: # VeeVueFormSlider ## Source code Click :source-code-link{component="Vee/VueFormSlider.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-vue-form-slider ``` ## Usage You can visit the [VueForm Slider page](https://github.com/vueform/slider?tab=readme-ov-file#demo){rel="nofollow"} for more information on how to use this component. ### Single Slider ::show-case :::docs-vee-vue-form-slider-single ::: #code ```vue [DocsVeeVueFormSliderSingle.vue] ``` :: ### Multiple Sliders ::show-case :::docs-vee-vue-form-slider-multiple ::: #code ```vue [DocsVeeVueFormSliderMultiple.vue] ``` :: ### Tooltip Formatting ::show-case :::docs-vee-vue-form-slider-tooltip ::: #code ```vue [DocsVeeVueFormSliderTooltip.vue] ``` :: ### Tooltip Merging ::show-case :::docs-vee-vue-form-slider-merging ::: #code ```vue [DocsVeeVueFormSliderMerging.vue] ``` :: ### Vertical Slider ::show-case :::docs-vee-vue-form-slider-vertical ::: #code ```vue [DocsVeeVueFormSliderVertical.vue] ``` :: ### Form Validation ::show-case :::docs-vee-vue-form-slider-validate ::: #code ```vue [DocsVeeVueFormSliderValidate.vue] ``` :: # VeeCheckbox ## Source code Click :source-code-link{component="Vee/Checkbox.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-checkbox ``` ## Usage ### Grouping checkboxes Checkboxes can be tricky to implement with validation libraries. Luckily, Vee-Validate takes care of the heavy lifting for us. Take a look at the [`Building Checkboxes Docs`](https://vee-validate.logaretm.com/v4/guide/composition-api/custom-inputs/#building-checkboxes){rel="nofollow"} for more information on how this works. ::show-case :::docs-vee-checkbox ::: #code ```vue [DocsVeeCheckbox.vue] ``` :: ### Single checkbox ::show-case :::docs-vee-checkbox-single ::: #code ```vue [DocsVeeCheckboxSingle.vue] ``` :: ### Default Value We can use the `v-model` prop to set the default value of the VeeCheckbox. ::show-case :::docs-vee-checkbox-default ::: #code ```vue [DocsVeeCheckboxDefault.vue] ``` :: ## Origin UI Examples These are some examples that I found today over here [Origin UI](https://originui.com/checks-radios-switches){rel="nofollow"}. I think they are cool. To use these examples you will have to copy the code and adjust it for your own use. ### Colored Checkbox ::show-case :::docs-vee-checkbox-colored ::: #code ```vue [DocsVeeCheckboxColored.vue] ``` :: ### Simple Todo ::show-case :::docs-vee-checkbox-simple-todo ::: #code ```vue [DocsVeeCheckboxSimpleTodo.vue] ``` :: ### Fancy Todo ::show-case :::docs-vee-checkbox-fancy-todo ::: #code ```vue [DocsVeeCheckboxFancyTodo.vue] ``` :: ### Terms of Service ::show-case :::docs-vee-checkbox-terms ::: #code ```vue [DocsVeeCheckboxTerms.vue] ``` :: ### Frameworks ::show-case :::docs-vee-checkbox-frameworks ::: #code ```vue [DocsVeeCheckboxFrameworks.vue] ``` :: ### Right Aligned ::show-case :::docs-vee-checkbox-right-aligned ::: #code ```vue [DocsVeeCheckboxRightAligned.vue] ``` :: ### Label w/ Sublabel ::show-case :::docs-vee-checkbox-label-sublabel ::: #code ```vue [DocsVeeCheckboxLabelSublabel.vue] ``` :: ### Input Expansion ::show-case :::docs-vee-checkbox-input-expansion ::: #code ```vue [DocsVeeCheckboxInputExpansion.vue] ``` :: ### Right Aligned w/ Sublabel ::show-case :::docs-vee-checkbox-right-aligned-sublabel ::: #code ```vue [DocsVeeCheckboxRightAlignedSublabel.vue] ``` :: ### Right Aligned w/ Sublabel Bordered ::show-case :::docs-vee-checkbox-right-aligned-sublabel-border ::: #code ```vue [DocsVeeCheckboxRightAlignedSublabelBorder.vue] ``` :: ### Grid Box ::show-case :::docs-vee-checkbox-grid-box ::: #code ```vue [DocsVeeCheckboxGridBox.vue] ``` :: ### Days of the Week ::show-case :::docs-vee-checkbox-days-of-the-week ::: #code ```vue [DocsVeeCheckboxDaysOfTheWeek.vue] ``` :: # Checkbox - Native ## Source code Click :source-code-link{component="Vee/NativeCheckbox.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-native-checkbox ``` ## Why? You may be wondering why this is here. I ran into an issue the other day with how the checkbox from Radix Vue was working with an array of values. This has been fixed with the `CheckboxGroup` component in Reka UI but I am keeping this here anyways 🙂 ## Usage ### Basic ::show-case :::docs-vee-native-checkbox-basic ::: #code ```vue [DocsVeeNativeCheckboxBasic.vue] ``` :: ### Indeterminate ::show-case :::docs-vee-native-checkbox-indeterminate ::: #code ```vue [DocsVeeNativeCheckboxIndeterminate.vue] ``` :: ### Colors ::show-case :::docs-vee-native-checkbox-colors ::: #code ```vue [DocsVeeNativeCheckboxColors.vue] ``` :: ### Sizes ::show-case :::docs-vee-native-checkbox-sizes ::: #code ```vue [DocsVeeNativeCheckboxSizes.vue] ``` :: ### Label Only ::show-case :::docs-vee-native-checkbox-label ::: #code ```vue [DocsVeeNativeCheckboxLabel.vue] ``` :: ### Description Only ::show-case :::docs-vee-native-checkbox-description ::: #code ```vue [DocsVeeNativeCheckboxDescription.vue] ``` :: ### Label & Description ::show-case :::docs-vee-native-checkbox-label-description ::: #code ```vue [DocsVeeNativeCheckboxLabelDescription.vue] ``` :: ### Array of Items ::show-case :::docs-vee-native-checkbox-array ::: #code ```vue [DocsVeeNativeCheckboxArray.vue] ``` :: # VeeCurrencyInput ## Source code Click :source-code-link{component="Vee/CurrencyInput.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-currency-input ``` ## Usage ### User form In the form below, we are using the `useForm` composition function provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `zod` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate and can be passed to the `toTypedSchema` function. ::show-case :::docs-vee-currency-input ::: #code ```vue [DocsVeeCurrencyInput.vue] ``` :: # VeeDateField ## Source code Click :source-code-link{component="Vee/DateField.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-date-field ``` ## Usage ### DOB form In the form below, we are using the `useForm` composition provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `yup` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate and can be passed to the `toTypedSchema` function. ::show-case :::docs-vee-date-field ::: #code ```vue [DocsVeeDateField.vue] ``` :: # VeeDatepicker ## Source code Click :source-code-link{component="Vee/Datepicker.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-datepicker ``` ## Usage ::show-case :::docs-vee-datepicker ::: #code ```vue [DocsVeeDatepicker.vue] ``` :: # VeeFileInput ## Source code Click :source-code-link{component="Vee/FileInput.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-file-input ``` ## Usage ### File upload Why not use the `VeeInput` to accept file uploads? Well, we cannot force select a file from a user's device so the way how data binding works with file inputs and `vee-validate` is a bit different. According to the [docs](https://vee-validate.logaretm.com/v4/api/field#rendering-complex-fields-with-scoped-slots){rel="nofollow"} it is better to use the `handleChange` and `handleBlur` methods to handle the file input changes. ::show-case :::docs-vee-input-files ::: #code ```vue [DocsVeeInputFiles.vue] ``` :: # VeeInput ## Source code Click :source-code-link{component="Vee/Input.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-input ``` ## Usage ### User form In the form below, we are using the `useForm` composition function provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `zod` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate and can be passed to the `toTypedSchema` function. ::show-case :::docs-vee-input ::: #code ```vue [DocsVeeInput.vue] ``` :: ## Origin UI Here we have some examples that come from [Origin UI](https://originui.com/inputs){rel="nofollow"}. Not all examples are copied but these should give you a good idea of what you can do with the `VeeInput` component. ### Required Input ::show-case :::docs-origin-input-required ::: #code ```vue [DocsOriginInputRequired.vue] ``` :: ### Input with Helper Text ::show-case :::docs-origin-input-helper-text ::: #code ```vue [DocsOriginInputHelperText.vue] ``` :: ### Input with label hint ::show-case :::docs-origin-input-label-hint ::: #code ```vue [DocsOriginInputLabelHint.vue] ``` :: ### Input with Colored Ring ::show-case :::docs-origin-input-colored-border ::: #code ```vue [DocsOriginInputColoredBorder.vue] ``` :: ### Input with Gray Background ::show-case :::docs-origin-input-gray-bg ::: #code ```vue [DocsOriginInputGrayBg.vue] ``` :: ### Disabled Input ::show-case :::docs-origin-input-disabled ::: #code ```vue [DocsOriginInputDisabled.vue] ``` :: ### Input with Start Icon ::show-case :::docs-origin-input-start-icon ::: #code ```vue [DocsOriginInputStartIcon.vue] ``` :: ### Input with End Icon ::show-case :::docs-origin-input-end-icon ::: #code ```vue [DocsOriginInputEndIcon.vue] ``` :: ### Input with Start Inline Addon ::show-case :::docs-origin-input-start-inline-add-on ::: #code ```vue [DocsOriginInputStartInlineAddOn.vue] ``` :: ### Input with End Inline Addon ::show-case :::docs-origin-input-end-inline-add-on ::: #code ```vue [DocsOriginInputEndInlineAddOn.vue] ``` :: ### Input with Inline Addons ::show-case :::docs-origin-input-inline-add-ons ::: #code ```vue [DocsOriginInputInlineAddOns.vue] ``` :: ### Input with Start Addon ::show-case :::docs-origin-input-start-addon ::: #code ```vue [DocsOriginInputStartAddon.vue] ``` :: ### Input with End Addon ::show-case :::docs-origin-input-end-addon ::: #code ```vue [DocsOriginInputEndAddon.vue] ``` :: ### Input with Inline Start & End Addon ::show-case :::docs-origin-input-inline-start-end-addon ::: #code ```vue [DocsOriginInputInlineStartEndAddon.vue] ``` :: ### Input with Start Select ::show-case :::docs-origin-input-start-select ::: #code ```vue [DocsOriginInputStartSelect.vue] ``` :: ### Input with End Select ::show-case :::docs-origin-input-end-select ::: #code ```vue [DocsOriginInputEndSelect.vue] ``` :: ### Input with End Inline Button ::show-case :::docs-origin-input-end-inline-button ::: #code ```vue [DocsOriginInputEndInlineButton.vue] ``` :: ### Input with End Icon Button ::show-case :::docs-origin-input-end-icon-button ::: #code ```vue [DocsOriginInputEndIconButton.vue] ``` :: ### Input with End Button ::show-case :::docs-origin-input-end-button ::: #code ```vue [DocsOriginInputEndButton.vue] ``` :: ### Input with Button ::show-case :::docs-origin-input-with-button ::: #code ```vue [DocsOriginInputWithButton.vue] ``` :: ### Input with Show/Hide Password ::show-case :::docs-origin-input-show-hide-password ::: #code ```vue [DocsOriginInputShowHidePassword.vue] ``` :: ### Input with Clear Button ::show-case :::docs-origin-input-clear-button ::: #code ```vue [DocsOriginInputClearButton.vue] ``` :: ### Input with \ ::show-case :::docs-origin-input-with-k-d-b ::: #code ```vue [DocsOriginInputWithKDB.vue] ``` :: ### Search Input with Icon & Button ::show-case :::docs-origin-input-search-with-icon-button ::: #code ```vue [DocsOriginInputSearchWithIconButton.vue] ``` :: ### Search Input with Loader Icon ::show-case :::docs-origin-input-search-with-loader ::: #code ```vue [DocsOriginInputSearchWithLoader.vue] ``` :: ### Input with Overlapping Label ::show-case :::docs-origin-input-overlapping-label ::: #code ```vue [DocsOriginInputOverlappingLabel.vue] ``` :: ### Input with Password Strength Indicator ::show-case :::docs-origin-input-password-strength-indicator ::: #code ```vue [DocsOriginInputPasswordStrengthIndicator.vue] ``` :: # VeeMultiSelect ## Source code Click :source-code-link{component="Vee/Multiselect.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-multi-select ``` ## Usage You can visit the [VueForm Multiselect page](https://www.npmjs.com/package/@vueform/multiselect#demo){rel="nofollow"} for more information on how to use this component. ### Objects ::show-case :::docs-vee-multiselect-object ::: #code ```vue [DocsVeeMultiselectObject.vue] ``` :: ### Groups ::show-case :::docs-vee-multiselect-group ::: #code ```vue [DocsVeeMultiselectGroup.vue] ``` :: ### Search ::show-case :::docs-vee-multiselect-search ::: #code ```vue [DocsVeeMultiselectSearch.vue] ``` :: ### Tags w/ Search & Create ::show-case :::docs-multiselect-tags-search-create ::: #code ```vue [DocsMultiselectTagsSearchCreate.vue] ``` :: ### Autocomplete w/ Async ::show-case :::docs-multiselect-autocomplete-async ::: #code ```vue [DocsMultiselectAutocompleteAsync.vue] ``` :: # VeeNumberField ## Source code Click :source-code-link{component="Vee/NumberField.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-number-field ``` ## Usage ### User form In the form below, we are using the `useForm` composition function provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `yup` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate. ::show-case :::docs-vee-number-field ::: #code ```vue [DocsVeeNumberField.vue] ``` :: # VeePinInput ## Source code Click :source-code-link{component="Vee/PinInput.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-pin-input ``` ## Usage ### User form In the form below, we are using the `useForm` composition function provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `zod` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate and can be passed to the `toTypedSchema` function. ::show-case :::docs-vee-pin-input ::: #code ```vue [DocsVeePinInput.vue] ``` :: # VeeRadioGroup ## Source code Click :source-code-link{component="Vee/RadioGroup.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-radio-group ``` ## Usage ### Notification type In the form below, we are using the `` component to create a radio group that allows the user to select how they want to be notified. The component uses the composition API provided by Vee-Validate to perform validation. Notice that we pass the different `RadioItems` into the default slot of the component. ::show-case :::docs-vee-radio-group ::: #code ```vue [DocsVeeRadioGroup.vue] ``` :: # VeeSelect ## Source code Click :source-code-link{component="Vee/Select.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-select ``` ## Usage ### Form In the form below, we are using the `useForm` composition function provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `zod` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate and can be passed to the `toTypedSchema` function. ::show-case :::docs-vee-select ::: #code ```vue [DocsVeeSelect.vue] ``` :: # VeeTagsInput ## Source code Click :source-code-link{component="Vee/TagsInput.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-tags-input ``` ## Usage In the form below, we are using the `useForm` composition function provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `zod` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate and can be passed to the `toTypedSchema` function. ::show-case :::docs-vee-tags-input ::: #code ```vue [DocsVeeTagsInput.vue] ``` :: # VeeTextarea ## Source code Click :source-code-link{component="Vee/Textarea.vue"} to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use. ## Installation ```bash npx ui-thing@latest add vee-textarea ``` ## Usage ### Form In the form below, we are using the `useForm` composition function provided by Vee-Validate to handle the form submission and validation. The `useForm` composable accepts a `validationSchema` option that we can use to define our validation rules. We are using the `zod` library to define our validation rules. You can use any validation library you want as long as it is supported by Vee-Validate and can be passed to the `toTypedSchema` function. ::show-case :::docs-vee-textarea ::: #code ```vue [DocsVeeTextarea.vue] ``` :: # ApexCharts ApexCharts is a modern charting library that helps developers to create beautiful and interactive visualizations for web pages. It is highly customizable and supports a wide range of chart types, making it a great choice for data visualization in web applications. ## Getting Started ::steps :::step ### Create the component Start by adding the following code to your project. Preferably in the components folder. ```vue [Apexchart.client.vue] ``` ::: :: # Area ### Interactive ::show-case :::docs-apex-charts-area-interactive ::: #code ```vue [DocsApexChartsAreaInteractive.vue] ``` :: ### Area Chart ::show-case :::docs-apex-charts-area1 ::: #code ```vue [DocsApexChartsArea1.vue] ``` :: ### Area Chart - Linear ::show-case :::docs-apex-charts-area2 ::: #code ```vue [DocsApexChartsArea2.vue] ``` :: ### Area Chart - Step Line ::show-case :::docs-apex-charts-area3 ::: #code ```vue [DocsApexChartsArea3.vue] ``` :: ### Area Chart - Legend ::show-case :::docs-apex-charts-area4 ::: #code ```vue [DocsApexChartsArea4.vue] ``` :: ### Area Chart - Custom Marker ::show-case :::docs-apex-charts-area5 ::: #code ```vue [DocsApexChartsArea5.vue] ``` :: ### Area Chart - Gradient ::show-case :::docs-apex-charts-area6 ::: #code ```vue [DocsApexChartsArea6.vue] ``` :: ### Area Chart - Axes ::show-case :::docs-apex-charts-area7 ::: #code ```vue [DocsApexChartsArea7.vue] ``` :: ### Area Chart - Annotations ::show-case :::docs-apex-charts-area8 ::: #code ```vue [DocsApexChartsArea8.vue] ``` :: ### Area Chart - Custom Tooltip ::show-case :::docs-apex-charts-area9 ::: #code ```vue [DocsApexChartsArea9.vue] ``` :: ### Area Chart - Toolbar ::show-case :::docs-apex-charts-area10 ::: #code ```vue [DocsApexChartsArea10.vue] ``` :: ### Area Chart - Sparkline ::show-case :::docs-apex-charts-area11 ::: #code ```vue [DocsApexChartsArea11.vue] ``` :: # Bar ### Interactive ::show-case :::docs-apex-charts-bar1 ::: #code ```vue [DocsApexChartsBar1.vue] ``` :: ### Bar Chart ::show-case :::docs-apex-charts-bar2 ::: #code ```vue [DocsApexChartsBar2.vue] ``` :: ### Bar Chart - Horizontal ::show-case :::docs-apex-charts-bar3 ::: #code ```vue [DocsApexChartsBar3.vue] ``` :: ### Bar Chart - Multiple ::show-case :::docs-apex-charts-bar4 ::: #code ```vue [DocsApexChartsBar4.vue] ``` :: ### Bar Chart - Stacked ::show-case :::docs-apex-charts-bar5 ::: #code ```vue [DocsApexChartsBar5.vue] ``` :: ### Bar Chart - Label ::show-case :::docs-apex-charts-bar6 ::: #code ```vue [DocsApexChartsBar6.vue] ``` :: ### Bar Chart - Mixed ::show-case :::docs-apex-charts-bar7 ::: #code ```vue [DocsApexChartsBar7.vue] ``` :: ### Bar Chart - Negative ::show-case :::docs-apex-charts-bar8 ::: #code ```vue [DocsApexChartsBar8.vue] ``` :: ### Bar Chart - Image ::show-case :::docs-apex-charts-bar9 ::: #code ```vue [DocsApexChartsBar9.vue] ``` :: # Candlestick ### Candlestick Chart ::show-case :::docs-apex-charts-candlestick1 ::: #code ```vue [DocsApexChartsCandlestick1.vue] ``` :: # Funnel ### Funnel Chart ::show-case :::docs-apex-charts-funnel1 ::: #code ```vue [DocsApexChartsFunnel1.vue] ``` :: ### Funnel Chart - Inverted ::show-case :::docs-apex-charts-funnel2 ::: #code ```vue [DocsApexChartsFunnel2.vue] ``` :: # Heatmap ### Heatmap Chart ::show-case :::docs-apex-charts-heatmap1 ::: #code ```vue [DocsApexChartsHeatmap1.vue] ``` :: ### Heatmap Chart - Color Range ::show-case :::docs-apex-charts-heatmap2 ::: #code ```vue [DocsApexChartsHeatmap2.vue] ``` :: # Line ### Interactive ::show-case :::docs-apex-charts-line1 ::: #code ```vue [DocsApexChartsLine1.vue] ``` :: ### Line Chart ::show-case :::docs-apex-charts-line2 ::: #code ```vue [DocsApexChartsLine2.vue] ``` :: ### Line Chart - Linear ::show-case :::docs-apex-charts-line3 ::: #code ```vue [DocsApexChartsLine3.vue] ``` :: ### Line Chart - Multiple ::show-case :::docs-apex-charts-line4 ::: #code ```vue [DocsApexChartsLine4.vue] ``` :: ### Line Chart - Step Line ::show-case :::docs-apex-charts-line5 ::: #code ```vue [DocsApexChartsLine5.vue] ``` :: ### Line Chart - Label ::show-case :::docs-apex-charts-line6 ::: #code ```vue [DocsApexChartsLine6.vue] ``` :: ### Line Chart - Custom Label ::show-case :::docs-apex-charts-line7 ::: #code ```vue [DocsApexChartsLine7.vue] ``` :: ### Line Chart - Negative ::show-case :::docs-apex-charts-line8 ::: #code ```vue [DocsApexChartsLine8.vue] ``` :: # Pie / Donut ### Pie Chart ::show-case :::docs-apex-charts-pie-donut1 ::: #code ```vue [DocsApexChartsPieDonut1.vue] ``` :: ### Pie Chart - Labels ::show-case :::docs-apex-charts-pie-donut2 ::: #code ```vue [DocsApexChartsPieDonut2.vue] ``` :: ### Pie Chart - Legend ::show-case :::docs-apex-charts-pie-donut3 ::: #code ```vue [DocsApexChartsPieDonut3.vue] ``` :: ### Donut Chart - Labels ::show-case :::docs-apex-charts-pie-donut4 ::: #code ```vue [DocsApexChartsPieDonut4.vue] ``` :: ### Donut Chart - Inner Text ::show-case :::docs-apex-charts-pie-donut5 ::: #code ```vue [DocsApexChartsPieDonut5.vue] ``` :: ### Donut Chart - Semi ::show-case :::docs-apex-charts-pie-donut6 ::: #code ```vue [DocsApexChartsPieDonut6.vue] ``` :: ### Donut Chart - Gradient ::show-case :::docs-apex-charts-pie-donut7 ::: #code ```vue [DocsApexChartsPieDonut7.vue] ``` :: ### Pie Chart - Images ::show-case :::docs-apex-charts-pie-donut8 ::: #code ```vue [DocsApexChartsPieDonut8.vue] ``` :: # Polar Area ### Polar Area Chart ::show-case :::docs-apex-charts-polar-area1 ::: #code ```vue [DocsApexChartsPolarArea1.vue] ``` :: ### Polar Area Chart - No Lines ::show-case :::docs-apex-charts-polar-area2 ::: #code ```vue [DocsApexChartsPolarArea2.vue] ``` :: ### Polar Area Chart - Rings ::show-case :::docs-apex-charts-polar-area3 ::: #code ```vue [DocsApexChartsPolarArea3.vue] ``` :: ### Polar Area Chart - Legend ::show-case :::docs-apex-charts-polar-area4 ::: #code ```vue [DocsApexChartsPolarArea4.vue] ``` :: ### Polar Area Chart - Labels ::show-case :::docs-apex-charts-polar-area5 ::: #code ```vue [DocsApexChartsPolarArea5.vue] ``` :: # Radar ### Radar Chart ::show-case :::docs-apex-charts-radar1 ::: #code ```vue [DocsApexChartsRadar1.vue] ``` :: ### Radar Chart - Lines Only ::show-case :::docs-apex-charts-radar2 ::: #code ```vue [DocsApexChartsRadar2.vue] ``` :: ### Radar Chart - Labels ::show-case :::docs-apex-charts-radar3 ::: #code ```vue [DocsApexChartsRadar3.vue] ``` :: ### Radar Chart - No Grid Lines ::show-case :::docs-apex-charts-radar4 ::: #code ```vue [DocsApexChartsRadar4.vue] ``` :: ### Radar Chart - Grid Filled ::show-case :::docs-apex-charts-radar5 ::: #code ```vue [DocsApexChartsRadar5.vue] ``` :: # Radial ### Radial Chart ::show-case :::docs-apex-charts-radial1 ::: #code ```vue [DocsApexChartsRadial1.vue] ``` :: ### Radial Chart - Bar Labels ::show-case :::docs-apex-charts-radial2 ::: #code ```vue [DocsApexChartsRadial2.vue] ``` :: ### Radial Chart - Custom Text ::show-case :::docs-apex-charts-radial3 ::: #code ```vue [DocsApexChartsRadial3.vue] ``` :: ### Radial Chart - Expanded Section ::show-case :::docs-apex-charts-radial4 ::: #code ```vue [DocsApexChartsRadial4.vue] ``` :: # Slope ### Slope Chart ::show-case :::docs-apex-charts-slope1 ::: #code ```vue [DocsApexChartsSlope1.vue] ``` :: # Treemaps ### Treemap Chart ::show-case :::docs-apex-charts-treemap1 ::: #code ```vue [DocsApexChartsTreemap1.vue] ``` :: ### Treemap Chart - Multiple ::show-case :::docs-apex-charts-treemap2 ::: #code ```vue [DocsApexChartsTreemap2.vue] ``` :: ### Treemap Chart - Color Ranges ::show-case :::docs-apex-charts-treemap3 ::: #code ```vue [DocsApexChartsTreemap3.vue] ``` :: # About ## Simple Centered Clean, centered layout with company description and mission statement. ::block-showcase --- block-path: About/BlockAbout1 component: BlockAbout1 components: container --- :: ## Team Grid Grid layout showcasing team members with photos, names, and roles. ::block-showcase --- block-path: About/BlockAbout2 component: BlockAbout2 components: avatar iframe-height: 700px --- :: ## Story Timeline Timeline-based layout telling your company's story with key milestones. ::block-showcase --- block-path: About/BlockAbout3 component: BlockAbout3 components: badge iframe-height: 800px --- :: ## Two Column Split layout with company image on one side and description on the other. ::block-showcase --- block-path: About/BlockAbout4 component: BlockAbout4 iframe-height: 600px --- :: ## Stats Highlight About section featuring key statistics and achievements with prominent numbers. ::block-showcase --- block-path: About/BlockAbout5 component: BlockAbout5 components: card iframe-height: 700px --- :: ## Values Grid Grid showcasing company values with icons and descriptions. ::block-showcase --- block-path: About/BlockAbout6 component: BlockAbout6 iframe-height: 700px --- :: ## Leadership Team Focused layout highlighting leadership team with detailed bios. ::block-showcase --- block-path: About/BlockAbout7 component: BlockAbout7 components: avatar card badge iframe-height: 800px --- :: ## Mission Vision Side-by-side cards displaying mission and vision statements. ::block-showcase --- block-path: About/BlockAbout8 component: BlockAbout8 components: card border-beam iframe-height: 600px --- :: ## Image Gallery About section with image gallery showcasing office, team, or culture. ::block-showcase --- block-path: About/BlockAbout9 component: BlockAbout9 iframe-height: 800px --- :: ## Culture & Values Comprehensive section highlighting company culture and core values. ::block-showcase --- block-path: About/BlockAbout10 component: BlockAbout10 components: card badge iframe-height: 900px --- :: ## Testimonials About section featuring client or employee testimonials with photos. ::block-showcase --- block-path: About/BlockAbout11 component: BlockAbout11 components: avatar card iframe-height: 700px --- :: ## Journey Map Visual journey map showing company evolution with interactive elements. ::block-showcase --- block-path: About/BlockAbout12 component: BlockAbout12 components: badge card iframe-height: 800px --- :: ## Meet the Founders Dedicated section for founder stories with personal narratives. ::block-showcase --- block-path: About/BlockAbout13 component: BlockAbout13 components: button badge iframe-height: 800px --- :: ## Office Locations Multi-location display with addresses and contact information. ::block-showcase --- block-path: About/BlockAbout14 component: BlockAbout14 components: card badge button iframe-height: 700px --- :: ## Awards & Recognition Showcase of company awards, certifications, and achievements. ::block-showcase --- block-path: About/BlockAbout15 component: BlockAbout15 components: badge card iframe-height: 700px --- :: ## Team Carousel Carousel-style team showcase with smooth transitions. **Requires:** Nuxt Swiper module. ::block-showcase --- block-path: About/BlockAbout16 component: BlockAbout16 components: button card iframe-height: 700px --- :: ## Split Content Alternating content and image sections for storytelling. ::block-showcase --- block-path: About/BlockAbout17 component: BlockAbout17 components: badge iframe-height: 900px --- :: ## FAQ About Combined about section with frequently asked questions. ::block-showcase --- block-path: About/BlockAbout18 component: BlockAbout18 components: collapsible card button iframe-height: 800px --- :: ## Contact Integrated About section with integrated contact form and information. ::block-showcase --- block-path: About/BlockAbout19 component: BlockAbout19 components: vee-input card vee-textarea button iframe-height: 800px --- :: ## Full Page Comprehensive full-page about layout combining multiple elements. ::block-showcase --- block-path: About/BlockAbout20 component: BlockAbout20 components: avatar badge card button iframe-height: 1200px --- :: # App - Empty State ## Style One ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState1 component: BlockAppEmptyState1 components: container button fancy-icon container-class: max-w-2xl mx-auto iframe-height: 400px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState1.vue language: vue title: Style One --- ::: :: ## Style Two ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState2 component: BlockAppEmptyState2 components: button container-class: max-w-md mx-auto iframe-height: 400px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState2.vue language: vue title: Style Two --- ::: :: ## Style Three ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState3 component: BlockAppEmptyState3 components: button container-class: max-w-md mx-auto iframe-height: 400px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState3.vue language: vue title: Style Three --- ::: :: ## Style Four ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState4 component: BlockAppEmptyState4 components: card button border-beam container-class: max-w-lg mx-auto iframe-height: 500px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState4.vue language: vue title: Card with Animation --- ::: :: ## Style Five ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState5 component: BlockAppEmptyState5 components: button container-class: max-w-2xl mx-auto iframe-height: 600px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState5.vue language: vue title: Animated Grid Layout --- ::: :: ## Style Six ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState6 component: BlockAppEmptyState6 components: button border-beam container-class: max-w-md mx-auto iframe-height: 600px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState6.vue language: vue title: Upload State with Features --- ::: :: ## Style Seven ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState7 component: BlockAppEmptyState7 components: card container-class: max-w-xl mx-auto iframe-height: 500px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState7.vue language: vue title: Two-Card Choice Layout --- ::: :: ## Style Eight ::block-showcase --- block-path: App/EmptyState/BlockAppEmptyState8 component: BlockAppEmptyState8 components: button gradient-divider container-class: max-w-md mx-auto iframe-height: 500px --- :::prose-code-snippet --- file: /components/content/Block/App/EmptyState/BlockAppEmptyState8.vue language: vue title: Setup Steps with Spinner --- ::: :: # App - Header ## Style One Profile header with cover image, breadcrumbs, avatar, and action buttons. Perfect for user profile pages. ::block-showcase --- block-path: App/Header/BlockAppHeader1 component: BlockAppHeader1 components: container breadcrumbs avatar button divider iframe-height: 500px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader1.vue language: vue title: Style One --- ::: :: ## Style Two Simple header with avatar, title, description, and action buttons. Great for team or list pages. ::block-showcase --- block-path: App/Header/BlockAppHeader2 component: BlockAppHeader2 components: container avatar button iframe-height: 200px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader2.vue language: vue title: Style Two --- ::: :: ## Style Three Minimal header with title, description, and action buttons. Clean layout for content pages. ::block-showcase --- block-path: App/Header/BlockAppHeader3 component: BlockAppHeader3 components: container button divider iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader3.vue language: vue title: Style Three --- ::: :: ## Style Four Header with icon, badge, description, and multiple action buttons. Ideal for dashboard overviews. ::block-showcase --- block-path: App/Header/BlockAppHeader4 component: BlockAppHeader4 components: container badge button divider iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader4.vue language: vue title: Style Four --- ::: :: ## Style Five Header with breadcrumbs, tabs, and dropdown menu. Perfect for complex navigation structures. ::block-showcase --- block-path: App/Header/BlockAppHeader5 component: BlockAppHeader5 components: container breadcrumbs tabs button dropdown-menu iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader5.vue language: vue title: Style Five --- ::: :: ## Style Six Profile header with avatar, stats metadata, and tab navigation. Great for user profiles with activity tracking. ::block-showcase --- block-path: App/Header/BlockAppHeader6 component: BlockAppHeader6 components: container avatar separator tabs button iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader6.vue language: vue title: Style Six --- ::: :: ## Style Seven Project header with status badge, metadata (owner, members, due date), and action buttons. Ideal for project management. ::block-showcase --- block-path: App/Header/BlockAppHeader7 component: BlockAppHeader7 components: container badge avatar separator button divider iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader7.vue language: vue title: Style Seven --- ::: :: ## Style Eight Edit page header with back button, subtitle, and save/cancel actions. Perfect for form pages. ::block-showcase --- block-path: App/Header/BlockAppHeader8 component: BlockAppHeader8 components: container button separator dropdown-menu iframe-height: 400px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader8.vue language: vue title: Style Eight --- ::: :: ## Style Nine List header with inline statistics, search input, and filter actions. Great for data-heavy pages. ::block-showcase --- block-path: App/Header/BlockAppHeader9 component: BlockAppHeader9 components: container separator vee-input button iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader9.vue language: vue title: Style Nine --- ::: :: ## Style Ten Application header with gradient background, large icon, technology chips, and tab navigation. Perfect for project/app details. ::block-showcase --- block-path: App/Header/BlockAppHeader10 component: BlockAppHeader10 components: container chip badge tabs button iframe-height: 400px --- :::prose-code-snippet --- file: /components/content/Block/App/Header/BlockAppHeader10.vue language: vue title: Style Ten --- ::: :: # App - Sidebar ## Style One Full-width sidebar with collapsible navigation groups, search input, storage usage card, and user profile. Features nested navigation items. ::block-showcase --- block-path: App/Sidebar/BlockAppSidebar1 component: BlockAppSidebar1 components: scroll-area avatar vee-input button collapsible progress divider tooltip --- :::prose-code-snippet --- file: /components/content/Block/App/Sidebar/BlockAppSidebar1.vue language: vue title: Style One --- ::: :: ## Style Two Dual-panel sidebar with primary navigation and expandable secondary panel. Features slide-out mini sidebar for sub-items. ::block-showcase --- block-path: App/Sidebar/BlockAppSidebar2 component: BlockAppSidebar2 components: scroll-area avatar vee-input button progress divider tooltip --- :::prose-code-snippet --- file: /components/content/Block/App/Sidebar/BlockAppSidebar2.vue language: vue title: Style Two --- ::: :: ## Style Three Collapsible icon-only sidebar that expands on hover. Minimal design with tooltips for navigation labels. Perfect for maximizing content space. ::block-showcase --- block-path: App/Sidebar/BlockAppSidebar3 component: BlockAppSidebar3 components: scroll-area avatar button divider --- :::prose-code-snippet --- file: /components/content/Block/App/Sidebar/BlockAppSidebar3.vue language: vue title: Style Three --- ::: :: ## Style Four Organized sidebar with categorized sections, notification badges, and colored workspace indicators. Features smooth slide-in animations. ::block-showcase --- block-path: App/Sidebar/BlockAppSidebar4 component: BlockAppSidebar4 components: scroll-area avatar vee-input button badge dropdown-menu --- :::prose-code-snippet --- file: /components/content/Block/App/Sidebar/BlockAppSidebar4.vue language: vue title: Style Four --- ::: :: ## Style Five Sidebar with quick action buttons, multiple navigation sections, and storage usage indicator. Includes collapsible groups and nested items. ::block-showcase --- block-path: App/Sidebar/BlockAppSidebar5 component: BlockAppSidebar5 components: scroll-area avatar button border-beam badge collapsible progress dropdown-menu --- :::prose-code-snippet --- file: /components/content/Block/App/Sidebar/BlockAppSidebar5.vue language: vue title: Style Five --- ::: :: ## Style Six Two-tier navigation with icon sidebar and expandable detail panel. Features contextual content based on selected section with animated transitions. ::block-showcase --- block-path: App/Sidebar/BlockAppSidebar6 component: BlockAppSidebar6 components: scroll-area avatar vee-input button tooltip dropdown-menu divider --- :::prose-code-snippet --- file: /components/content/Block/App/Sidebar/BlockAppSidebar6.vue language: vue title: Style Six --- ::: :: ## Style Seven Project-focused sidebar with tabs for recent, starred, and all projects. Features color-coded projects, star functionality, and quick links section. ::block-showcase --- block-path: App/Sidebar/BlockAppSidebar7 component: BlockAppSidebar7 components: button scroll-area avatar dropdown-menu vee-input tabs divider --- :::prose-code-snippet --- file: /components/content/Block/App/Sidebar/BlockAppSidebar7.vue language: vue title: Style Seven --- ::: :: # App - Stats ## Style One ::block-showcase --- block-path: App/Stats/BlockAppStats1 component: BlockAppStats1 components: card button dropdown-menu badge fancy-icon container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats1.vue language: vue title: Stat Card with Icon --- ::: :: ## Style Two ::block-showcase --- block-path: App/Stats/BlockAppStats2 component: BlockAppStats2 components: card container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats2.vue language: vue title: Stat Card with Icon Right Aligned --- ::: :: ## Style Three ::block-showcase --- block-path: App/Stats/BlockAppStats3 component: BlockAppStats3 components: card badge progress container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats3.vue language: vue title: Stat Card with Progress Bar --- ::: :: ## Style Four ::block-showcase --- block-path: App/Stats/BlockAppStats4 component: BlockAppStats4 components: card badge container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats4.vue language: vue title: Stat Card with Left Accent Color --- ::: :: ## Style Five ::block-showcase --- block-path: App/Stats/BlockAppStats5 component: BlockAppStats5 components: card button dropdown-menu container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats5.vue language: vue title: Style Five --- ::: :: ## Style Six ::block-showcase --- block-path: App/Stats/BlockAppStats6 component: BlockAppStats6 components: card fancy-icon separator container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats6.vue language: vue title: Style Six --- ::: :: ## Style Seven ::block-showcase --- block-path: App/Stats/BlockAppStats7 component: BlockAppStats7 components: card container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats7.vue language: vue title: Style Seven --- ::: :: ## Style Eight ::block-showcase --- block-path: App/Stats/BlockAppStats8 component: BlockAppStats8 components: card container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats8.vue language: vue title: Style Eight --- ::: :: ## Style Nine ::block-showcase --- block-path: App/Stats/BlockAppStats9 component: BlockAppStats9 components: card button avatar chip badge container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats9.vue language: vue title: Style Nine --- ::: :: ## Style Ten ::block-showcase --- block-path: App/Stats/BlockAppStats10 component: BlockAppStats10 components: card progress container-class: max-w-md mx-auto frame-class: py-5 px-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/App/Stats/BlockAppStats10.vue language: vue title: Style Ten --- ::: :: # Banner ## Style One Newsletter subscription banner with email input and call-to-action button. Perfect for email capture campaigns. ::block-showcase --- block-path: Banner/BlockBanner1 component: BlockBanner1 components: container button vee-input frame-class: p-1 iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner1.vue language: vue title: Style One --- ::: :: ## Style Two Compact announcement banner with icon and action button. Ideal for product updates and news. ::block-showcase --- block-path: Banner/BlockBanner2 component: BlockBanner2 components: container button frame-class: p-1 iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner2.vue language: vue title: Style Two --- ::: :: ## Style Three Cookie consent banner with accept/decline options. Essential for GDPR compliance. ::block-showcase --- block-path: Banner/BlockBanner3 component: BlockBanner3 components: container button frame-class: p-1 iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner3.vue language: vue title: Style Three --- ::: :: ## Style Four Minimal notification banner with simple message and dismiss button. Clean and unobtrusive. ::block-showcase --- block-path: Banner/BlockBanner4 component: BlockBanner4 components: container button frame-class: p-1 iframe-height: 200px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner4.vue language: vue title: Style Four --- ::: :: ## Style Five Feature announcement banner with gradient background, animated icon, and dual action buttons. Eye-catching design with smooth entrance animations. ::block-showcase --- block-path: Banner/BlockBanner5 component: BlockBanner5 components: container button frame-class: p-1 iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner5.vue language: vue title: Style Five --- ::: :: ## Style Six Premium upgrade banner with feature highlights, badge, and progress indicator. Highlights key benefits with staggered animations. ::block-showcase --- block-path: Banner/BlockBanner6 component: BlockBanner6 components: button badge frame-class: p-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner6.vue language: vue title: Style Six --- ::: :: ## Style Seven System maintenance alert banner with warning icon, metadata, and action buttons. Perfect for status updates and scheduled events. ::block-showcase --- block-path: Banner/BlockBanner7 component: BlockBanner7 components: container button separator frame-class: p-1 iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner7.vue language: vue title: Style Seven --- ::: :: ## Style Eight Promotional banner with animated progress bar, badge, and trending indicators. Creates urgency with visual countdown. ::block-showcase --- block-path: Banner/BlockBanner8 component: BlockBanner8 components: button badge frame-class: p-1 iframe-height: 250px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner8.vue language: vue title: Style Eight --- ::: :: ## Style Nine Notification center banner with count badge, timestamp, and multiple action buttons. Perfect for updates and alerts. ::block-showcase --- block-path: Banner/BlockBanner9 component: BlockBanner9 components: container button frame-class: py-5 p-1 iframe-height: 300px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner9.vue language: vue title: Style Nine --- ::: :: ## Style Ten Sale event banner with statistics, badge variants, and detailed information. Ideal for e-commerce promotions and limited-time offers. ::block-showcase --- block-path: Banner/BlockBanner10 component: BlockBanner10 components: button frame-class: p-1 iframe-height: 350px --- :::prose-code-snippet --- file: /components/content/Block/Banner/BlockBanner10.vue language: vue title: Style Ten --- ::: :: # Blog - Page ## Style One Full blog page with category filter tabs and featured hero post. Features left-aligned header, staggered animations, and three-column responsive grid. ::block-showcase --- block-path: Blog/Page/BlockBlogPage1 component: BlockBlogPage1 components: container avatar badge tabs --- :: ## Style Two Blog page with sticky sidebar navigation and search functionality. Features centered header, category links, and two-column article layout. ::block-showcase --- block-path: Blog/Page/BlockBlogPage2 component: BlockBlogPage2 components: container avatar badge input --- :: ## Style Three Newsletter-integrated blog page with subscription form and tag-based filtering. Features centered header, inline email signup, and three-column grid with animated tags. ::block-showcase --- block-path: Blog/Page/BlockBlogPage3 component: BlockBlogPage3 components: container badge input button --- :: ## Style Four Minimal search-focused blog page with trending topics. Features large search bar, trending topic chips, horizontal dividers, and clean two-column article list. ::block-showcase --- block-path: Blog/Page/BlockBlogPage4 component: BlockBlogPage4 components: container avatar chip input button divider --- :: ## Style Five Magazine-style blog page with featured grid layout and statistics. Features large featured post, trending sidebar, author cards, sort dropdown, and mixed grid layout. ::block-showcase --- block-path: Blog/Page/BlockBlogPage5 component: BlockBlogPage5 components: container avatar badge card dropdown-menu button --- :: ## Style Six Premium dark theme blog page with gradient header and featured authors. Features animated gradient blobs, author spotlight cards, enhanced hover effects, engagement metrics, and pagination. ::block-showcase --- block-path: Blog/Page/BlockBlogPage6 component: BlockBlogPage6 components: container avatar badge card tabs button divider pagination --- :: # Blog - Card ## Style One Classic vertical card with smooth image scale, staggered content reveal, and author profile section. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard1 component: BlockBlogPostCard1 components: avatar container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 550px --- :: ## Style Two Modern card with sharp edges, outlined badge with read time, and slide-in animations from the left. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard2 component: BlockBlogPostCard2 components: badge avatar container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 550px --- :: ## Style Three Tag-focused card with multiple category badges and date integration in headline. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard3 component: BlockBlogPostCard3 components: badge container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 550px --- :: ## Style Four Horizontal layout card with side-by-side image and content, perfect for list views. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard4 component: BlockBlogPostCard4 components: avatar container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 550px --- :: ## Style Five Premium card with gradient overlay on hover, arrow icon indicator, and bordered design. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard5 component: BlockBlogPostCard5 components: badge avatar container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 650px --- :: ## Style Six Horizontal featured card with metadata icons, read more button, and image hover effects. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard6 component: BlockBlogPostCard6 components: badge avatar button container-class: max-w-2xl mx-auto py-10 frame-class: px-1 iframe-height: 400px --- :: ## Style Seven Gradient-bordered card with staggered tag animations, center arrow on hover, and bookmark icon. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard7 component: BlockBlogPostCard7 components: badge avatar button container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 600px --- :: ## Style Eight Interactive card with social engagement metrics (views, comments), action buttons, and gradient hover effect. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard8 component: BlockBlogPostCard8 components: badge avatar button container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 650px --- :: ## Style Nine Compact card with engagement stats (likes, bookmarks), divider separator, and corner arrow icon animation. ::block-showcase --- block-path: Blog/Post/BlockBlogPostCard9 component: BlockBlogPostCard9 components: badge avatar divider container-class: max-w-md mx-auto py-10 frame-class: px-1 iframe-height: 600px --- :: # Blog - Section ## Style One Classic three-column grid with centered header, author avatars, and staggered card animations. Features responsive layout with mobile-first design. ::block-showcase --- block-path: Blog/Section/BlockBlogSection1 component: BlockBlogSection1 components: container avatar button --- :: ## Style Two Clean two-column grid layout with left-aligned header and tag-based filtering. Includes category badges and "View all posts" action button. ::block-showcase --- block-path: Blog/Section/BlockBlogSection2 component: BlockBlogSection2 components: container badge button --- :: ## Style Three Mixed layout with featured content and recent posts sidebar. Features horizontal card layout on mobile with image-heavy design. ::block-showcase --- block-path: Blog/Section/BlockBlogSection3 component: BlockBlogSection3 components: container avatar --- :: ## Style Four Featured post with sidebar layout showcasing a large hero post and recent articles. Includes gradient header, category chips, and navigation sidebar. ::block-showcase --- block-path: Blog/Section/BlockBlogSection4 component: BlockBlogSection4 components: container avatar badge chip card --- :: ## Style Five Masonry-style grid with varied card heights and category filter tabs. Features large featured card spanning multiple rows with load more functionality. ::block-showcase --- block-path: Blog/Section/BlockBlogSection5 component: BlockBlogSection5 components: container avatar badge card tabs button --- :: ## Style Six Newsletter-integrated section with inline subscription card. Features engagement metrics (likes, comments), animated pulse indicator, and social stats. ::block-showcase --- block-path: Blog/Section/BlockBlogSection6 component: BlockBlogSection6 components: container avatar badge card input button divider separator --- :: ## Style Seven Timeline-style chronological layout with vertical connecting line and date markers. Features horizontal card design with distinct content sections. ::block-showcase --- block-path: Blog/Section/BlockBlogSection7 component: BlockBlogSection7 components: container avatar badge card button --- :: ## Style Eight Horizontal scrollable cards section with trending badges and gradient fade edges. Features view counters, bookmark actions, and mobile-optimized scrolling. ::block-showcase --- block-path: Blog/Section/BlockBlogSection8 component: BlockBlogSection8 components: container avatar badge card button scroll-area divider --- :: # Blog - Subscribe ## Style One Classic newsletter card with gradient icon, centered layout, and staggered entrance animations. ::block-showcase --- block-path: Blog/Subscribe/BlockBlogSubscribe1 component: BlockBlogSubscribe1 components: card vee-input button container-class: max-w-md mx-auto my-10 frame-class: px-1 iframe-height: 550px --- :: ## Style Two Modern design with animated top border accent and spring-based motion effects. ::block-showcase --- block-path: Blog/Subscribe/BlockBlogSubscribe2 component: BlockBlogSubscribe2 components: card vee-input button container-class: max-w-md mx-auto my-10 frame-class: px-1 iframe-height: 550px --- :: ## Style Three Eye-catching card with large animated icon, and privacy assurance badge. ::block-showcase --- block-path: Blog/Subscribe/BlockBlogSubscribe3 component: BlockBlogSubscribe3 components: card vee-input button container-class: max-w-md mx-auto my-10 frame-class: px-1 iframe-height: 650px --- :: ## Style Four Feature-rich subscription card with badge, benefits checklist, and decorative blur effects. ::block-showcase --- block-path: Blog/Subscribe/BlockBlogSubscribe4 component: BlockBlogSubscribe4 components: card vee-input button badge container-class: max-w-md mx-auto my-10 frame-class: px-1 iframe-height: 600px --- :: ## Style Five Gradient background card with inline form, social proof stats, and animated divider. ::block-showcase --- block-path: Blog/Subscribe/BlockBlogSubscribe5 component: BlockBlogSubscribe5 components: card vee-input button container-class: max-w-md mx-auto my-10 frame-class: px-1 iframe-height: 600px --- :: ## Style Six Centered design with dashed border, icon input field, and trust indicators footer. ::block-showcase --- block-path: Blog/Subscribe/BlockBlogSubscribe6 component: BlockBlogSubscribe6 components: card vee-input button container-class: max-w-md mx-auto my-10 frame-class: px-1 iframe-height: 550px --- :: ## Style Seven Premium dark-themed card with statistics grid, inverted colors, and exclusive content badge. ::block-showcase --- block-path: Blog/Subscribe/BlockBlogSubscribe7 component: BlockBlogSubscribe7 components: card vee-input button badge container-class: max-w-md mx-auto my-10 frame-class: px-1 iframe-height: 600px --- :: # Career ## Style One Simple centered career listing with clean job cards. Features staggered animations, hover effects, and inline action buttons. ::block-showcase --- block-path: Career/BlockCareer1 component: BlockCareer1 components: container badge button --- :: ## Style Two Two-column layout with descriptive header on the left. Features side-by-side design with company philosophy and job listings. ::block-showcase --- block-path: Career/BlockCareer2 component: BlockCareer2 components: container badge button --- :: ## Style Three Career section with team image showcase. Features centered header, job listings with animated image, and visual appeal. ::block-showcase --- block-path: Career/BlockCareer3 component: BlockCareer3 components: container badge button --- :: ## Style Four Card-based career page with department filtering. Features tab navigation, salary ranges, benefits chips, and card hover effects. ::block-showcase --- block-path: Career/BlockCareer4 component: BlockCareer4 components: container badge button card divider tabs --- :: ## Style Five Minimal search-focused career page with featured position. Features search bar, highlighted featured role with image, and clean position list. ::block-showcase --- block-path: Career/BlockCareer5 component: BlockCareer5 components: container badge button card vee-input --- :: ## Style Six Modern career page with team culture and perks showcase. Features gradient header, team statistics, benefits cards, accordion job listings, and CTA section. ::block-showcase --- block-path: Career/BlockCareer6 component: BlockCareer6 components: container badge button card chip accordion --- :: # Contact - Header ## Style One - Centered Contact Form Simple centered contact form with staggered animations and clean layout. ::block-showcase --- block-path: Contact/Header/BlockContactHeader1 component: BlockContactHeader1 components: container vee-input vee-textarea button --- :: ## Style Two - Form with Google Maps Two-column layout with contact form and embedded Google Maps integration. ::block-showcase --- block-path: Contact/Header/BlockContactHeader2 component: BlockContactHeader2 components: container vee-input vee-textarea button --- :: ## Style Three - Form with Image Contact form paired with decorative image in a two-column layout. ::block-showcase --- block-path: Contact/Header/BlockContactHeader3 component: BlockContactHeader3 components: container vee-input vee-textarea button --- :: ## Style Four - Contact Information Cards Three-column layout with contact information cards featuring icons and hover effects. ::block-showcase --- block-path: Contact/Header/BlockContactHeader4 component: BlockContactHeader4 components: container --- :: ## Style Five - Multiple Locations Large map showcase with location cards for multiple office addresses. ::block-showcase --- block-path: Contact/Header/BlockContactHeader5 component: BlockContactHeader5 components: container --- :: ## Style Six - Team Support Cards Contact form with support team member cards, avatars, and quick info panel. ::block-showcase --- block-path: Contact/Header/BlockContactHeader6 component: BlockContactHeader6 components: container card avatar badge vee-input vee-textarea button --- :: ## Style Seven - FAQ with Contact Form Two-column layout featuring FAQ accordion and contact form card. ::block-showcase --- block-path: Contact/Header/BlockContactHeader7 component: BlockContactHeader7 components: container card accordion vee-input vee-textarea button --- :: ## Style Eight - Gradient Hero Contact Full-width gradient background with centered form, animated blobs, and social links. ::block-showcase --- block-path: Contact/Header/BlockContactHeader8 component: BlockContactHeader8 components: container card divider vee-input vee-textarea button --- :: ## Style Nine - Department Selection Contact form with department chip selection, priority badge, and response time estimates. ::block-showcase --- block-path: Contact/Header/BlockContactHeader9 component: BlockContactHeader9 components: container card chip badge vee-input vee-textarea button --- :: # Call To Action (CTA) ## Style One - Centered CTA Simple centered call-to-action with dual buttons and staggered animations. ::block-showcase --- block-path: CTA/BlockCTA1 component: BlockCTA1 components: container button iframe-height: 450px --- :: ## Style Two - Horizontal Split CTA Text and buttons arranged side-by-side with responsive stacking on mobile. ::block-showcase --- block-path: CTA/BlockCTA2 component: BlockCTA2 components: container button iframe-height: 350px --- :: ## Style Three - Feature List with Image CTA with feature checklist and decorative image in two-column layout. ::block-showcase --- block-path: CTA/BlockCTA3 component: BlockCTA3 components: container button --- :: ## Style Four - Testimonial Carousel Swiper-powered testimonial slider with customer reviews and feature list. Requires [Nuxt Swiper Module](https://github.com/cpreston321/nuxt-swiper){rel="nofollow"}. ::prose-pm-x{command="nuxi@latest module add swiper"} :: Then add it to your `nuxt.config` file: ```ts export default defineNuxtConfig({ modules: ["nuxt-swiper"], swiper: { /* module options */ }, }); ``` ::block-showcase --- block-path: CTA/BlockCTA4 component: BlockCTA4 components: container button --- :: ## Style Five - App Download CTA Mobile app showcase with platform download buttons and phone mockup. ::block-showcase --- block-path: CTA/BlockCTA5 component: BlockCTA5 components: container button --- :: ## Style Six - Gradient with Statistics Full-width gradient background with statistics badges and animated blobs. ::block-showcase --- block-path: CTA/BlockCTA6 component: BlockCTA6 components: container button --- :: ## Style Seven - Newsletter Signup Email newsletter subscription with inline input and submit button. ::block-showcase --- block-path: CTA/BlockCTA7 component: BlockCTA7 components: container badge input button iframe-height: 500px --- :: ## Style Eight - Feature Card CTA Centered card design with feature grid, icon badges, and shadow effects. ::block-showcase --- block-path: CTA/BlockCTA8 component: BlockCTA8 components: container card button --- :: ## Style Nine - Customer Testimonials Swiper carousel with customer quotes, avatars, and rating stars. Requires [Nuxt Swiper Module](https://github.com/cpreston321/nuxt-swiper){rel="nofollow"}. ::block-showcase --- block-path: CTA/BlockCTA9 component: BlockCTA9 components: container card avatar button --- :: # Error ## Background patterns Here is one source for background patterns. {rel="nofollow"} You can copy them and modify them as you see fit. ## Adding a custom error page To add a custom error page, you can create a new file in the root of your nuxt app call `error.vue`. You can learn more about this in the [Nuxt documentation](https://nuxt.com/docs/guide/directory-structure/error){rel="nofollow"}. ## Simple Grid pattern background with left-aligned content and staggered entrance animations. ::block-showcase --- block-path: Error/BlockError component: BlockError components: button iframe-height: 600px --- :: ## Centered Radial dot pattern background with centered text layout and animated content reveal. ::block-showcase --- block-path: Error/BlockErrorCentered component: BlockErrorCentered components: button iframe-height: 600px --- :: ## Image Two-column split layout featuring decorative image with slide-in animation and responsive stacking. ::block-showcase --- block-path: Error/BlockErrorImage component: BlockErrorImage components: button iframe-height: 600px --- :: ## Links Grid background with helpful navigation links featuring staggered animations and hover effects. ::block-showcase --- block-path: Error/BlockErrorLinks component: BlockErrorLinks components: button iframe-height: 600px --- :: ## Animated Gradient background with floating blobs and GSAP timeline animations for smooth sequential reveals. **Requires:** `npm install gsap` ::block-showcase --- block-path: Error/BlockError5 component: BlockError5 iframe-height: 700px --- #components The button component is used for the retry action. :::prose-pm-x{command="ui-thing@latest add button"} ::: This also needs gsap to be installed. :::prose-pm-install{name="gsap"} ::: :: ## Suggestions carousel Interactive carousel showcasing helpful resource cards with auto-play functionality. **Requires:** Nuxt Swiper module. ::block-showcase --- block-path: Error/BlockError6 component: BlockError6 components: card button iframe-height: 700px --- :: ## Minimal Clean, minimal design with custom SVG illustration and spring-based entrance animations. ::block-showcase --- block-path: Error/BlockError7 component: BlockError7 components: button iframe-height: 700px --- :: ## Dark / Stats Dark-themed error page with status cards, error details in terminal style, and retry actions. ::block-showcase --- block-path: Error/BlockError8 component: BlockError8 components: card badge button iframe-height: 700px --- :: ## Interactive Search Feature-rich error page with inline search input and popular pages grid for easy navigation. ::block-showcase --- block-path: Error/BlockError9 component: BlockError9 components: card input button iframe-height: 700px --- :: # FAQs ## Style One Grid layout with centered icon cards. Features three-column responsive design, staggered animations, icon badges, and centered CTA section. ::block-showcase --- block-path: FAQ/BlockFAQ1 component: BlockFAQ1 components: container button --- :: ## Style Two Grid layout with left-aligned content. Features three-column cards, icon badges with hover effects, and horizontal CTA with responsive stacking. ::block-showcase --- block-path: FAQ/BlockFAQ2 component: BlockFAQ2 components: container button --- :: ## Style Three Classic accordion FAQ layout. Features expandable/collapsible questions, centered content area, smooth animations, and support CTA. ::block-showcase --- block-path: FAQ/BlockFAQ3 component: BlockFAQ3 components: container button accordion --- :: ## Style Four Categorized FAQ with tabs and search. Features category navigation, search bar, accordion per tab, and organized content by topic. ::block-showcase --- block-path: FAQ/BlockFAQ4 component: BlockFAQ4 components: container button accordion vee-input tabs --- :: ## Style Five Card-based FAQ with search filtering. Features interactive cards with hover effects, real-time search, category badges, and dual CTA buttons. ::block-showcase --- block-path: FAQ/BlockFAQ5 component: BlockFAQ5 components: container card badge button vee-input --- :: ## Style Six Two-column minimal layout. Features sticky sidebar with description, clean question list, simple border separators, and compact design. ::block-showcase --- block-path: FAQ/BlockFAQ6 component: BlockFAQ6 components: container badge button --- :: ## Style Seven Interactive collapsible cards. Features manual toggle controls, plus/minus icons, card hover states, and dual support contact options. ::block-showcase --- block-path: FAQ/BlockFAQ7 component: BlockFAQ7 components: container card button --- :: # Features ## Style One Alternating image and content layout with checkmark lists. Features large images with detailed feature descriptions and bullet points. ::block-showcase --- block-path: Feature/BlockFeature1 component: BlockFeature1 components: container container-class: min-h-screen --- :: ## Style Two Image and content sections with call-to-action buttons. Similar to Style One but includes action buttons for demos and learn more links. ::block-showcase --- block-path: Feature/BlockFeature2 component: BlockFeature2 components: container button container-class: min-h-screen --- :: ## Style Three Simple centered grid with icon cards. Clean, minimal three-column layout perfect for highlighting key features. ::block-showcase --- block-path: Feature/BlockFeature3 component: BlockFeature3 components: container --- :: ## Style Four Six-feature grid with centered icon cards. Expanded version of Style Three showing more features in a 2x3 or 3x2 grid. ::block-showcase --- block-path: Feature/BlockFeature4 component: BlockFeature4 components: container --- :: ## Style Five Left-aligned grid with feature links. Each feature card includes an arrow link for more information. ::block-showcase --- block-path: Feature/BlockFeature5 component: BlockFeature5 components: container --- :: ## Style Six Grid with decorative SVG and featured image. Includes a decorative arrow SVG element and split layout with feature grid and image. ::block-showcase --- block-path: Feature/BlockFeature6 component: BlockFeature6 components: container --- :: ## Style Seven Horizontal layout with image and linked features. Features displayed in a row with detailed descriptions and learn more links. ::block-showcase --- block-path: Feature/BlockFeature7 component: BlockFeature7 components: container --- :: ## Style Eight Two-column layout with decorative SVG and video embed. Includes a YouTube video iframe and decorative background element. ::block-showcase --- block-path: Feature/BlockFeature8 component: BlockFeature8 components: container --- :: ## Style Nine Centered layout with hero image and feature grid. Features a large hero image followed by a centered grid of features with links. ::block-showcase --- block-path: Feature/BlockFeature9 component: BlockFeature9 components: container badge button --- :: ## Style Ten Three-column layout with phone mockup. Features arranged on both sides of a centered phone mockup image. ::block-showcase --- block-path: Feature/BlockFeature10 component: BlockFeature10 components: container badge button --- :: ## Style Eleven Integration showcase with logo icons. Perfect for displaying third-party integrations and partnerships. ::block-showcase --- block-path: Feature/BlockFeature11 component: BlockFeature11 components: container badge button --- :: ## Style Twelve Tab-based feature sections with images. Interactive tabs for Analytics, Security, and Automation with detailed features and images. ::block-showcase --- block-path: Feature/BlockFeature12 component: BlockFeature12 components: container tabs --- :: ## Style Thirteen Bento grid layout with mixed card sizes. Modern bento-box style grid with featured large card and smaller feature cards. ::block-showcase --- block-path: Feature/BlockFeature13 component: BlockFeature13 components: container card --- :: ## Style Fourteen Services grid with hover effects. Six colorful service cards with icons, features, and hover glow effects. ::block-showcase --- block-path: Feature/BlockFeature14 component: BlockFeature14 components: container card badge button --- :: ## Style Fifteen Feature comparison table. Comprehensive table comparing features across Starter, Professional, and Enterprise tiers. ::block-showcase --- block-path: Feature/BlockFeature15 component: BlockFeature15 components: container card button --- :: ## Style Sixteen Animated feature cards with badges. Six feature cards with hover animations, badges, and detailed highlights. ::block-showcase --- block-path: Feature/BlockFeature16 component: BlockFeature16 components: container card badge --- :: ## Style Seventeen Gradient background with floating elements. Features colorful gradient backgrounds with animated floating orbs and feature cards with tags. ::block-showcase --- block-path: Feature/BlockFeature17 component: BlockFeature17 components: container card badge button --- :: ## Style Eighteen Dark theme with GSAP animations. **Requires:** `npm install gsap`. Dark gradient background with animated floating orbs and feature cards with stats. ::block-showcase --- block-path: Feature/BlockFeature18 component: BlockFeature18 components: container card button --- :: ## Style Nineteen Animated gradient blobs with masonry grid. Features animated gradient blob backgrounds with mixed-size feature cards in a masonry-style layout. ::block-showcase --- block-path: Feature/BlockFeature19 component: BlockFeature19 components: container card badge --- :: ## Style Twenty Glassmorphism design with dark background. Premium glassmorphic cards with backdrop blur, gradient borders, and animated particles. ::block-showcase --- block-path: Feature/BlockFeature20 component: BlockFeature20 components: container badge button --- :: # Footer ## Style One Six-column link grid footer. Simple footer with a grid of navigation links organized into columns and copyright section with logo. ::block-showcase --- block-path: Footer/BlockFooter1 component: BlockFooter1 components: container --- :: ## Style Two Logo and description with link columns. Features a prominent logo section with description, four columns of links, and social media icons. ::block-showcase --- block-path: Footer/BlockFooter2 component: BlockFooter2 components: container --- :: ## Style Three Newsletter subscription with link columns. Includes a newsletter signup form alongside navigation columns and social media links. ::block-showcase --- block-path: Footer/BlockFooter3 component: BlockFooter3 components: container button --- :: ## Style Four Newsletter highlight with six-column links. Newsletter section at top with prominent call-to-action, followed by comprehensive link grid. ::block-showcase --- block-path: Footer/BlockFooter4 component: BlockFooter4 components: container button --- :: ## Style Five Navigation and newsletter combined. Features primary navigation links alongside newsletter subscription form in a clean layout. ::block-showcase --- block-path: Footer/BlockFooter5 component: BlockFooter5 components: container button --- :: ## Style Six Call-to-action footer with centered content. Large CTA section with prominent messaging and action buttons, followed by simple copyright bar. ::block-showcase --- block-path: Footer/BlockFooter6 component: BlockFooter6 components: container button --- :: ## Style Seven Minimal single-line footer. Simple, clean footer with just logo, copyright, and centered layout. ::block-showcase --- block-path: Footer/BlockFooter7 component: BlockFooter7 components: container iframe-height: 200px --- :: ## Style Eight Ultra-minimal centered footer. Compact footer with logo, navigation links, and copyright in a horizontal layout. ::block-showcase --- block-path: Footer/BlockFooter8 component: BlockFooter8 components: container iframe-height: 300px --- :: ## Style Nine Four-column footer with social media. Features company description, organized link columns, and social media icons in rounded buttons. ::block-showcase --- block-path: Footer/BlockFooter9 component: BlockFooter9 components: container container-class: mt-5 --- :: ## Style Ten Dark theme comprehensive footer. Full-featured dark footer with five link columns, newsletter subscription, and social links. ::block-showcase --- block-path: Footer/BlockFooter10 component: BlockFooter10 components: container button --- :: ## Style Eleven Two-column layout with inline navigation. Clean design with logo/description on left, social links and legal footer on right. ::block-showcase --- block-path: Footer/BlockFooter11 component: BlockFooter11 components: container --- :: ## Style Twelve Gradient CTA footer with six columns. Features prominent call-to-action section, comprehensive link grid, and social media. ::block-showcase --- block-path: Footer/BlockFooter12 component: BlockFooter12 components: container button --- :: ## Style Thirteen App download footer with detailed links. Includes App Store/Google Play buttons, extensive social links, and three-column navigation. ::block-showcase --- block-path: Footer/BlockFooter13 component: BlockFooter13 components: container --- :: ## Style Fourteen Compact single-line footer. Minimal design with logo, inline navigation, and copyright in one clean row. ::block-showcase --- block-path: Footer/BlockFooter14 component: BlockFooter14 components: container --- :: ## Style Fifteen Centered social-first footer. Large logo with centered navigation, prominent social media icons, and legal links. ::block-showcase --- block-path: Footer/BlockFooter15 component: BlockFooter15 components: container --- :: ## Style Sixteen Three-column balanced footer. Features logo, quick links, and newsletter subscription in equal-width columns. ::block-showcase --- block-path: Footer/BlockFooter16 component: BlockFooter16 components: container button divider --- :: # Forgot & Reset Password ## Style One Email input form for password recovery with grid background. Simple centered layout with email field and instructions to send reset link. ::block-showcase --- block-path: ForgotPassword/BlockForgotPassword component: BlockForgotPassword components: button vee-input container-class: h-screen iframe-height: 550px --- :: ## Style Two Card-based forgot password form with muted background. Clean centered design with email input, divider, and sign-in link. Features icon badge and helpful hint text. ::block-showcase --- block-path: ForgotPassword/BlockForgotPassword2 component: BlockForgotPassword2 components: button card divider vee-input container-class: h-screen iframe-height: 600px --- :: ## Style Three Split-screen forgot password layout. Left side features the form while right side displays security information with feature highlights and icons. Modern design for larger screens. ::block-showcase --- block-path: ForgotPassword/BlockForgotPassword3 component: BlockForgotPassword3 components: button vee-input container-class: h-screen iframe-height: 700px --- :: ## Success Confirmation Success confirmation page. Displays after email submission with mail icon, success message, and option to resend instructions. ::block-showcase --- block-path: ForgotPassword/BlockForgotPasswordSuccess component: BlockForgotPasswordSuccess components: button container-class: h-screen iframe-height: 550px --- :: ## Two-Step Verification Multi-method verification selector. Users choose between email or SMS verification with dynamic form fields. Features card-based selection with icons and check indicators. ::block-showcase --- block-path: ForgotPassword/BlockTwoStepVerification component: BlockTwoStepVerification components: button card vee-input container-class: h-screen iframe-height: 750px --- :: ## OTP Verification - Style One OTP verification with grid background. Features 6-digit PIN input using UiVeePinInput, email confirmation display, and resend functionality. ::block-showcase --- block-path: OTP/BlockOTPVerification component: BlockOTPVerification components: button vee-input vee-pin-input container-class: h-screen iframe-height: 600px --- :: ## OTP Verification - Style Two Card-based OTP verification. Clean centered design with lock icon, 6-digit PIN input, verification instructions, and resend option with divider. ::block-showcase --- block-path: OTP/BlockOTPVerification2 component: BlockOTPVerification2 components: button card divider vee-input vee-pin-input container-class: h-screen iframe-height: 650px --- :: ## Reset Password - Style One Password reset form with validation and grid background. Features password strength indicators, confirmation field matching, and real-time validation feedback with check icons. ::block-showcase --- block-path: ResetPassword/BlockResetPassword component: BlockResetPassword components: button vee-input container-class: h-screen iframe-height: 680px --- :: ## Reset Password - Style Two Card-based password reset form. Minimal design with password inputs, validation requirements list in muted background, and clear visual feedback. ::block-showcase --- block-path: ResetPassword/BlockResetPassword2 component: BlockResetPassword2 components: button card vee-input container-class: h-screen iframe-height: 650px --- :: # Header Section ## Style One Centered header with headline, title, and description. Features slotted content area for custom buttons or CTAs. Clean minimal design with responsive text sizing. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection1 component: BlockHeaderSection1 components: container container-class: h-screen iframe-height: 400px --- :: ## Style Two Centered header with dual button layout. Includes headline, title, description, and two action buttons (outline and solid variants) for primary and secondary CTAs. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection2 component: BlockHeaderSection2 components: button container container-class: h-screen iframe-height: 400px --- :: ## Style Three Centered header with billing toggle tabs. Features monthly/annual billing selector with badge highlighting savings. Ideal for pricing pages with plan options. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection3 component: BlockHeaderSection3 components: badge container tabs container-class: h-screen iframe-height: 400px --- :: ## Style Four Centered header with email signup form. Features email input with submit button and privacy policy text. Wide form layout optimized for newsletter signups. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection4 component: BlockHeaderSection4 components: button container vee-input container-class: h-screen iframe-height: 400px --- :: ## Style Five Centered header with search input. Clean design featuring search icon input field. Perfect for documentation sites, knowledge bases, or product search pages. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection5 component: BlockHeaderSection5 components: container vee-input container-class: h-screen iframe-height: 400px --- :: ## Style Six Left-aligned header with slotted content. Features headline, title, and description aligned to the left. Provides flexible slot for custom action elements. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection6 component: BlockHeaderSection6 components: container container-class: h-screen iframe-height: 400px --- :: ## Style Seven Left-aligned header with dual buttons. Similar to Style Six but includes outline and solid button pair for primary and secondary actions. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection7 component: BlockHeaderSection7 components: button container container-class: h-screen iframe-height: 400px --- :: ## Style Eight Left-aligned header with billing tabs. Features monthly/annual billing toggle with savings badge. Left-aligned variant of the pricing header layout. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection8 component: BlockHeaderSection8 components: badge container tabs container-class: h-screen iframe-height: 400px --- :: ## Style Nine Left-aligned header with email form. Email signup form with privacy policy notice. Left-aligned layout for newsletter subscription or waitlist signups. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection9 component: BlockHeaderSection9 components: button container vee-input container-class: h-screen iframe-height: 400px --- :: ## Style Ten Left-aligned header with search field. Features search icon input aligned to the left. Ideal for category pages or filtered content sections. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection10 component: BlockHeaderSection10 components: container vee-input container-class: h-screen iframe-height: 400px --- :: ## Style Eleven Split header with headline and title on left, description on right. Two-column responsive layout that balances heading content with supporting description text. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection11 component: BlockHeaderSection11 components: container container-class: h-screen iframe-height: 400px --- :: ## Style Twelve Split header with dual buttons. Two-column layout with headline/title on left, description on right, and action buttons below for balanced content presentation. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection12 component: BlockHeaderSection12 components: button container container-class: h-screen iframe-height: 400px --- :: ## Style Thirteen Split header with billing tabs. Two-column layout featuring headline/title split with description and billing period selector. Perfect for pricing page headers. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection13 component: BlockHeaderSection13 components: badge container tabs container-class: h-screen iframe-height: 400px --- :: ## Style Fourteen Split header with email signup. Two-column layout with email form and privacy notice. Balanced presentation for lead generation and newsletter signups. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection14 component: BlockHeaderSection14 components: button container vee-input container-class: h-screen iframe-height: 400px --- :: ## Style Fifteen Split header with search input. Two-column layout featuring search field. Ideal for content-heavy pages requiring prominent search functionality. ::block-showcase --- block-path: HeaderSection/BlockHeaderSection15 component: BlockHeaderSection15 components: container vee-input container-class: h-screen iframe-height: 400px --- :: # Hero ## Style One Split layout hero with email signup form and side image. Features badge, headline, description, and email input with animated slide-in effects from left and right. ::block-showcase --- block-path: Hero/BlockHero1 component: BlockHero1 components: badge button vee-input container-class: h-screen iframe-height: 600px --- :: ## Style Two Split layout with dual action buttons and clipped image. Features secondary badge variant, demo and signup buttons, with scale animation on the image. ::block-showcase --- block-path: Hero/BlockHero2 component: BlockHero2 components: badge button container-class: h-screen iframe-height: 600px --- :: ## Style Three Split layout with customer social proof. Includes email signup form, avatar stack, star ratings, and customer count display. ::block-showcase --- block-path: Hero/BlockHero3 component: BlockHero3 components: button vee-input animated-tooltip container-class: h-screen iframe-height: 600px --- :: ## Style Four Hero with background grid pattern and rounded image. Features overlay image with custom border radius and grid background with radial mask. ::block-showcase --- block-path: Hero/BlockHero4 component: BlockHero4 components: button container container-class: h-screen iframe-height: 600px --- :: ## Style Five Hero with dotted background pattern and social proof. Includes email form, avatar stack, star ratings, and radial dot background pattern. ::block-showcase --- block-path: Hero/BlockHero5 component: BlockHero5 components: button container vee-input animated-tooltip container-class: h-screen iframe-height: 600px --- :: ## Style Six Hero with decorative SVG arrow and signup form. Features centered or left-aligned content with custom SVG decoration and card-based form layout. ::block-showcase --- block-path: Hero/BlockHero6 component: BlockHero6 components: button container vee-input animated-tooltip container-class: h-screen iframe-height: 600px --- :: ## Style Seven Centered hero with embedded video. Features badge, headline, buttons, and YouTube video embed with staggered fade-in animations. ::block-showcase --- block-path: Hero/BlockHero7 component: BlockHero7 components: badge button container container-class: h-screen iframe-height: 600px --- :: ## Style Eight Centered hero with dashboard preview. Features feature badges with icons, dual CTAs, trust indicators, and large dashboard screenshot with shadow. ::block-showcase --- block-path: Hero/BlockHero8 component: BlockHero8 components: badge button container container-class: h-screen iframe-height: 700px --- :: ## Style Nine Centered hero with animated background and stats. Features gradient background, grid pattern, animated status badge, and key statistics display. ::block-showcase --- block-path: Hero/BlockHero9 component: BlockHero9 components: button container container-class: h-screen iframe-height: 700px --- :: ## Style Ten Split layout with email form and glowing image. Features security badges, email signup, and product showcase image with gradient glow effect. ::block-showcase --- block-path: Hero/BlockHero10 component: BlockHero10 components: button container vee-input container-class: h-screen iframe-height: 700px --- :: # Login ## Simple A minimal login form with email and password fields. Includes links for password recovery and account creation. Perfect for straightforward authentication needs. ::block-showcase --- block-path: Login/BlockLoginSimple component: BlockLoginSimple components: vee-input button container-class: h-screen iframe-height: 550px --- :: ## Simple w/ Card Clean login form presented within a bordered card container. Features subtle shadow and rounded corners for a polished, contained appearance. ::block-showcase --- block-path: Login/BlockLoginSimpleCard component: BlockLoginSimpleCard components: vee-input button container-class: h-screen iframe-height: 600px --- :: ## Simple w/ Social Login form with social authentication options. Includes Google and Facebook sign-in buttons separated by a divider for multiple authentication methods. ::block-showcase --- block-path: Login/BlockLoginSimpleSocial component: BlockLoginSimpleSocial components: vee-input button divider container-class: h-screen iframe-height: 650px --- :: ## Simple w/ Social 2 Email-only login with extensive social options. Features company logo and multiple social providers including Google, Facebook, and Github for flexible authentication. ::block-showcase --- block-path: Login/BlockLoginSimpleSocial2 component: BlockLoginSimpleSocial2 components: vee-input button divider container-class: h-screen iframe-height: 650px --- :: ## Simple w/ Image Split-screen login with decorative image. Form on one side, full-height background image on the other. Includes social login option and responsive layout that hides image on mobile. ::block-showcase --- block-path: Login/BlockLoginSimpleSocialImage component: BlockLoginSimpleSocialImage components: vee-input button divider container-class: h-screen iframe-height: 650px --- :: ## Remember Me Login form with remember me functionality. Features company logo, checkbox for persistent sessions, and convenient forgot password link positioned next to the checkbox. ::block-showcase --- block-path: Login/BlockLoginSimpleRemember component: BlockLoginSimpleRemember components: vee-input button vee-checkbox container-class: h-screen iframe-height: 650px --- :: ## Two Column Modern two-column layout with form and feature showcase. Left side contains login form with social options and remember me checkbox. Right side displays security message with icon on muted background. ::block-showcase --- block-path: Login/BlockLoginTwoColumn component: BlockLoginTwoColumn components: vee-input button vee-checkbox divider container-class: h-screen iframe-height: 650px --- :: ## Minimal Card Centered card design with icon header. Features circular user icon, clean spacing, and focused layout. Ideal for admin panels or dashboard authentication. ::block-showcase --- block-path: Login/BlockLoginMinimal component: BlockLoginMinimal components: vee-input button container-class: h-screen iframe-height: 600px --- :: ## Centered Social Social-first authentication with centered layout. Company logo and prominent social login buttons above the traditional email/password form. Remember me checkbox included. ::block-showcase --- block-path: Login/BlockLoginCentered component: BlockLoginCentered components: vee-input button vee-checkbox divider container-class: h-screen iframe-height: 700px --- :: ## Compact Ultra-compact login card with minimal text. Features borderless inputs, simple card design, and terms of service notice. Perfect for space-constrained layouts or mobile-first designs. ::block-showcase --- block-path: Login/BlockLoginCompact component: BlockLoginCompact components: vee-input button container-class: h-screen iframe-height: 550px --- :: # Metric ## Style One Centered metrics display with muted background container. Features large primary-colored values in a three-column grid layout, perfect for highlighting key achievements. ::block-showcase --- block-path: Metric/BlockMetric1 component: BlockMetric1 components: container --- :: ## Style Two Bordered metrics section with four-column responsive grid. Simple, clean layout with top and bottom borders separating the metrics from surrounding content. ::block-showcase --- block-path: Metric/BlockMetric2 component: BlockMetric2 components: container iframe-height: 400px --- :: ## Style Three Metrics with header and call-to-action buttons. Features responsive button placement and additional descriptions for each metric, ideal for conversion-focused pages. ::block-showcase --- block-path: Metric/BlockMetric3 component: BlockMetric3 components: container button --- :: ## Style Four Split layout with image and metrics grid. Combines compelling visuals with statistics, featuring descriptive text for each metric and a strong heading section. ::block-showcase --- block-path: Metric/BlockMetric4 component: BlockMetric4 components: container --- :: ## Style Five Compact icon-based metrics in horizontal layout. Features icons next to values for visual interest, perfect for dashboard-style metric displays with minimal vertical space. ::block-showcase --- block-path: Metric/BlockMetric5 component: BlockMetric5 components: container --- :: ## Style Six Card-based metrics with icon badges. Each metric presented in a rounded card with circular icon background, ideal for emphasizing individual statistics with equal weight. ::block-showcase --- block-path: Metric/BlockMetric6 component: BlockMetric6 components: container iframe-height: 550px --- :: ## Style Seven Two-column layout with contextual section. Features heading with descriptive copy alongside a compact 2x2 metrics grid, great for storytelling with data. ::block-showcase --- block-path: Metric/BlockMetric7 component: BlockMetric7 components: container --- :: ## Style Eight Detailed card metrics with descriptions. Each statistic includes an icon, value, label, and supporting description text within a bordered card container. ::block-showcase --- block-path: Metric/BlockMetric8 component: BlockMetric8 components: container iframe-height: 550px --- :: ## Style Nine Primary-colored hero metrics section. Bold primary background with grid pattern overlay and centered layout, perfect for high-impact metric showcases. ::block-showcase --- block-path: Metric/BlockMetric9 component: BlockMetric9 components: container --- :: ## Style Ten Business metrics with growth badges. Features hover effects, icon containers, and trend badges showing percentage changes, ideal for dashboards and reports. ::block-showcase --- block-path: Metric/BlockMetric10 component: BlockMetric10 components: container badge iframe-height: 500px --- :: # Navigation (Header) ## Note In order to see the full navigation bar, please click on the `Full Screen View` button ( :icon{.inline name="lucide:gallery-vertical"} ) at the top of the style. This is because the full Navigation is not displayed unless you are above the `lg` breakpoint. ## Style One Multi-level mega menu navigation with categorized sections. Features large dropdown panels with grouped links, icons, and descriptions. Includes mobile sheet navigation with collapsible sections. ::block-showcase --- block-path: Navigation/BlockNavigation1 component: BlockNavigation1 components: container navigation-menu button sheet scroll-area collapsible gradient-divider container-class: h-screen --- :: ## Style Two Mega menu with icon cards and call-to-action footer. Each dropdown item displayed in a bordered card with icon, perfect for feature showcases. Includes promotional message in dropdown footer. ::block-showcase --- block-path: Navigation/BlockNavigation2 component: BlockNavigation2 components: container navigation-menu button sheet scroll-area collapsible gradient-divider container-class: h-screen --- :: ## Style Three Blog-focused navigation with image previews. Features grid layout of blog posts with thumbnail images in the dropdown menu. Includes hover effects and "View all" call-to-action. ::block-showcase --- block-path: Navigation/BlockNavigation3 component: BlockNavigation3 components: container navigation-menu button sheet collapsible scroll-area gradient-divider container-class: h-screen --- :: ## Style Four Compact dropdown menus with narrow panels. Features single-column dropdown layout with icons and descriptions, ideal for simpler navigation structures. Includes "Learn more" footer links. ::block-showcase --- block-path: Navigation/BlockNavigation4 component: BlockNavigation4 components: container navigation-menu button sheet scroll-area collapsible gradient-divider container-class: h-screen --- :: # Newsletter ## Style One Split layout with large image and email signup form. Features heading, description, email input, subscribe button, and privacy notice with responsive behavior. ::block-showcase --- block-path: Newsletter/BlockNewsletter1 component: BlockNewsletter1 components: container vee-input button --- :: ## Style Two Horizontal layout with heading and inline form. Simple design with email input and subscribe button, includes privacy policy notice. ::block-showcase --- block-path: Newsletter/BlockNewsletter2 component: BlockNewsletter2 components: container vee-input button iframe-height: 400px --- :: ## Style Three Centered newsletter signup with badge and animations. Features staggered fade-in effects, simple email form, and privacy message with Motion-v animations. ::block-showcase --- block-path: Newsletter/BlockNewsletter3 component: BlockNewsletter3 components: container badge vee-input button iframe-height: 500px --- :: ## Style Four Card-based newsletter with split content and decorative icons. Features subscriber count badge, feature icons (check marks, shield), and slide-in animations from left and right. ::block-showcase --- block-path: Newsletter/BlockNewsletter4 component: BlockNewsletter4 components: container card vee-input button iframe-height: 500px --- :: ## Style Five Newsletter form with grid background and multi-field inputs. Includes first name, last name, email fields, checkbox for terms acceptance, and card container with fade-in animations. ::block-showcase --- block-path: Newsletter/BlockNewsletter5 component: BlockNewsletter5 components: container card vee-input button checkbox iframe-height: 600px --- :: ## Style Six Featured newsletter block with benefits and statistics. Split layout showcasing weekly digest, instant updates, and exclusive offers with icon cards and staggered animations. ::block-showcase --- block-path: Newsletter/BlockNewsletter6 component: BlockNewsletter6 components: container vee-input button iframe-height: 500px --- :: ## Style Seven Premium newsletter card with decorative elements and social proof. Features centered layout with sparkles icon, subscriber count, rating, security badges, and bordered card design with fade-in animations. ::block-showcase --- block-path: Newsletter/BlockNewsletter7 component: BlockNewsletter7 components: container card vee-input button iframe-height: 550px --- :: # Pricing ## Style One Three-column pricing cards with icon headers and featured border. Each card includes icon badge, plan details, feature list with checkmarks, and call-to-action buttons. Features header with description and action buttons. ::block-showcase --- block-path: Pricing/BlockPricing1 component: BlockPricing1 components: container card button --- :: ## Style Two Simplified pricing cards with dual action buttons. Features large pricing display, plan name, and feature lists. Each card includes both primary and outline button options in the footer. ::block-showcase --- block-path: Pricing/BlockPricing2 component: BlockPricing2 components: container card button --- :: ## Style Three Two-column pricing with billing toggle and detailed features. Includes tabs for monthly/annual billing with savings badge, plan descriptions, and extensive two-column feature grids with checkmark indicators. ::block-showcase --- block-path: Pricing/BlockPricing3 component: BlockPricing3 components: container card button tabs badge iframe-height: 700px --- :: ## Style Four Comparison table pricing with detailed feature breakdown. Features billing tabs, comprehensive feature comparison across plans with category groupings. Desktop view shows side-by-side comparison, mobile shows stacked layout. ::block-showcase --- block-path: Pricing/BlockPricing4 component: BlockPricing4 components: container button tabs badge iframe-height: 800px --- :: ## Style Five Popular badge pricing with muted background. Three-column layout with "Most popular" badge on recommended plan, clean feature lists, and varied button styles to emphasize the featured option. ::block-showcase --- block-path: Pricing/BlockPricing5 component: BlockPricing5 components: container button badge iframe-height: 700px --- :: ## Style Six Two-column detailed pricing with feature descriptions. Features recommended badge, detailed feature explanations under each point, and different visual treatment for the featured plan with primary background tint. ::block-showcase --- block-path: Pricing/BlockPricing6 component: BlockPricing6 components: container button badge iframe-height: 750px --- :: ## Style Seven Annual/monthly toggle with switch component. Three-column layout featuring interactive switch for billing period, real-time price updates, and savings badge. Displays annual total when yearly billing selected. ::block-showcase --- block-path: Pricing/BlockPricing7 component: BlockPricing7 components: container button badge switch iframe-height: 700px --- :: ## Style Eight Four-tier pricing with icon badges and custom pricing option. Features icon headers, highlighted popular plan, free tier, and enterprise custom pricing. Organized with key features section separated by border. ::block-showcase --- block-path: Pricing/BlockPricing8 component: BlockPricing8 components: container button iframe-height: 750px --- :: # Sidebar ## Sidebar 01 A simple sidebar with navigation grouped by section. Features version switcher dropdown, search input, and organized navigation sections with labels and dividers. ::block-showcase --- block-path: Sidebar/BlockSidebar01 component: BlockSidebar01 components: sidebar dropdown-menu label navbar divider breadcrumbs placeholder iframe-height: 80vh --- :: ## Sidebar 02 A sidebar with collapsible sections. Includes expandable navigation groups using collapsible components, version switcher, search functionality, and breadcrumb navigation. ::block-showcase --- block-path: Sidebar/BlockSidebar02 component: BlockSidebar02 components: sidebar dropdown-menu label collapsible navbar divider breadcrumbs placeholder iframe-height: 80vh --- :: ## Sidebar 03 A sidebar with submenus. Features nested navigation items with expandable submenus, organized by sections with labels and dividers for better content organization. ::block-showcase --- block-path: Sidebar/BlockSidebar03 component: BlockSidebar03 components: sidebar dropdown-menu label navbar divider breadcrumbs placeholder iframe-height: 80vh --- :: ## Sidebar 04 A floating sidebar with submenus. Displays as a floating panel with nested navigation structure, dropdown menus for user actions, and organized sections with visual separators. ::block-showcase --- block-path: Sidebar/BlockSidebar04 component: BlockSidebar04 components: sidebar dropdown-menu label navbar divider breadcrumbs placeholder iframe-height: 80vh --- :: ## Sidebar 05 A sidebar with collapsible submenus. Features expandable navigation groups with nested items, allowing users to collapse/expand sections to manage sidebar content density. ::block-showcase --- block-path: Sidebar/BlockSidebar05 component: BlockSidebar05 components: sidebar dropdown-menu collapsible navbar breadcrumbs iframe-height: 80vh --- :: ## Sidebar 06 A sidebar with submenus as dropdowns. Navigation items with children render as dropdown menus on hover or click, providing a compact navigation solution. ::block-showcase --- block-path: Sidebar/BlockSidebar06 component: BlockSidebar06 components: sidebar dropdown-menu navbar breadcrumbs --- :: ## Sidebar 07 A sidebar that collapses to icons. Features a toggle button to minimize the sidebar to icon-only view, saving screen space while maintaining quick access to navigation. ::block-showcase --- block-path: Sidebar/BlockSidebar07 component: BlockSidebar07 components: sidebar dropdown-menu navbar breadcrumbs toggle iframe-height: 80vh --- :: ## Sidebar 08 An inset sidebar with secondary navigation. Features a main sidebar with an additional inset panel for secondary navigation items, perfect for multi-level app structures. ::block-showcase --- block-path: Sidebar/BlockSidebar08 component: BlockSidebar08 components: sidebar dropdown-menu navbar breadcrumbs iframe-height: 80vh --- :: ## Sidebar 09 Collapsible nested sidebars. Features multiple sidebar panels that can be collapsed independently, providing flexible navigation for complex applications with multiple sections. ::block-showcase --- block-path: Sidebar/BlockSidebar09 component: BlockSidebar09 components: sidebar dropdown-menu collapsible navbar breadcrumbs iframe-height: 80vh --- :: ## Sidebar 10 A sidebar in a popover. Navigation displayed within a popover component, ideal for mobile layouts or when sidebar should be triggered rather than always visible. ::block-showcase --- block-path: Sidebar/BlockSidebar10 component: BlockSidebar10 components: sidebar dropdown-menu popover navbar breadcrumbs iframe-height: 80vh --- :: ## Sidebar 11 A sidebar with a collapsible file tree. Features a recursive file/folder tree structure with expand/collapse functionality, perfect for documentation or file management interfaces. ::block-showcase --- block-path: Sidebar/BlockSidebar11 component: BlockSidebar11 components: sidebar dropdown-menu collapsible navbar breadcrumbs iframe-height: 80vh --- :: ## Sidebar 12 A sidebar with a calendar. Integrates a calendar component within the sidebar for date selection, along with standard navigation items and user dropdown menu. ::block-showcase --- block-path: Sidebar/BlockSidebar12 component: BlockSidebar12 components: sidebar dropdown-menu calendar navbar breadcrumbs iframe-height: 80vh --- :: ## Sidebar 13 A sidebar in a dialog. Navigation rendered within a dialog component, useful for full-screen overlays or modal-based navigation on smaller screens. ::block-showcase --- block-path: Sidebar/BlockSidebar13 component: BlockSidebar13 components: sidebar dropdown-menu dialog navbar breadcrumbs iframe-height: 80vh --- :: ## Sidebar 14 A sidebar on the right. Features the sidebar positioned on the right side of the layout instead of the default left position, with all standard navigation features. ::block-showcase --- block-path: Sidebar/BlockSidebar14 component: BlockSidebar14 components: sidebar dropdown-menu navbar breadcrumbs iframe-height: 80vh --- :: # Sign Up ## Background patterns Here is one source for background patterns. {rel="nofollow"} You can copy them and modify them as you see fit. ## Simple Clean sign up form with radial gradient background pattern. Features name, email, and password fields with a centered layout and subtle masked background effect. ::block-showcase --- block-path: SignUp/BlockSignUp component: BlockSignUp components: vee-input button container-class: h-screen iframe-height: 600px --- :: ## Card Simple sign up form presented in a card with border. Features radial dot pattern background and rounded card container with shadow for a polished appearance. ::block-showcase --- block-path: SignUp/BlockSignUpCard component: BlockSignUpCard components: vee-input button container-class: h-screen iframe-height: 600px --- :: ## Password Meter Sign up form with real-time password strength validation. Displays checkmark indicators for password requirements, showing users when their password meets security criteria. ::block-showcase --- block-path: SignUp/BlockSignUpPasswordMeter component: BlockSignUpPasswordMeter components: vee-input button container-class: h-screen iframe-height: 700px --- :: ## Social Email-only signup with multiple social authentication options. Features Google, Facebook, and Github sign-in buttons separated by divider, with grid background pattern. ::block-showcase --- block-path: SignUp/BlockSignUpSocial component: BlockSignUpSocial components: vee-input button divider container-class: h-screen iframe-height: 700px --- :: ## Image Split-screen layout with form and decorative image. Features social login option, form on left side, full-height image on right. Responsive layout hides image on mobile. ::block-showcase --- block-path: SignUp/BlockSignUpImage component: BlockSignUpImage components: vee-input button divider container-class: h-screen iframe-height: 700px --- :: ## Two Column Modern two-column layout with feature showcase. Left side includes first/last name fields, terms checkbox, and social options. Right side displays branded message on muted background. ::block-showcase --- block-path: SignUp/BlockSignUpTwoColumn component: BlockSignUpTwoColumn components: vee-input button vee-checkbox divider container-class: h-screen iframe-height: 700px --- :: ## Minimal Card Centered card with icon header and password confirmation. Features circular user icon badge, confirm password field for validation, and clean card design with muted background. ::block-showcase --- block-path: SignUp/BlockSignUpMinimal component: BlockSignUpMinimal components: vee-input button container-class: h-screen iframe-height: 650px --- :: ## Centered Social Social-first authentication with centered layout. Company logo, prominent social buttons above traditional form, and optional marketing checkbox for user preferences. ::block-showcase --- block-path: SignUp/BlockSignUpCentered component: BlockSignUpCentered components: vee-input button vee-checkbox divider container-class: h-screen iframe-height: 750px --- :: ## Compact Ultra-compact signup with minimal fields. Features borderless inputs, simple card design, and terms/privacy policy notice below form. Perfect for quick account creation flows. ::block-showcase --- block-path: SignUp/BlockSignUpCompact component: BlockSignUpCompact components: vee-input button container-class: h-screen iframe-height: 600px --- :: # Social Proof ## Style One Simple centered logo grid with company logos. Features staggered scale animations on logos with hover opacity effects. Clean minimal design for showcasing trusted partners. ::block-showcase --- block-path: SocialProof/BlockSocialProof1 component: BlockSocialProof1 components: container iframe-height: 300px --- :: ## Style Two Grid layout with heading and bordered logo cards. Features 8 company logos in responsive grid with hover effects and border animations. Includes descriptive heading and statistics. ::block-showcase --- block-path: SocialProof/BlockSocialProof2 component: BlockSocialProof2 components: container iframe-height: 500px --- :: ## Style Three Split layout combining statistics and company logos. Left side features key metrics with icons (users, rating, awards), right side displays company logos in grid format. ::block-showcase --- block-path: SocialProof/BlockSocialProof3 component: BlockSocialProof3 components: container iframe-height: 500px --- :: ## Style Four Testimonials with star ratings and company logos. Features customer testimonial cards with avatars, 5-star ratings, quotes, and grayscale logo footer. Muted background design. ::block-showcase --- block-path: SocialProof/BlockSocialProof4 component: BlockSocialProof4 components: avatar card container iframe-height: 700px --- :: ## Style Five Infinite scrolling logo marquee with statistics. Features auto-scrolling company logos with hover-to-pause, plus three key metrics displayed below in grid layout. ::block-showcase --- block-path: SocialProof/BlockSocialProof5 component: BlockSocialProof5 components: container iframe-height: 500px --- :: # Team ## Style One Centered header with avatar grid layout. Features 6 team members with circular avatars, names, and roles. Simple centered design with scale animations on member cards. ::block-showcase --- block-path: Team/BlockTeam1 component: BlockTeam1 components: avatar container --- :: ## Style Two Team grid with social links and experience. Displays 9 members with circular avatars, bio bullets, and social media icons (Twitter, LinkedIn, Dribbble). Slide-in animations on cards. ::block-showcase --- block-path: Team/BlockTeam2 component: BlockTeam2 components: avatar container --- :: ## Style Three Full-width photo cards with action buttons. Features 8 members with large rectangular photos, roles, bios, and CTA buttons (About us, Open positions). Card fade-in animations. ::block-showcase --- block-path: Team/BlockTeam3 component: BlockTeam3 components: avatar button container --- :: ## Style Four Leadership cards with hover effects. Displays 6 team members in card format with square photos, detailed bios, and social links. Image zoom on hover with staggered entrance animations. ::block-showcase --- block-path: Team/BlockTeam4 component: BlockTeam4 components: card container --- :: ## Style Five Split layout with statistics and team grid. Top section features company stats (team size, countries, remote status, rating), bottom shows 8 members with overlay gradient and names. ::block-showcase --- block-path: Team/BlockTeam5 component: BlockTeam5 components: button container --- :: ## Style Six Department-organized team sections. Groups members by department (Leadership, Engineering) with large avatars, badges (Founder, New, Core), roles, and locations. Sectioned layout with animations. ::block-showcase --- block-path: Team/BlockTeam6 component: BlockTeam6 components: avatar container --- :: # Testimony ## Style One Carousel testimonial slider with auto-rotation. Features centered quotes, customer avatars, star ratings, and company information. Uses Nuxt Swiper Module for smooth transitions between testimonials. This one requires the [Nuxt Swiper Module](https://github.com/cpreston321/nuxt-swiper?tab=readme-ov-file#features){rel="nofollow"}. ::prose-pm-x{command="nuxi@latest module add swiper"} :: Then add it to your `nuxt.config` file. ```ts export default defineNuxtConfig({ modules: ["nuxt-swiper"], swiper: { /* module options */ }, }); ``` ::block-showcase --- block-path: Testimony/BlockTestimony1 component: BlockTestimony1 components: container avatar --- :: ## Style Two Single centered testimonial with company logos. Features large quote display, customer details with avatar, star rating, and brand logos below for social proof. ::block-showcase --- block-path: Testimony/BlockTestimony2 component: BlockTestimony2 components: container avatar --- :: ## Style Three Side-by-side testimonial with customer image. Features large customer photo on the left, star rating at top, quote, and customer details. Responsive layout stacks vertically on mobile. ::block-showcase --- block-path: Testimony/BlockTestimony3 component: BlockTestimony3 components: container --- :: ## Style Four Split layout with testimonial carousel. Combines static quote section with background image carousel slider. Features decorative SVG element and glass-morphism cards. Requires Nuxt Swiper Module. This one requires the [Nuxt Swiper Module](https://github.com/cpreston321/nuxt-swiper?tab=readme-ov-file#features){rel="nofollow"}. ::block-showcase --- block-path: Testimony/BlockTestimony4 component: BlockTestimony4 components: container iframe-height: 750px --- :: ## Style Five Three-column testimonial grid with cards. Features equal-height cards with star ratings, quotes, and customer avatars. Clean grid layout perfect for showcasing multiple testimonials. ::block-showcase --- block-path: Testimony/BlockTestimony5 component: BlockTestimony5 components: container avatar iframe-height: 600px --- :: ## Style Six Two-column layout with stats and testimonials. Left side shows overall rating (4.9/5) and customer count with visual divider. Right side displays stacked testimonial cards with compact layout. ::block-showcase --- block-path: Testimony/BlockTestimony6 component: BlockTestimony6 components: container avatar iframe-height: 550px --- :: ## Style Seven Large card container with four testimonials. Features bordered card wrapper with centered heading and 2x2 grid layout of detailed testimonials including company names. ::block-showcase --- block-path: Testimony/BlockTestimony7 component: BlockTestimony7 components: container avatar iframe-height: 700px --- :: ## Style Eight Masonry grid layout with compact testimonial cards. Uses CSS columns for Pinterest-style staggered layout. Features multiple short testimonials with avatars and ratings in card format. ::block-showcase --- block-path: Testimony/BlockTestimony8 component: BlockTestimony8 components: container avatar iframe-height: 650px --- :: # Tiptap Editor ## Style One Custom Tiptap instance with grouped icon buttons and tooltips. Features organized button groups for text formatting (bold, italic, strike), headings (H1-H3), lists (bullet, ordered), and block elements (code, blockquote). Includes undo/redo actions with disabled states. ::block-showcase --- block-path: Tiptap/BlockTiptap1 component: BlockTiptap1 components: container toggle button separator tooltip --- :: # Callout ## Usage The `ProseCallout` component is used to highlight important information, tips, warnings, and other contextual messages. It supports multiple variants, optional icons, and can even be turned into a clickable link. ## Basic Example ::show-case --- prose: "" --- :::prose-callout This is a default callout with auto-generated icon. ::: :::prose-callout{icon="lucide:star"} This is a callout with a custom icon. ::: #code ```mdc ::prose-callout This is a default callout with auto-generated icon. :: ::prose-callout{icon="lucide:star"} This is a callout with a custom icon. :: ``` :: ## Variants The callout component comes with several pre-styled variants, each with its own default icon and color scheme. ### Info ::show-case --- prose: "" --- :::prose-callout{variant="info"} This is an informational message. Use this variant for general information or helpful tips. ::: :::prose-callout{title="Did you know?" variant="info"} You can combine the variant with a title to make the callout more prominent and easier to scan. ::: #code ```mdc ::prose-callout{variant="info"} This is an informational message. Use this variant for general information or helpful tips. :: ::prose-callout{variant="info" title="Did you know?"} You can combine the variant with a title to make the callout more prominent and easier to scan. :: ``` :: ### Success ::show-case --- prose: "" --- :::prose-callout{variant="success"} Operation completed successfully! Your changes have been saved. ::: :::prose-callout{title="Well done!" variant="success"} You've successfully completed all the required steps. You can now proceed to the next section. ::: #code ```mdc ::prose-callout{variant="success"} Operation completed successfully! Your changes have been saved. :: ::prose-callout{variant="success" title="Well done!"} You've successfully completed all the required steps. You can now proceed to the next section. :: ``` :: ### Warning ::show-case --- prose: "" --- :::prose-callout{variant="warning"} Please review your changes carefully before proceeding. This action may have side effects. ::: :::prose-callout{title="Heads up!" variant="warning"} Make sure to backup your data before running this command. It will modify files in your project. ::: #code ```mdc ::prose-callout{variant="warning"} Please review your changes carefully before proceeding. This action may have side effects. :: ::prose-callout{variant="warning" title="Heads up!"} Make sure to backup your data before running this command. It will modify files in your project. :: ``` :: ### Error ::show-case --- prose: "" --- :::prose-callout{variant="error"} An error occurred while processing your request. Please try again later. ::: :::prose-callout{title="Something went wrong" variant="error"} The build failed due to syntax errors. Check the console output for more details. ::: #code ```mdc ::prose-callout{variant="error"} An error occurred while processing your request. Please try again later. :: ::prose-callout{variant="error" title="Something went wrong"} The build failed due to syntax errors. Check the console output for more details. :: ``` :: ### Tip ::show-case --- prose: "" --- :::prose-callout{variant="tip"} Here's a helpful tip: You can use keyboard shortcuts to speed up your workflow. ::: :::prose-callout{title="Pro Tip" variant="tip"} Press `Cmd+K` to open the command palette and quickly navigate to any file in your project. ::: #code ```mdc ::prose-callout{variant="tip"} Here's a helpful tip: You can use keyboard shortcuts to speed up your workflow. :: ::prose-callout{variant="tip" title="Pro Tip"} Press `Cmd+K` to open the command palette and quickly navigate to any file in your project. :: ``` :: ### Note ::show-case --- prose: "" --- :::prose-callout{variant="note"} This is a general note. Use this variant for supplementary information. ::: :::prose-callout{title="Note" variant="note"} The API behavior may vary depending on your subscription plan. Check your plan details for more information. ::: #code ```mdc ::prose-callout{variant="note"} This is a general note. Use this variant for supplementary information. :: ::prose-callout{variant="note" title="Note"} The API behavior may vary depending on your subscription plan. Check your plan details for more information. :: ``` :: ### Example ::show-case --- prose: "" --- :::prose-callout{variant="example"} Here's a practical example of how to use this feature in your code. ::: :::prose-callout{title="Code Example" variant="example"} The following snippet demonstrates how to implement authentication in your application. ::: #code ```mdc ::prose-callout{variant="example"} Here's a practical example of how to use this feature in your code. :: ::prose-callout{variant="example" title="Code Example"} The following snippet demonstrates how to implement authentication in your application. :: ``` :: ## Filled Style Use the `filled` prop to create a more prominent callout with solid background colors: ::show-case --- prose: "" --- :::prose-callout{filled filled="" title="Filled Info" variant="info"} This is a filled info callout with solid colors. ::: :::prose-callout{filled filled="" title="Filled Success" variant="success"} This is a filled success callout with solid colors. ::: :::prose-callout{filled filled="" title="Filled Warning" variant="warning"} This is a filled warning callout with solid colors. ::: :::prose-callout{filled filled="" title="Filled Error" variant="error"} This is a filled error callout with solid colors. ::: #code ```mdc ::prose-callout{variant="info" filled title="Filled Info"} This is a filled info callout with solid colors. :: ::prose-callout{variant="success" filled title="Filled Success"} This is a filled success callout with solid colors. :: ::prose-callout{variant="warning" filled title="Filled Warning"} This is a filled warning callout with solid colors. :: ::prose-callout{variant="error" filled title="Filled Error"} This is a filled error callout with solid colors. :: ``` :: ## Custom Icons Override the default icon for any variant: ::show-case --- prose: "" --- :::prose-callout{icon="lucide:rocket" variant="info"} Custom icon callouts let you match the icon to your specific use case. ::: :::prose-callout --- icon: lucide:trophy title: Achievement Unlocked variant: success --- You've earned a new badge! Keep up the great work. ::: :::prose-callout{icon="lucide:zap" title="Performance Tip" variant="tip"} Enable caching to improve your application's load time by up to 70%. ::: #code ```mdc ::prose-callout{variant="info" icon="lucide:rocket"} Custom icon callouts let you match the icon to your specific use case. :: ::prose-callout{variant="success" icon="lucide:trophy" title="Achievement Unlocked"} You've earned a new badge! Keep up the great work. :: ::prose-callout{variant="tip" icon="lucide:zap" title="Performance Tip"} Enable caching to improve your application's load time by up to 70%. :: ``` :: ## With Title and Description ::show-case --- prose: "" --- :::prose-callout --- description: Follow these steps to set up your development environment and start building your application. title: Getting Started variant: info --- ::: :::prose-callout --- description: Version 2.0 introduces breaking changes. Please review the migration guide before upgrading. title: Breaking Change variant: warning --- ::: #code ```mdc ::prose-callout{variant="info" title="Getting Started" description="Follow these steps to set up your development environment and start building your application."} :: ::prose-callout{variant="warning" title="Breaking Change" description="Version 2.0 introduces breaking changes. Please review the migration guide before upgrading."} :: ``` :: ## Clickable Callouts Make callouts clickable by adding a `url` prop ::show-case --- prose: "" --- :::prose-callout --- description: Click to view the complete documentation. title: Documentation url: /components/accordion variant: info --- ::: :::prose-callout --- description: Visit our website for tutorials and guides. target: \_blank title: Learn More url: https://example.com variant: tip --- ::: #code ```mdc ::prose-callout{variant="info" title="Documentation" url="/components/accordion" description="Click to view the complete documentation."} :: ::prose-callout{variant="tip" title="Learn More" url="https://example.com" target="\_blank" description="Visit our website for tutorials and guides."} :: ``` :: ## Complex Content Callouts support rich content including lists, code, and formatting ::show-case --- prose: "" --- :::prose-callout{title="Installation Steps" variant="example"} Follow these steps to install the package: 1. Install the package: `npm install my-package` 2. Import in your app: `import { MyComponent } from 'my-package'` 3. Use the component: `` **Note:** Make sure you have Node.js 18+ installed. ::: :::prose-callout{title="Best Practices" variant="tip"} Here are some recommendations: - Keep your components small and focused - Write tests for critical functionality - Use TypeScript for better type safety - Document your code with JSDoc comments For more details, check the [style guide](https://uithing.com/docs/style-guide). ::: #code ```mdc ::prose-callout{variant="example" title="Installation Steps"} Follow these steps to install the package: 1. Install the package: `npm install my-package` 2. Import in your app: `import { MyComponent } from 'my-package'` 3. Use the component: `` **Note:** Make sure you have Node.js 18+ installed. :: ::prose-callout{variant="tip" title="Best Practices"} Here are some recommendations: - Keep your components small and focused - Write tests for critical functionality - Use TypeScript for better type safety - Document your code with JSDoc comments For more details, check the [style guide](/docs/style-guide). :: ``` :: ## Props ### Component Props | Prop | Type | Default | Description | | :----------------- | :---------------------------------------------------------------------------------- | :---------- | :--------------------------------------------------------- | | `variant` | `"default" | "info" | "success" | "warning" | "error" | "tip" | "note" | "example"` | `"default"` | Visual style variant | | `filled` | `boolean` | `false` | Use filled/solid background style | | `title` | `string` | - | Title text for the callout | | `description` | `string` | - | Description text (can also use default slot) | | `icon` | `string` | Auto | Icon name (auto-selected based on variant if not provided) | | `url` | `string` | - | Make the callout clickable with this URL | | `target` | `"_self" | "_blank" | "_parent" | "_top"` | `"_self"` | Link target (use `_blank` for external links) | | `class` | `string` | - | Additional CSS classes for wrapper | | `titleClass` | `string` | - | Additional CSS classes for title | | `descriptionClass` | `string` | - | Additional CSS classes for description | | `iconClass` | `string` | - | Additional CSS classes for icon | ### Default Icons by Variant | Variant | Icon | | :-------- | :---------------------- | | `default` | `lucide:info` | | `info` | `lucide:info` | | `success` | `lucide:circle-check` | | `warning` | `lucide:triangle-alert` | | `error` | `lucide:circle-x` | | `tip` | `lucide:lightbulb` | | `note` | `lucide:sticky-note` | | `example` | `lucide:code-2` | ## Slots The component provides three slots for maximum flexibility: | Slot | Description | | :-------- | :---------------------------------------------------- | | `default` | Main content area (overrides `description` prop) | | `title` | Title content (overrides `title` prop) | | `icon` | Icon content (overrides `icon` prop and variant icon) | ## Vue Component Usage You can also use the Callout component in your Vue files: ::show-case --- prose: "" --- :::docs-callout ::: #code ```vue [DocsCallout.vue] ``` :: ## Styling The component uses Tailwind Variants for styling. You can override any part using the class props: ```vue Fully customizable styling ``` ## Examples in Context ### Documentation Page ::show-case --- prose: "" --- :::prose-callout{title="Before You Begin" variant="info"} This guide assumes you have basic knowledge of Vue.js and TypeScript. If you're new to these technologies, we recommend reviewing the official documentation first. ::: #code ```mdc ::prose-callout{variant="info" title="Before You Begin"} This guide assumes you have basic knowledge of Vue.js and TypeScript. If you're new to these technologies, we recommend reviewing the official documentation first. :: ``` :: ### Migration Guide ::show-case --- prose: "" --- :::prose-callout ### Breaking Changes in v2.0 The following breaking changes require updates to your code: - `theme` prop renamed to `variant` - `color` prop removed (use `variant` instead) - Default icon size changed from 20px to 24px ::: #### API Documentation :::prose-callout{title="Rate Limiting" variant="note"} This endpoint is rate-limited to 100 requests per minute per API key. Exceeding this limit will result in a 429 error. ::: #### Tutorial :::prose-callout{icon="lucide:sparkles" title="Quick Tip" variant="tip"} You can use the keyboard shortcut `Cmd + /` to quickly toggle comments in your code editor. ::: #### Error Handling :::prose-callout --- target: \_blank title: Authentication Failed url: https://example.com variant: error --- Your session has expired. Please log in again to continue. ::: #code ```mdc ::prose-callout ### Breaking Changes in v2.0 The following breaking changes require updates to your code: - `theme` prop renamed to `variant` - `color` prop removed (use `variant` instead) - Default icon size changed from 20px to 24px :: #### API Documentation ::prose-callout{variant="note" title="Rate Limiting"} This endpoint is rate-limited to 100 requests per minute per API key. Exceeding this limit will result in a 429 error. :: #### Tutorial ::prose-callout{variant="tip" icon="lucide:sparkles" title="Quick Tip"} You can use the keyboard shortcut `Cmd + /` to quickly toggle comments in your code editor. :: #### Error Handling ::prose-callout{variant="error" title="Authentication Failed" url="https://example.com" target="\_blank"} Your session has expired. Please log in again to continue. :: ``` :: # Card ## Overview The `ProseCard` component creates visually appealing cards with a subtle animated border beam effect on hover. Cards can be static content containers or interactive links, making them perfect for feature highlights, navigation menus, and content organization. ::prose-callout{title="Features" variant="info"} - **Animated Border Beam** - Subtle glowing border animation on hover - **Link Support** - Works as NuxtLink with `to` or `href` props - **Flexible Slots** - Customize icon, title, description, and footer - **Icon Support** - Built-in icon display - **Accessible** - Semantic HTML structure with proper link handling - **Customizable** - Add custom classes for additional styling :: ## Basic Usage Create a simple card with title and description: ::show-case --- prose: "" --- :::prose-card --- description: Learn the basics of using this component library with step-by-step tutorials and examples. title: Getting Started --- ::: #code ```mdc ::prose-card{title="Getting Started" description="Learn the basics of using this component library with step-by-step tutorials and examples."} :: ``` :: ## With Icon Add an icon to make cards more visually distinctive: ::show-case --- prose: "" --- :::prose-card --- description: Get up and running in minutes with our automated setup process and sensible defaults. icon: lucide:rocket title: Quick Setup --- ::: #code ```mdc ::prose-card{icon="lucide:rocket" title="Quick Setup" description="Get up and running in minutes with our automated setup process and sensible defaults."} :: ``` :: ## As Link Make cards clickable by adding a `to` or `href` prop. The card will render as a NuxtLink: ::show-case --- prose: "" --- :::prose-card --- description: Explore our comprehensive guides and API references. icon: lucide:book-open title: Documentation to: https://uithing.com/getting-started/introduction --- ::: #code ```mdc ::prose-card{to="/getting-started/introduction" icon="lucide:book-open" title="Documentation" description="Explore our comprehensive guides and API references."} :: ``` :: ## External Link Link to external URLs using the `href` prop: ::show-case --- prose: "" --- :::prose-card --- description: View the source code and contribute to the project. href: https://github.com icon: lucide:github target: \_blank title: GitHub --- ::: #code ```mdc ::prose-card{href="https://github.com" target="_blank" icon="lucide:github" title="GitHub" description="View the source code and contribute to the project."} :: ``` :: ## With Markdown Content Use the default slot for rich markdown content: ::show-case --- prose: "" --- :::prose-card{icon="lucide:code" title="Developer Experience"} Built with modern tools and best practices: - TypeScript for type safety - Tailwind CSS for styling - Nuxt 3 for performance - Accessible by default Hover to see the animated border effect! ✨ ::: #code ```mdc ::prose-card{icon="lucide:code" title="Developer Experience"} Built with modern tools and best practices: - TypeScript for type safety - Tailwind CSS for styling - Nuxt 3 for performance - Accessible by default Hover to see the animated border effect! ✨ :: ``` :: ## Custom Title Slot Override the title with custom markdown formatting: ::show-case --- prose: "" --- :::prose-card --- icon: lucide:sparkles --- Check out the latest updates including dark mode, improved animations, and better accessibility. #title [**New** in Version 2.0] ::: #code ```mdc ::prose-card{icon="lucide:sparkles"} Check out the latest updates including dark mode, improved animations, and better accessibility. #title [**New** in Version 2.0] :: ``` :: ## With Footer Slot Add additional content at the bottom of the card using the footer slot: ::show-case --- prose: "" --- :::prose-card --- description: View a fully functional dashboard with charts, tables, and interactive components. icon: lucide:layout-dashboard title: Dashboard Example --- #footer [View Example →](https://uithing.com/examples/dashboard){.text-sm} ::: #code ```mdc ::prose-card{icon="lucide:layout-dashboard" title="Dashboard Example" description="View a fully functional dashboard with charts, tables, and interactive components."} #footer [View Example →](/examples/dashboard){.text-sm} :: ``` :: ## Card Grid Display multiple cards in a responsive grid layout: ::show-case --- prose: "" --- :::div{.grid.gap-4.sm:grid-cols-2} ::::prose-card --- description: Optimized for speed with lazy loading and tree-shaking support. icon: lucide:zap title: Fast Performance to: https://uithing.com/components --- :::: ::::prose-card --- description: Full TypeScript support with comprehensive type definitions. icon: lucide:shield-check title: Type Safe to: https://uithing.com/components --- :::: ::::prose-card --- description: Customizable with Tailwind CSS and CSS variables. icon: lucide:palette title: Themeable to: https://uithing.com/components --- :::: ::::prose-card --- description: WCAG compliant with proper ARIA attributes and keyboard navigation. icon: lucide:accessibility title: Accessible to: https://uithing.com/components --- :::: ::::prose-card --- description: Import only what you need with tree-shakeable components. icon: lucide:package title: Modular to: https://uithing.com/components --- :::: ::::prose-card --- description: Comprehensive guides with live examples and best practices. icon: lucide:book-open title: Well Documented to: https://uithing.com/components --- :::: ::: #code ```mdc
::prose-card{to="/components" icon="lucide:zap" title="Fast Performance" description="Optimized for speed with lazy loading and tree-shaking support."} :: ::prose-card{to="/components" icon="lucide:shield-check" title="Type Safe" description="Full TypeScript support with comprehensive type definitions."} :: ::prose-card{to="/components" icon="lucide:palette" title="Themeable" description="Customizable with Tailwind CSS and CSS variables."} :: ::prose-card{to="/components" icon="lucide:accessibility" title="Accessible" description="WCAG compliant with proper ARIA attributes and keyboard navigation."} :: ::prose-card{to="/components" icon="lucide:package" title="Modular" description="Import only what you need with tree-shakeable components."} :: ::prose-card{to="/components" icon="lucide:book-open" title="Well Documented" description="Comprehensive guides with live examples and best practices."} ::
``` :: ## Feature Showcase Highlight key features with rich content: ::show-case --- prose: "" --- :::div{.grid.gap-6.md:grid-cols-2} ::::prose-card --- icon: lucide:layout-dashboard --- Pre-built dashboard components for quick prototyping: - Charts and graphs - Data tables - Statistics cards - Activity feeds [View Examples →](https://uithing.com/examples/dashboard) #title #### Dashboard Components :::: ::::prose-card --- icon: lucide:form-input --- Everything you need for complex forms: - Input validation - File uploads - Date pickers - Multi-select [View Components →](https://uithing.com/components/form) #title #### Form Components :::: ::: #code ```mdc
::prose-card{icon="lucide:layout-dashboard"} Pre-built dashboard components for quick prototyping: - Charts and graphs - Data tables - Statistics cards - Activity feeds [View Examples →](/examples/dashboard) #title #### Dashboard Components :: ::prose-card{icon="lucide:form-input"} Everything you need for complex forms: - Input validation - File uploads - Date pickers - Multi-select [View Components →](/components/form) #title #### Form Components ::
``` :: ## Use Cases ::prose-callout{title="Perfect For" variant="tip"} - **Feature Highlights** - Showcase product features with icons and descriptions - **Navigation Menus** - Create engaging navigation with linked cards - **Resource Links** - Direct users to guides, examples, or external resources - **Documentation Sections** - Organize docs into clickable category cards - **Service Listings** - Display services or offerings in an attractive grid - **Call-to-Actions** - Highlight important actions or pages - **Content Previews** - Teasers for articles, examples, or pages :: ## Best Practices ### 1. Use Meaningful Icons Choose icons that clearly represent the card's content: ```mdc ::prose-card{icon="lucide:shield-check" title="Security"} ::prose-card{icon="lucide:circle" title="Security"} ``` ### 2. Keep Titles Concise Short, punchy titles work best: ```mdc ::prose-card{title="Quick Setup"} ::prose-card{title="How to Quickly Set Up Your Development Environment"} ``` ### 3. Balance Grid Layouts Use appropriate grid columns for screen sizes: ```mdc
``` # Code Collapse ## Overview The `ProseCodeCollapse` component wraps code blocks and provides a toggle button to expand or collapse content. It's ideal for lengthy code examples that would take up too much vertical space, starting at a fixed height with a gradient fade effect. ::prose-callout{title="Features" variant="info"} - **Clean Toggle** - Simple expand/collapse functionality - **Gradient Fade** - Visual indicator when content is collapsed - **Customizable Labels** - Configure button text and labels - **Accessible** - Proper ARIA attributes for screen readers - **Smart Defaults** - Works great out of the box with sensible defaults :: ## Basic Usage Wrap any code block to make it collapsible: ::show-case --- prose: "" --- :::prose-code-collapse ::::prose-code-snippet --- file: /plugins/mermaid.client.ts language: ts title: Mermaid Plugin --- :::: ::: #code ```mdc ::prose-code-collapse ::prose-code-snippet{file="/plugins/mermaid.client.ts" language="ts" title="Mermaid Plugin"} :: :: ``` :: ## Custom Labels Customize the button text and name: ::show-case --- prose: "" --- :::prose-code-collapse{close-text="Hide" name="Implementation" open-text="Show"} ```vue ``` ::: #code ````mdc ::prose-code-collapse{name="Implementation" openText="Show" closeText="Hide"} ```vue ``` :: ```` :: ## With Code Snippet Combine with `::prose-code-snippet` to show actual source files: ::show-case --- prose: "" --- :::prose-code-collapse{name="Full Source"} ::::prose-code-snippet --- file: /composables/useFormField.ts language: ts title: useFormField Composable --- :::: ::: #code ```mdc ::prose-code-collapse{name="Full Source"} ::prose-code-snippet{file="/composables/useFormField.ts" language="typescript" title="useFormField Composable"} :: :: ``` :: ## Custom Icon Change the toggle icon: ::show-case --- prose: "" --- :::prose-code-collapse{icon="lucide:code" name="Example"} ::::prose-code-snippet --- file: /components/Ui/Chip.vue language: vue title: Chip Component --- :::: ::: #code ```mdc ::prose-code-collapse{icon="lucide:code" name="Example"} ::prose-code-snippet{file="/components/Ui/Chip.vue" language="vue" title="Chip Component"} :: :: ``` :: ## Props | Prop | Type | Default | Description | | :---------- | :------- | :---------------------- | :------------------------------------------------------- | | `icon` | `string` | `"lucide:chevron-down"` | Icon displayed on the toggle button | | `name` | `string` | `"Code"` | Name/label shown in the button text | | `openText` | `string` | `"Expand"` | Text shown when code is collapsed (clickable to expand) | | `closeText` | `string` | `"Collapse"` | Text shown when code is expanded (clickable to collapse) | | `class` | `string` | - | Additional CSS classes for the root container | ## Behavior ### Initial State - Code starts **collapsed** at 200px height - Gradient fade overlay indicates more content below - Button shows: "{openText} {name}" (e.g., "Expand Code") ### Expanded State - Code expands to full height (max 80vh) - Gradient fade removed - Button shows: "{closeText} {name}" (e.g., "Collapse Code") ## Accessibility The component includes proper accessibility features: - **ARIA Attributes**: `aria-expanded` indicates current state - **ARIA Labels**: `aria-label` provides context for screen readers - **Keyboard Support**: Button is focusable and clickable via keyboard - **Icon Decoration**: Chevron icon is marked `aria-hidden="true"` - **Semantic HTML**: Uses proper button element for interaction ## Use Cases ::prose-callout{title="When to Use Code Collapse" variant="tip"} - **Long Examples** - Code snippets over \~30 lines - **Complete Files** - Full component implementations - **Optional Details** - Advanced examples users can expand if needed - **Tutorial Code** - Progressive disclosure of complex solutions - **API References** - Full endpoint implementations :: ## Best Practices 1. **Use Descriptive Names** - Make it clear what's being collapsed ```mdc ::prose-code-collapse{name="Full Implementation"} ``` 2. **Customize Button Text** - Match your documentation tone ```mdc ::prose-code-collapse{openText="Show" closeText="Hide"} ``` 3. **Combine with Snippets** - Keep docs in sync with source ```mdc ::prose-code-collapse ::prose-code-snippet{file="/path/to/file.vue"} :: :: ``` 4. **Use Sparingly** - Don't collapse everything; save for truly long code 5. **Consider Context** - Some readers want full code upfront, others prefer collapsed ## Related Components ::prose-icon-list [**ProseCodeSnippet**](https://uithing.com/prose/code-snippet) - Import code from files or URL [**ProseCodeGroup**](https://uithing.com/prose/code-group) - Tabbed code snippets [**ProseCodeTree**](https://uithing.com/prose/code-tree) - Interactive file tree with code preview :: # Code Group ## Overview The `ProseCodeGroup` component creates a tabbed interface for displaying multiple code blocks. It's perfect for showing the same functionality in different languages, comparing implementations, or displaying related configuration files side by side. ::prose-callout{title="Features" variant="info"} - **Automatic Language Icons** - Detects language from code fence and shows appropriate icon - **Custom Icons** - Override with custom icons per tab - **Tab Sync** - Synchronize selections across multiple code groups - **Search Functionality** - Quick tab search for groups with many options - **Responsive Design** - Works seamlessly on all screen sizes :: ## Basic Usage Use the `::prose-code-group` wrapper with code fences. The filename in brackets becomes the tab label: ::show-case --- prose: "" --- :::prose-code-group ```vue [app.vue] noFormat ``` ```vue [pages/index.vue] noFormat ``` ::: #code ````mdc ::prose-code-group ```vue [app.vue] noFormat ``` ```vue [pages/index.vue] noFormat ``` :: ```` :: ## Multi-Language Examples ### Component Implementation Show how to create the same component in different frameworks: ::show-case --- prose: "" --- :::prose-code-group ```vue [Vue 3] hideHeader // hideHeader removes the name in the pre component ``` ```tsx [React] hideHeader import { useState } from "react"; export default function Counter() { const [count, setCount] = useState(0); return ; } ``` ```svelte [Svelte] hideHeader ``` ```tsx [Solid] hideHeader import { createSignal } from "solid-js"; export default function Counter() { const [count, setCount] = createSignal(0); return ; } ``` ::: #code ````mdc ::prose-code-group ```vue [Vue 3] hideHeader // hideHeader removes the name in the pre component ``` ```tsx [React] hideHeader import { useState } from 'react' export default function Counter() { const [count, setCount] = useState(0) return ( ) } ``` ```svelte [Svelte] hideHeader ``` ```tsx [Solid] hideHeader // Hide header removes the name in the pre component import { createSignal } from 'solid-js' export default function Counter() { const [count, setCount] = createSignal(0) return ( ) } ``` :: ```` :: ### API Requests Compare different HTTP client libraries: ::prose-code-group ```ts [Fetch API] hideHeader async function getUser(id: string) { const response = await fetch(`/api/users/${id}`); if (!response.ok) { throw new Error("Failed to fetch user"); } return response.json(); } ``` ```ts [Axios] hideHeader import axios from "axios"; async function getUser(id: string) { const { data } = await axios.get(`/api/users/${id}`); return data; } ``` ```ts [Ky] hideHeader import ky from "ky"; async function getUser(id: string) { return ky.get(`/api/users/${id}`).json(); } ``` ```ts [ofetch] hideHeader import { ofetch } from "ofetch"; async function getUser(id: string) { return ofetch(`/api/users/${id}`); } ``` :: ## Configuration Files ### Framework Setup Show related configuration files together: ::prose-code-group ```ts [nuxt.config.ts] hideHeader export default defineNuxtConfig({ modules: ["@nuxtjs/tailwindcss", "@nuxt/content"], content: { highlight: { theme: "github-dark", }, }, }); ``` ```js [tailwind.config.js] hideHeader export default { content: ["./components/**/*.{vue,js,ts}", "./layouts/**/*.vue", "./pages/**/*.vue", "./app.vue"], theme: { extend: {}, }, }; ``` ```json [package.json] hideHeader { "name": "my-app", "scripts": { "dev": "nuxt dev", "build": "nuxt build", "preview": "nuxt preview" }, "dependencies": { "nuxt": "^3.13.0", "@nuxt/content": "^2.13.0" } } ``` ```json [tsconfig.json] hideHeader { "extends": "./.nuxt/tsconfig.json", "compilerOptions": { "strict": true, "types": ["@nuxt/types"] } } ``` :: ### Environment Variables ::prose-code-group ```bash [.env] hideHeader DATABASE_URL=postgresql://localhost:5432/mydb REDIS_URL=redis://localhost:6379 JWT_SECRET=your-secret-key API_KEY=your-api-key ``` ```bash [.env.example] hideHeader DATABASE_URL= REDIS_URL= JWT_SECRET= API_KEY= ``` ```ts [env.d.ts] hideHeader declare global { namespace NodeJS { interface ProcessEnv { DATABASE_URL: string; REDIS_URL: string; JWT_SECRET: string; API_KEY: string; } } } export {}; ``` :: ## Synced Code Groups Use the `sync` prop to keep tab selections synchronized across multiple code groups on the same page: ### Installation ::prose-code-group{sync="package-manager"} ```bash [npm] hideHeader icon="devicon:npm" npm install ui-thing@latest ``` ```bash [pnpm] hideHeader icon="devicon:pnpm" pnpm add ui-thing@latest ``` ```bash [yarn] hideHeader icon="devicon:yarn" yarn add ui-thing@latest ``` ```bash [bun] hideHeader icon="devicon:bun" bun add ui-thing@latest ``` :: ### Run Dev Server ::prose-code-group{sync="package-manager"} ```bash [npm] hideHeader icon="devicon:npm" npm run dev ``` ```bash [pnpm] hideHeader icon="devicon:pnpm" pnpm dev ``` ```bash [yarn] hideHeader icon="devicon:yarn" yarn dev ``` ```bash [bun] hideHeader icon="devicon:bun" bun dev ``` :: ::prose-callout{title="Try It!" variant="tip"} Click between tabs above - both groups stay synchronized because they use `sync="package-manager"`. :: ## Custom Icons Override default language icons with custom ones: ::show-case --- prose: "" --- :::prose-code-group ```ts [server.ts] icon="lucide:server" import express from "express"; const app = express(); const PORT = 3000; app.get("/", (req, res) => { res.json({ message: "Hello World" }); }); app.listen(PORT); ``` ```ts [client.ts] icon="lucide:smartphone" async function fetchData() { const response = await fetch("/api/data"); return response.json(); } ``` ```ts [database.ts] icon="lucide:database" import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); export async function getUsers() { return prisma.user.findMany(); } ``` ::: #code ````mdc ::prose-code-group ```ts [server.ts] icon="lucide:server" import express from 'express' const app = express() const PORT = 3000 app.get('/', (req, res) => { res.json({ message: 'Hello World' }) }) app.listen(PORT) ``` ```ts [client.ts] icon="lucide:smartphone" async function fetchData() { const response = await fetch('/api/data') return response.json() } ``` ```ts [database.ts] icon="lucide:database" import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() export async function getUsers() { return prisma.user.findMany() } ``` :: ```` :: ## Testing Examples ### Unit Tests ::prose-code-group ```ts [component.test.ts] import { mount } from "@vue/test-utils"; import { describe, expect, it } from "vitest"; import MyButton from "./MyButton.vue"; describe("MyButton", () => { it("renders correctly", () => { const wrapper = mount(MyButton, { props: { label: "Click me" }, }); expect(wrapper.text()).toBe("Click me"); }); it("emits click event", async () => { const wrapper = mount(MyButton); await wrapper.trigger("click"); expect(wrapper.emitted("click")).toBeTruthy(); }); }); ``` ```ts [utils.test.ts] import { describe, expect, it } from "vitest"; import { calculateTotal, formatDate } from "./utils"; describe("Utils", () => { it("formats date correctly", () => { const date = new Date("2024-01-15"); expect(formatDate(date)).toBe("Jan 15, 2024"); }); it("calculates total", () => { expect(calculateTotal([10, 20, 30])).toBe(60); }); }); ``` ```ts [api.test.ts] import { describe, expect, it, vi } from "vitest"; import { getUser } from "./api"; describe("API", () => { it("fetches user successfully", async () => { global.fetch = vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ id: 1, name: "John" }), }) ) as any; const user = await getUser("1"); expect(user.name).toBe("John"); }); }); ``` :: ## Database Schemas ### Prisma Schema ::prose-code-group ```prisma [schema.prisma] datasource db { provider = "postgresql" url = env("DATABASE_URL") } generator client { provider = "prisma-client-js" } model User { id Int @id @default(autoincrement()) email String @unique name String? posts Post[] createdAt DateTime @default(now()) } model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId Int createdAt DateTime @default(now()) } ``` ```sql [migration.sql] CREATE TABLE "User" ( "id" SERIAL PRIMARY KEY, "email" TEXT NOT NULL UNIQUE, "name" TEXT, "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE "Post" ( "id" SERIAL PRIMARY KEY, "title" TEXT NOT NULL, "content" TEXT, "published" BOOLEAN NOT NULL DEFAULT false, "authorId" INTEGER NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY ("authorId") REFERENCES "User"("id") ); ``` ```ts [types.ts] export interface User { id: number; email: string; name: string | null; posts: Post[]; createdAt: Date; } export interface Post { id: number; title: string; content: string | null; published: boolean; author: User; authorId: number; createdAt: Date; } ``` :: ## Styling Examples ### CSS Solutions ::prose-code-group ```css [styles.css] .button { padding: 0.5rem 1rem; border-radius: 0.25rem; background: #3b82f6; color: white; border: none; cursor: pointer; transition: background 0.2s; } .button:hover { background: #2563eb; } .button:disabled { opacity: 0.5; cursor: not-allowed; } ``` ```scss [styles.scss] .button { padding: 0.5rem 1rem; border-radius: 0.25rem; background: #3b82f6; color: white; border: none; cursor: pointer; transition: background 0.2s; &:hover { background: #2563eb; } &:disabled { opacity: 0.5; cursor: not-allowed; } } ``` ```vue [Scoped CSS] ``` ```ts [Tailwind] const buttonClasses = [ "px-4 py-2", "rounded", "bg-blue-500", "text-white", "border-none", "cursor-pointer", "transition-colors", "hover:bg-blue-600", "disabled:opacity-50", "disabled:cursor-not-allowed", ].join(" "); ``` :: ## Props | Prop | Type | Default | Description | | :------------------ | :-------- | :---------------- | :------------------------------------------------ | | `inStack` | `boolean` | `false` | Whether the code group is in a stack layout | | `sync` | `string` | - | Sync identifier for syncing with other tab groups | | `padded` | `boolean` | `true` | Whether to add padding around the tabs | | `disableSearch` | `boolean` | `false` | Disable the search functionality | | `searchPlaceholder` | `string` | `'Search Tab...'` | Placeholder text for the search input | | `searchEmpty` | `string` | `'No tab found.'` | Text to display when no tab is found | | `comboBoxFullWidth` | `boolean` | `false` | Whether the combobox should take full width | | `class` | `string` | - | Additional classes to add to the wrapper | ## Syntax ### Basic Structure ````mdc ::prose-code-group ```language [Tab Name] code here ``` ```language [Another Tab] more code ``` :: ```` ### With Props ````mdc ::prose-code-group{sync="my-group" padded=false} ```ts [Option 1] const a = 1 ``` ```ts [Option 2] const b = 2 ``` :: ```` ### With Icons ````mdc ::prose-code-group ```ts [server.ts] icon="lucide:server" // server code ``` ```ts [client.ts] icon="lucide:smartphone" // client code ``` :: ```` ## Search Functionality For code groups with many tabs, users can search: ::prose-code-group ```ts [auth.ts] export async function login(email: string, password: string) { // Login logic } ``` ```ts [user.ts] export async function getUser(id: string) { // Get user logic } ``` ```ts [post.ts] export async function createPost(data: any) { // Create post logic } ``` ```ts [comment.ts] export async function addComment(postId: string, text: string) { // Add comment logic } ``` ```ts [profile.ts] export async function updateProfile(userId: string, data: any) { // Update profile logic } ``` ```ts [settings.ts] export async function updateSettings(settings: any) { // Update settings logic } ``` ```ts [notification.ts] export async function sendNotification(userId: string, message: string) { // Send notification logic } ``` ```ts [analytics.ts] export async function trackEvent(event: string, data: any) { // Track event logic } ``` :: ::prose-callout{title="Search Tips" variant="tip"} When you have 5 or more tabs, the `Combobox` variant is automatically used to help users find tabs quickly. :: ## Real-World Use Cases ### API Routes ::prose-code-group ```ts [GET /api/users] noFormat export default defineEventHandler(async (event) => { const users = await prisma.user.findMany(); return users; }); ``` ```ts [GET /api/users/[id\\]] noFormat export default defineEventHandler(async (event) => { const id = getRouterParam(event, "id"); const user = await prisma.user.findUnique({ where: { id: Number(id) }, }); if (!user) { throw createError({ statusCode: 404, message: "User not found", }); } return user; }); ``` ```ts [POST /api/users] noFormat export default defineEventHandler(async (event) => { const body = await readBody(event); const user = await prisma.user.create({ data: body, }); return user; }); ``` ```ts [PUT /api/users/[id\\]] noFormat export default defineEventHandler(async (event) => { const id = getRouterParam(event, "id"); const body = await readBody(event); const user = await prisma.user.update({ where: { id: Number(id) }, data: body, }); return user; }); ``` ```ts [DELETE /api/users/[id\\]] noFormat export default defineEventHandler(async (event) => { const id = getRouterParam(event, "id"); await prisma.user.delete({ where: { id: Number(id) }, }); return { success: true }; }); ``` :: ### Docker Setup ::prose-code-group ```dockerfile [Dockerfile] FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build EXPOSE 3000 CMD ["node", ".output/server/index.mjs"] ``` ```yaml [docker-compose.yml] version: "3.8" services: app: build: . ports: - "3000:3000" environment: - DATABASE_URL=postgresql://postgres:password@db:5432/mydb - NODE_ENV=production depends_on: - db - redis db: image: postgres:16-alpine environment: - POSTGRES_PASSWORD=password - POSTGRES_DB=mydb volumes: - postgres_data:/var/lib/postgresql/data redis: image: redis:7-alpine volumes: - redis_data:/data volumes: postgres_data: redis_data: ``` ```yaml [.dockerignore] node_modules .nuxt .output .git .env .env.* *.log ``` :: ### GitHub Actions ::prose-code-group ```yaml [test.yml] name: Test on: push: branches: [main] pull_request: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npm test ``` ```yaml [deploy.yml] name: Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npm run build - name: Deploy to production run: | # Deploy command here env: API_KEY: ${{ secrets.API_KEY }} ``` ```yaml [lint.yml] name: Lint on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npm run lint ``` :: ## Best Practices ::prose-callout{title="Tips for Code Groups" variant="tip"} - Use descriptive tab names that clearly indicate what the code does - Keep the number of tabs reasonable (5-10 max for best UX) - Use `sync` prop when showing package manager commands across multiple groups - Add custom icons to make tabs more visually distinct - Use `noFormat` meta flag if you want to preserve exact filename formatting - Use `hideHeader` meta flag if you want to hide the tab header - Consider grouping related code (configs, routes, tests) together :: ## Accessibility The component provides excellent keyboard navigation: - **Tab** - Move between tabs - **Enter/Space** - Activate selected tab - **Arrow Keys** - Navigate tabs in the list - **Type to Search** - Quick search when many tabs are present Screen readers announce tab labels and active states properly. ## Vue Component Usage You can also use it programmatically in Vue files: ```vue ``` ## Related Components ::prose-icon-list :::prose-li{icon="lucide:table-2"} [**ProseTabs**](https://uithing.com/prose/tabs) - General-purpose tabbed interface ::: :::prose-li{icon="lucide:workflow"} [**ProseMermaid**](https://uithing.com/prose/mermaid) - Diagram rendering in code blocks ::: :: # Code Snippet ## Overview The `ProseCodeSnippet` component allows you to reference actual source files from your project or external URLs, ensuring your documentation always shows the latest code without manual updates. Perfect for keeping docs in sync with your codebase. ::prose-callout{title="Features" variant="info"} - **Dynamic Imports** - Load code directly from your project files - **External URLs** - Fetch code from GitHub, GitLab, or any URL - **Line Extraction** - Show specific line ranges from large files - **Syntax Highlighting** - Full language support via Shiki - **Auto-sync** - Documentation updates automatically when source code changes - **Performance** - Lazy loads files only when needed :: ::prose-callout{title="Build Consideration" variant="warning"} Files must match the `import.meta.glob` patterns in the component. The current setup includes all `.vue`, `.ts`, `.css`, and `.json` files from `/app/**` (excluding test files). Adjust patterns as needed for your use case. :: ## Basic Usage Import a component from your project: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /components/Ui/Button.vue language: vue title: Button Component --- ::: #code ```mdc ::prose-code-snippet{file="/components/Ui/Button.vue" language="vue" title="Button Component"} :: ``` :: ## Import Project Files ### Vue Components Show your actual component code: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /components/Ui/Card/Card.vue language: vue title: Card.vue --- ::: #code ```mdc ::prose-code-snippet{file="/components/Ui/Card/Card.vue" language="vue" title="Card.vue"} :: ``` :: ### TypeScript Utilities Reference utility functions: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /utils/colors.ts language: ts title: Color Utilities --- ::: #code ```mdc ::prose-code-snippet{file="/utils/colors.ts" language="ts" title="Color Utilities"} :: ``` :: ### Composables Display your composable logic: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /composables/usePm.ts language: ts meta: noFormat title: usePm Composable --- ::: #code ```mdc ::prose-code-snippet{file="/composables/usePm.ts" language="ts" title="usePm Composable" meta="noFormat"} :: ``` :: ## Extract Specific Lines Use `start` and `offset` to show only relevant portions of large files: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /components/Ui/Button.vue language: vue offset: "31" start: 137 title: Button Props --- ::: #code ```mdc ::prose-code-snippet{file="/components/Ui/Button.vue" language="vue" title="Button Props" start="137" offset="31"} :: ``` :: The example above starts at line 137 and shows the next 31 lines. ## Highlight Lines Combine with the `highlights` prop to emphasize important code: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /components/Ui/Button.vue highlights: 2,4-6,10 language: vue meta: lines offset: "31" start: 137 title: Button Props --- ::: #code ```mdc ::prose-code-snippet{file="/components/Ui/Button.vue" language="vue" title="Button Props" start="137" offset="31" highlights="2,4-6,10" meta="lines"} :: ``` :: ## External URLs ### GitHub Raw Content Load code directly from GitHub: ::show-case --- prose: "" --- :::prose-code-snippet --- language: ts meta: lines noFormat title: Nuxt useState Source url: https://raw.githubusercontent.com/nuxt/nuxt/refs/heads/main/packages/nuxt/src/app/composables/state.ts --- ::: #code ```mdc ::prose-code-snippet{url="https://raw.githubusercontent.com/nuxt/nuxt/refs/heads/main/packages/nuxt/src/app/composables/state.ts" language="ts" title="Nuxt useState Source" meta="lines noFormat"} :: ``` :: ### External Examples Pull examples from documentation sites or CDNs. This example fetches the Vue 3 ESM build from a CDN and displays lines 1-20: ::show-case --- prose: "" --- :::prose-code-snippet --- language: js meta: lines offset: "20" start: 1 title: Vue 3 ESM Build url: https://unpkg.com/vue@3/dist/vue.esm-browser.js --- ::: #code ```mdc ::prose-code-snippet{url="https://unpkg.com/vue@3/dist/vue.esm-browser.js" language="js" title="Vue 3 ESM Build" start="1" offset="20" meta="lines"} :: ``` :: ### Style Guide Show your actual CSS/Tailwind configuration: ::show-case{prose prose=""} :::prose-code-snippet --- file: /assets/css/tailwind.css language: css title: Tailwind Base Styles --- ::: :: ### Migration Guides Show before and after by referencing different file versions or branches: ```mdc ## Migration from v1 to v2 ### Old API (v1) ::prose-code-snippet{url="https://raw.githubusercontent.com/yourorg/yourrepo/v1/src/api.ts" language="typescript" title="Old API"} :: ### New API (v2) ::prose-code-snippet{file="/app/utils/api.ts" language="typescript" title="New API"} :: ### Changes The new API uses fetch instead of axios and includes better error handling. ``` ### Tutorial Series Create step-by-step tutorials showing progressive code changes: ```mdc ## Step 1: Create Basic Component ::prose-code-snippet{file="/app/components/Tutorial/Step1.vue" language="vue" title="Step 1: Basic Setup"} :: ## Step 2: Add Props ::prose-code-snippet{file="/app/components/Tutorial/Step2.vue" language="vue" title="Step 2: With Props"} :: ## Step 3: Add State Management ::prose-code-snippet{file="/app/components/Tutorial/Step3.vue" language="vue" title="Step 3: Complete"} :: ``` ## Advanced Meta Options Use the `meta` prop to pass additional options to the code block: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /composables/useDocPage.ts language: ts meta: icon=lucide:package noFormat lines title: useDocPage Composable --- ::: #code ```mdc ::prose-code-snippet{file="/composables/useDocPage.ts" language="ts" title="useDocPage Composable" meta="icon=lucide:package noFormat lines"} :: ``` :: Available meta options: - `icon=` - Custom file icon - `noFormat` - Disable code formatting - `lines` - Show line numbers - `noHeader` - Hide title header ## Extract Function Definitions Show just a specific function from a large file: ::show-case --- prose: "" --- :::prose-code-snippet --- file: /utils/colors.ts language: ts offset: "8" start: 45 title: hexToRgb Function --- ::: #code ```mdc ::prose-code-snippet{file="/utils/colors.ts" language="ts" title="hexToRgb Function" start="45" offset="8"} :: ``` :: ## Multiple File Comparison Compare related files side by side using tabs: ::show-case --- prose: "" --- :::prose-tabs{variant="line"} ::::div{label="Button Component"} :::::prose-code-snippet --- file: /components/Ui/Button.vue language: vue title: Button Component --- ::::: :::: ::::div{label="Badge Component"} :::::prose-code-snippet --- file: /components/Ui/Badge.vue language: vue title: Badge Component --- ::::: :::: ::::div{label="Divider Component"} :::::prose-code-snippet --- file: /components/Ui/Divider.vue language: vue title: Divider Component --- ::::: :::: ::: #code ```mdc :::prose-tabs{variant="line"} ::div{label="Button Component"} ::prose-code-snippet{file="/components/Ui/Button.vue" language="vue" title="Button Component"} :: :: ::div{label="Badge Component"} ::prose-code-snippet{file="/components/Ui/Badge.vue" language="vue" title="Badge Component"} :: :: ::div{label="Divider Component"} ::prose-code-snippet{file="/components/Ui/Divider.vue" language="vue" title="Divider Component"} :: :: ::: ``` :: ## Props | Prop | Type | Default | Description | | :----------- | :------- | :----------- | :------------------------------------------------------------------- | | `file` | `string` | - | Relative path to a file in your project (must match glob patterns) | | `url` | `string` | - | External URL to fetch code from | | `language` | `string` | **required** | Programming language for syntax highlighting | | `title` | `string` | - | Optional title displayed above the code block | | `highlights` | `string` | - | Line numbers or ranges to highlight (e.g., `"1,3-5,10"`) | | `meta` | `string` | - | Additional metadata passed to ProsePre (e.g., `"icon=vue noFormat"`) | | `start` | `number` | - | Starting line number to extract (1-indexed) | | `offset` | `number` | - | Number of lines to extract from the starting line | ## Syntax ### Basic Import ```mdc ::prose-code-snippet{file="/app/components/Button.vue" language="vue"} :: ``` ### With Title ```mdc ::prose-code-snippet{file="/app/utils/helpers.ts" language="typescript" title="Helper Functions"} :: ``` ### With Line Extraction ```mdc ::prose-code-snippet{file="/app/app.vue" language="vue" start="10" offset="5"} :: ``` ### From URL ```mdc ::prose-code-snippet{url="https://example.com/code.js" language="javascript" title="External Example"} :: ``` ::prose-callout{title="Extending Patterns" variant="tip"} To include more directories, edit the `import.meta.glob` array in `ProseCodeSnippet.global.vue`. :: ## Performance Considerations ### Bundle Size Impact The `import.meta.glob` pattern includes files in your build. Be strategic: **✅ Good Practices:** - Use specific file extensions: `*.{vue,ts}` instead of `*` - Exclude test files: `!**/*.test.ts` - Only include directories you'll reference in docs - Use `eager: false` for lazy loading (already configured) **❌ Avoid:** - Overly broad patterns like `/app/**/*` (includes everything) - Including asset files (images, videos) - Globbing node\_modules or build outputs ### Current Configuration Impact With the default patterns (`/app/**/*.{vue,ts,css,json}`), expect: - **Small projects** (<100 files): \~100-200KB added to bundle - **Medium projects** (100-500 files): \~200KB-1MB added to bundle - **Large projects** (500+ files): 1MB+ added to bundle Files are lazy-loaded, so only referenced snippets are downloaded to the client. ### URL Fetching for Large Files For very large files or files outside your project: ```mdc ::prose-code-snippet{url="/api/files/large-schema.json" language="json"} :: ``` This avoids bundling and fetches on-demand. ## Error Handling The component handles errors gracefully: ### File Not Found ```mdc ::prose-code-snippet{file="/app/nonexistent.ts" language="typescript"} :: ``` Shows error callout: "Cannot load code: /app/nonexistent.ts" ::prose-callout{title="Code Snippet Error" variant="error"} Cannot load code: `/app/nonexistent.ts` :: ### Invalid URL ```mdc ::prose-code-snippet{url="https://invalid-url-404.com/code.js" language="javascript"} :: ``` Shows error callout with the URL. ::prose-callout{title="Code Snippet Error" variant="error"} Cannot load code: `https://invalid-url-404.com/code.js` :: ## Best Practices ::prose-callout{title="Documentation Tips" variant="tip"} 1. **Keep Docs in Sync** - Reference actual source files instead of copying code 2. **Show Relevant Code** - Use `start` and `offset` to show only what matters 3. **Add Context** - Always use `title` to explain what the code does 4. **Highlight Key Lines** - Use `highlights` to draw attention to important parts 5. **Version Control** - Reference specific branches/tags in URLs for stable examples 6. **Test Paths** - Ensure file paths match your glob patterns 7. **Performance** - For large apps, consider creating a `/docs-examples/` directory with curated files :: ## Common Patterns ### Tutorial with Progressive Examples ```mdc ## Build a User Card ### 1. Basic Structure ::prose-code-snippet{file="/app/examples/tutorial/UserCard-1.vue" language="vue" title="Step 1: Basic HTML"} :: ### 2. Add Styling ::prose-code-snippet{file="/app/examples/tutorial/UserCard-2.vue" language="vue" title="Step 2: With Tailwind"} :: ### 3. Make Interactive ::prose-code-snippet{file="/app/examples/tutorial/UserCard-3.vue" language="vue" title="Step 3: Complete Component"} :: ``` ### API Endpoint Documentation ````mdc ## Users API ### List Users ::prose-code-snippet{file="/server/api/users/index.get.ts" language="typescript" title="GET /api/users"} :: **Response:** ```json { "data": [...], "total": 100, "page": 1, "limit": 10 } ``` ### Get Single User ::prose-code-snippet{file="/server/api/users/[id].get.ts" language="typescript" title="GET /api/users/:id"} :: ```` ### Component Anatomy ```mdc ## Understanding the Button Component The button component consists of three main files: ::prose-code-snippet{file="/app/components/Ui/Button/Button.vue" language="vue" title="Component Implementation"} :: ::prose-code-snippet{file="/app/components/Ui/Button/types.ts" language="typescript" title="TypeScript Types"} :: ::prose-code-snippet{file="/app/components/Ui/Button/index.ts" language="typescript" title="Public API"} :: ``` # Code Tree ## Overview The `ProseCodeTree` component renders an interactive file tree navigator that displays code files in a two-panel layout. The left panel shows the directory structure with expandable folders, while the right panel displays the selected file's content with syntax highlighting. ::prose-callout{title="Features" variant="info"} - **Interactive Navigation** - Click folders to expand/collapse, click files to view content - **Material Icons** - Beautiful file and folder icons based on file extensions - **Auto-expansion** - Automatically expands path to selected file - **Keyboard Accessible** - Full keyboard navigation support - **Responsive** - Adapts to mobile and desktop screens - **Sort Intelligence** - Folders first, then alphabetically :: ## Basic Usage ::show-case --- prose: "" --- :::prose-code-tree{default-value="app.vue" title="Simple Vue App"} ```vue [app.vue] ``` ```ts [utils.ts] export function greet(name: string) { return `Hello, ${name}!`; } ``` ::: #code ````mdc ::prose-code-tree{defaultValue="app.vue" title="Simple Vue App"} ```vue [app.vue] ``` ```ts [utils.ts] export function greet(name: string) { return `Hello, ${name}!` } ``` :: ```` :: ## Project Showcase Show a complete project structure: ::show-case --- prose: "" --- :::prose-code-tree{default-value="src/main.ts" title="TypeScript React App"} ```tsx [src/App.tsx] import { useState } from "react"; import "./App.css"; function App() { const [count, setCount] = useState(0); return (

Counter: {count}

); } export default App; ``` ```ts [src/main.ts] import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' ReactDOM.createRoot( document.getElementById('root')! ).render( , ) ``` ```ts [src/vite-env.d.ts] /// ``` ```css [src/App.css] .App { text-align: center; padding: 2rem; } button { padding: 0.5rem 1rem; font-size: 1rem; background: #646cff; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background: #535bf2; } ``` ```css [src/index.css] :root { font-family: Inter, system-ui, sans-serif; line-height: 1.5; font-weight: 400; } body { margin: 0; min-height: 100vh; } ``` ```html [index.html] React App
``` ```json [package.json] { "name": "react-app", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc && vite build", "preview": "vite preview" }, "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": { "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", "typescript": "^5.5.3", "vite": "^5.4.2" } } ``` ```json [tsconfig.json] { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] } ``` ::: #code ````mdc ::prose-code-tree{defaultValue="src/main.ts" title="TypeScript React App"} ```tsx [src/App.tsx] import { useState } from 'react' import './App.css' function App() { const [count, setCount] = useState(0) return (

Counter: {count}

) } export default App ``` ```ts [src/main.ts] import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' ReactDOM.createRoot( document.getElementById('root')! ).render( , ) ``` ```ts [src/vite-env.d.ts] /// ``` ```css [src/App.css] .App { text-align: center; padding: 2rem; } button { padding: 0.5rem 1rem; font-size: 1rem; background: #646cff; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background: #535bf2; } ``` ```css [src/index.css] :root { font-family: Inter, system-ui, sans-serif; line-height: 1.5; font-weight: 400; } body { margin: 0; min-height: 100vh; } ``` ```html [index.html] React App
``` ```json [package.json] { "name": "react-app", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc && vite build", "preview": "vite preview" }, "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": { "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", "typescript": "^5.5.3", "vite": "^5.4.2" } } ``` ```json [tsconfig.json] { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] } ``` :: ```` :: ## Expand All Folders Use `expandAll` to show the full structure at once: ::show-case --- prose: "" --- :::prose-code-tree{expand-all expand-all="" title="API Routes"} ```ts [server/api/users/index.get.ts] export default defineEventHandler(async (event) => { const users = await prisma.user.findMany(); return users; }); ``` ```ts [server/api/users/[id\\].get.ts] export default defineEventHandler(async (event) => { const id = getRouterParam(event, "id"); const user = await prisma.user.findUnique({ where: { id: Number(id) }, }); if (!user) { throw createError({ statusCode: 404, message: "User not found", }); } return user; }); ``` ```ts [server/api/users/index.post.ts] export default defineEventHandler(async (event) => { const body = await readBody(event); const user = await prisma.user.create({ data: body, }); return user; }); ``` ```ts [server/api/posts/index.get.ts] export default defineEventHandler(async (event) => { const posts = await prisma.post.findMany({ include: { author: true }, }); return posts; }); ``` ::: #code ````mdc ::prose-code-tree{expandAll title="API Routes"} ```ts [server/api/users/index.get.ts] export default defineEventHandler(async (event) => { const users = await prisma.user.findMany() return users }) ``` ```ts [server/api/users/[id].get.ts] export default defineEventHandler(async (event) => { const id = getRouterParam(event, 'id') const user = await prisma.user.findUnique({ where: { id: Number(id) } }) if (!user) { throw createError({ statusCode: 404, message: 'User not found' }) } return user }) ``` ```ts [server/api/users/index.post.ts] export default defineEventHandler(async (event) => { const body = await readBody(event) const user = await prisma.user.create({ data: body }) return user }) ``` ```ts [server/api/posts/index.get.ts] export default defineEventHandler(async (event) => { const posts = await prisma.post.findMany({ include: { author: true } }) return posts }) ``` :: ```` :: ## Component Library Structure Perfect for documenting UI component libraries: ::show-case --- prose: "" --- :::prose-code-tree --- default-value: components/Button/Button.vue title: Component Library --- ```vue [components/Button/Button.vue] ``` ```ts [components/Button/types.ts] export interface ButtonProps { variant?: "primary" | "secondary" | "outline"; size?: "sm" | "md" | "lg"; disabled?: boolean; } ``` ```ts [components/Button/index.ts] export { default as Button } from "./Button.vue"; export type { ButtonProps } from "./types"; ``` ```vue [components/Input/Input.vue] ``` ```ts [components/Input/types.ts] export interface InputProps { modelValue?: string; type?: "text" | "email" | "password"; placeholder?: string; } ``` ```ts [components/Input/index.ts] export { default as Input } from "./Input.vue"; export type { InputProps } from "./types"; ``` ```ts [components/index.ts] export * from "./Button"; export * from "./Input"; ``` ::: #code ````mdc ::prose-code-tree{defaultValue="components/Button/Button.vue" title="Component Library"} ```vue [components/Button/Button.vue] ``` ```ts [components/Button/types.ts] export interface ButtonProps { variant?: 'primary' | 'secondary' | 'outline' size?: 'sm' | 'md' | 'lg' disabled?: boolean } ``` ```ts [components/Button/index.ts] export { default as Button } from './Button.vue' export type { ButtonProps } from './types' ``` ```vue [components/Input/Input.vue] ``` ```ts [components/Input/types.ts] export interface InputProps { modelValue?: string type?: 'text' | 'email' | 'password' placeholder?: string } ``` ```ts [components/Input/index.ts] export { default as Input } from './Input.vue' export type { InputProps } from './types' ``` ```ts [components/index.ts] export * from './Button' export * from './Input' ``` :: ```` :: ## Configuration Files Show configuration setups: ::show-case --- prose: "" --- :::prose-code-tree{default-value="vite.config.ts" title="Build Configuration"} ```ts [vite.config.ts] import { resolve } from "path"; import vue from "@vitejs/plugin-vue"; import { defineConfig } from "vite"; export default defineConfig({ plugins: [vue()], resolve: { alias: { "@": resolve(__dirname, "src"), }, }, build: { outDir: "dist", sourcemap: true, }, }); ``` ```json [tsconfig.json] { "compilerOptions": { "target": "ES2020", "module": "ESNext", "lib": ["ES2020", "DOM"], "moduleResolution": "bundler", "paths": { "@/*": ["./src/*"] }, "strict": true }, "include": ["src/**/*"] } ``` ```js [tailwind.config.js] export default { content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"], theme: { extend: { colors: { primary: "#646cff", }, }, }, plugins: [], }; ``` ```js [eslint.config.js] import js from "@eslint/js"; import typescript from "@typescript-eslint/eslint-plugin"; import vue from "eslint-plugin-vue"; export default [ js.configs.recommended, { files: ["**/*.{ts,tsx,vue}"], plugins: { "@typescript-eslint": typescript, vue: vue, }, rules: { "no-console": "warn", "no-debugger": "warn", }, }, ]; ``` ::: #code ````mdc ::prose-code-tree{defaultValue="vite.config.ts" title="Build Configuration"} ```ts [vite.config.ts] import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': resolve(__dirname, 'src'), }, }, build: { outDir: 'dist', sourcemap: true, }, }) ``` ```json [tsconfig.json] { "compilerOptions": { "target": "ES2020", "module": "ESNext", "lib": ["ES2020", "DOM"], "moduleResolution": "bundler", "paths": { "@/*": ["./src/*"] }, "strict": true }, "include": ["src/**/*"] } ``` ```js [tailwind.config.js] export default { content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"], theme: { extend: { colors: { primary: "#646cff", }, }, }, plugins: [], }; ``` ```js [eslint.config.js] import js from "@eslint/js"; import typescript from "@typescript-eslint/eslint-plugin"; import vue from "eslint-plugin-vue"; export default [ js.configs.recommended, { files: ["**/*.{ts,tsx,vue}"], plugins: { "@typescript-eslint": typescript, vue: vue, }, rules: { "no-console": "warn", "no-debugger": "warn", }, }, ]; ``` :: ```` :: ## API Documentation Document API endpoints: ::show-case --- prose: "" --- :::prose-code-tree{default-value="routes/auth.ts" title="API Endpoints"} ```ts [routes/auth.ts] import { Router } from "express"; import { login, logout, register } from "../controllers/auth"; const router = Router(); router.post("/login", login); router.post("/register", register); router.post("/logout", logout); export default router; ``` ```ts [routes/users.ts] import { Router } from "express"; import { createUser, deleteUser, getUser, getUsers, updateUser } from "../controllers/users"; import { authenticate } from "../middleware/auth"; const router = Router(); router.get("/", authenticate, getUsers); router.get("/:id", authenticate, getUser); router.post("/", authenticate, createUser); router.put("/:id", authenticate, updateUser); router.delete("/:id", authenticate, deleteUser); export default router; ``` ```ts [routes/index.ts] import { Router } from "express"; import authRoutes from "./auth"; import userRoutes from "./users"; const router = Router(); router.use("/auth", authRoutes); router.use("/users", userRoutes); export default router; ``` ::: #code ````mdc ::prose-code-tree{defaultValue="routes/auth.ts" title="API Endpoints"} ```ts [routes/auth.ts] import { Router } from 'express' import { login, register, logout } from '../controllers/auth' const router = Router() router.post('/login', login) router.post('/register', register) router.post('/logout', logout) export default router ``` ```ts [routes/users.ts] import { Router } from 'express' import { getUsers, getUser, createUser, updateUser, deleteUser } from '../controllers/users' import { authenticate } from '../middleware/auth' const router = Router() router.get('/', authenticate, getUsers) router.get('/:id', authenticate, getUser) router.post('/', authenticate, createUser) router.put('/:id', authenticate, updateUser) router.delete('/:id', authenticate, deleteUser) export default router ``` ```ts [routes/index.ts] import { Router } from 'express' import authRoutes from './auth' import userRoutes from './users' const router = Router() router.use('/auth', authRoutes) router.use('/users', userRoutes) export default router ``` :: ```` :: ## Testing Structure Show test organization: ::show-case --- prose: "" --- :::prose-code-tree{default-value="tests/unit/utils.test.ts" title="Test Suite"} ```ts [tests/unit/utils.test.ts] import { calculateTotal, formatDate } from "@/utils"; import { describe, expect, it } from "vitest"; describe("Utils", () => { describe("formatDate", () => { it("formats date correctly", () => { const date = new Date("2024-01-15"); expect(formatDate(date)).toBe("Jan 15, 2024"); }); }); describe("calculateTotal", () => { it("calculates sum of numbers", () => { expect(calculateTotal([10, 20, 30])).toBe(60); }); it("returns 0 for empty array", () => { expect(calculateTotal([])).toBe(0); }); }); }); ``` ```ts [tests/unit/components/Button.test.ts] import Button from "@/components/Button.vue"; import { mount } from "@vue/test-utils"; import { describe, expect, it } from "vitest"; describe("Button", () => { it("renders correctly", () => { const wrapper = mount(Button, { props: { label: "Click me" }, }); expect(wrapper.text()).toBe("Click me"); }); it("emits click event", async () => { const wrapper = mount(Button); await wrapper.trigger("click"); expect(wrapper.emitted("click")).toBeTruthy(); }); it("applies variant class", () => { const wrapper = mount(Button, { props: { variant: "primary" }, }); expect(wrapper.classes()).toContain("button--primary"); }); }); ``` ```ts [tests/integration/api.test.ts] import app from "@/app"; import request from "supertest"; import { describe, expect, it } from "vitest"; describe("API Integration", () => { describe("GET /api/users", () => { it("returns list of users", async () => { const response = await request(app).get("/api/users"); expect(response.status).toBe(200); expect(Array.isArray(response.body)).toBe(true); }); }); describe("POST /api/users", () => { it("creates new user", async () => { const userData = { email: "test@example.com", name: "Test User", }; const response = await request(app).post("/api/users").send(userData); expect(response.status).toBe(201); expect(response.body.email).toBe(userData.email); }); }); }); ``` ```ts [tests/setup.ts] import { afterAll, afterEach, beforeAll } from "vitest"; import { server } from "./mocks/server"; beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); ``` ::: #code ````mdc ::prose-code-tree{defaultValue="tests/unit/utils.test.ts" title="Test Suite"} ```ts [tests/unit/utils.test.ts] import { describe, it, expect } from 'vitest' import { formatDate, calculateTotal } from '@/utils' describe('Utils', () => { describe('formatDate', () => { it('formats date correctly', () => { const date = new Date('2024-01-15') expect(formatDate(date)).toBe('Jan 15, 2024') }) }) describe('calculateTotal', () => { it('calculates sum of numbers', () => { expect(calculateTotal([10, 20, 30])).toBe(60) }) it('returns 0 for empty array', () => { expect(calculateTotal([])).toBe(0) }) }) }) ``` ```ts [tests/unit/components/Button.test.ts] import { describe, it, expect } from 'vitest' import { mount } from '@vue/test-utils' import Button from '@/components/Button.vue' describe('Button', () => { it('renders correctly', () => { const wrapper = mount(Button, { props: { label: 'Click me' } }) expect(wrapper.text()).toBe('Click me') }) it('emits click event', async () => { const wrapper = mount(Button) await wrapper.trigger('click') expect(wrapper.emitted('click')).toBeTruthy() }) it('applies variant class', () => { const wrapper = mount(Button, { props: { variant: 'primary' } }) expect(wrapper.classes()).toContain('button--primary') }) }) ``` ```ts [tests/integration/api.test.ts] import { describe, it, expect } from 'vitest' import request from 'supertest' import app from '@/app' describe('API Integration', () => { describe('GET /api/users', () => { it('returns list of users', async () => { const response = await request(app).get('/api/users') expect(response.status).toBe(200) expect(Array.isArray(response.body)).toBe(true) }) }) describe('POST /api/users', () => { it('creates new user', async () => { const userData = { email: 'test@example.com', name: 'Test User' } const response = await request(app) .post('/api/users') .send(userData) expect(response.status).toBe(201) expect(response.body.email).toBe(userData.email) }) }) }) ``` ```ts [tests/setup.ts] import { beforeAll, afterAll, afterEach } from 'vitest' import { server } from './mocks/server' beforeAll(() => server.listen()) afterEach(() => server.resetHandlers()) afterAll(() => server.close()) ``` :: ```` :: ## Props | Prop | Type | Default | Description | | :------------- | :-------- | :------ | :-------------------------------------------------------------------------- | | `defaultValue` | `string` | - | Default file path to select on mount (e.g., `"src/main.ts"`) | | `expandAll` | `boolean` | `false` | Expand all directories by default instead of just the path to selected file | | `title` | `string` | - | Optional title displayed above the file tree | | `class` | `string` | - | Additional CSS classes for the root container | ## Syntax ### Basic Structure ````mdc ::prose-code-tree ```language [path/to/file.ext] code content ``` ```language [another/file.ext] more code ``` :: ```` ### With Props ````mdc ::prose-code-tree{defaultValue="src/App.vue" title="My Project"} ```vue [src/App.vue] ``` :: ```` ### With Expand All ````mdc ::prose-code-tree{expandAll title="Full Structure"} ```ts [src/utils/helpers.ts] export function helper() {} ``` :: ```` ## File Path Format The file path in brackets `[path/to/file.ext]` determines the tree structure: - `file.txt` - Root level file - `folder/file.txt` - File inside folder - `folder/subfolder/file.txt` - Nested structure - Folders are created automatically from paths - Files are sorted alphabetically within folders - Folders always appear before files ## Keyboard Navigation The component supports full keyboard navigation: - **Arrow Up/Down** - Navigate between files and folders - **Arrow Right** - Expand folder - **Arrow Left** - Collapse folder - **Enter/Space** - Select file or toggle folder - **Tab** - Move focus to next interactive element - **Home** - Jump to first item - **End** - Jump to last item ## Accessibility Features The component is built with accessibility in mind: ✅ **Semantic HTML** - Uses `