Button
Multi-variant button with loading states and icon support.
The packages/ui directory contains a collection of reusable Vue components styled with TailwindCSS 4. These components follow a similar pattern to shadcn/ui - providing primitives that you can copy, customize, and own.
Button
Multi-variant button with loading states and icon support.
Input
Text input with validation and label support.
Select
Dropdown select with search and multi-select options.
Dialog
Modal dialog with header, body, and footer slots.
Drawer
Slide-out panel for side content.
Tabs
Tab navigation component.
Steps
Multi-step wizard component.
Card
Content container with header and sections.
| Component | Description |
|---|---|
| Accordion | Expandable/collapsible content sections |
| Badge | Small status indicators and labels |
| Button | Interactive buttons with variants |
| Card | Content container with header, body, footer |
| Checkbox | Boolean input control |
| Dialog | Modal popup windows |
| Drawer | Slide-out side panels |
| Input | Text input fields |
| JsonViewer | JSON data display component |
| Label | Form field labels |
| Menu | Dropdown menu lists |
| Select | Dropdown selection |
| Skeleton | Loading placeholder |
| Steps | Multi-step wizard |
| Switch | Toggle switch control |
| Table | Data table display |
| Tabs | Tab navigation |
| Textarea | Multi-line text input |
These components are used internally within ion-components. Import them directly:
// In ion-components source filesimport { Button } from '@/packages/ui';import { Steps } from '@/packages/ui';import Tabs from '@/packages/ui/Tabs/Tabs.vue';import { SelectForm, type Item } from '@/packages/ui/Select';<script setup>import { Button } from '@/packages/ui';</script>
<template> <!-- Primary button --> <Button variant="primary">Submit</Button>
<!-- Secondary button --> <Button variant="secondary">Cancel</Button>
<!-- Danger button --> <Button variant="danger">Delete</Button>
<!-- Loading state --> <Button :loading="true">Processing...</Button>
<!-- Outlined style --> <Button variant="primary" outlined>Outline</Button>
<!-- Icon button --> <Button as="icon"> <PlusIcon /> </Button></template><script setup>import { SelectForm, type Item } from '@/packages/ui/Select';import { ref } from 'vue';
const selected = ref('');const options: Item[] = [ { label: 'Option 1', value: 'opt1' }, { label: 'Option 2', value: 'opt2' }, { label: 'Option 3', value: 'opt3', description: 'With description' },];</script>
<template> <SelectForm v-model="selected" :options="options" placeholder="Select an option..." /></template><script setup>import { Steps } from '@/packages/ui';import { ref } from 'vue';
const currentStep = ref(0);const steps = [ { title: 'Account', description: 'Create your account' }, { title: 'Profile', description: 'Add profile details' }, { title: 'Review', description: 'Confirm information' },];</script>
<template> <Steps :steps="steps" :current="currentStep" @change="currentStep = $event" />
<!-- Step content --> <div v-if="currentStep === 0">Step 1 content</div> <div v-if="currentStep === 1">Step 2 content</div> <div v-if="currentStep === 2">Step 3 content</div></template><script setup>import Tabs from '@/packages/ui/Tabs/Tabs.vue';import { ref } from 'vue';
const activeTab = ref('general');const tabs = [ { id: 'general', label: 'General' }, { id: 'advanced', label: 'Advanced' }, { id: 'security', label: 'Security' },];</script>
<template> <Tabs v-model="activeTab" :tabs="tabs" />
<div v-if="activeTab === 'general'">General settings</div> <div v-if="activeTab === 'advanced'">Advanced settings</div> <div v-if="activeTab === 'security'">Security settings</div></template>packages/ui/├── index.ts # Main exports├── theme.css # Theme variables (OKLCH)├── ui.css # Global UI styles├── types.ts # Shared TypeScript types├── webcomponent.css # Styles for CE context│├── Accordion/│ └── Accordion.vue├── Badge/│ └── Badge.vue├── Button/│ ├── index.ts│ ├── Button.vue│ └── variants.ts├── Card/│ ├── Card.vue│ ├── CardHeader.vue│ ├── CardContent.vue│ └── ...├── Dialog/│ └── Dialog.vue├── Drawer/│ └── Drawer.vue├── Input/│ ├── Input.vue│ └── ...├── Select/│ ├── index.ts│ ├── Select.vue│ ├── SelectForm.vue│ └── ...├── Steps/│ ├── index.ts│ └── Steps.vue├── Switch/│ └── Switch.vue├── Tabs/│ ├── Tabs.vue│ └── Tab.vue└── ...