npm package: @saali2901/sa-ui
Description: Vue.js free to use UI-Library
Author: saali
Latest version: 2.1.0

# Sa UI

A lightweight, accessible Vue 3 component library built with TypeScript, Tailwind CSS 4 and Tailwind Variants.

## Features

- 29 ready-to-use components
- Written in Vue 3 `<script setup>` + TypeScript
- Styled with Tailwind CSS 4 & Tailwind Variants
- Tree-shakable ESM & UMD builds
- Full type declarations out of the box
- Unit tests with Vitest
- Interactive docs with Histoire


## Installation

```bash
npm install @saali2901/sa-ui
```

### Peer dependencies

The library requires the following peer dependencies:

```bash
npm install vue lucide-vue-next tailwind-merge
```

| Package            | Version  |
| ------------------ | -------- |
| `vue`              | `≥ 3.2`  |
| `lucide-vue-next`  | `≥ 0.400`|
| `tailwind-merge`   | `≥ 2.0`  |

## Components

### Layout

| Component | Description |
| --- | --- |
| [SaAccordion](src/components/SaAccordion/SaAccordion.md) | Collapsible content panels |
| [SaCard](src/components/SaCard/SaCard.md) | Content container with image, title, body and actions |
| [SaDivider](src/components/SaDivider/SaDivider.md) | Visual separator (horizontal/vertical) |
| [SaModal](src/components/SaModal/SaModal.md) | Accessible modal dialog with focus trap |
| [SaTabs](src/components/SaTabs/SaTabs.md) | Tab navigation with underline and pills variants |

### Navigation

| Component | Description |
| --- | --- |
| [SaBreadcrumb](src/components/SaBreadcrumb/SaBreadcrumb.md) | Breadcrumb trail with configurable separator |
| [SaDropdown](src/components/SaDropdown/SaDropdown.md) | Select dropdown with keyboard support |
| [SaPagination](src/components/SaPagination/SaPagination.md) | Page navigation with ellipsis |
| [SaStepper](src/components/SaStepper/SaStepper.md) | Step indicator for multi-step workflows |

### Data Entry

| Component | Description |
| --- | --- |
| [SaButton](src/components/SaButton/SaButton.md) | Button with size, color, disabled and loading states |
| [SaCalendar](src/components/SaCalendar/SaCalendar.md) | Date picker calendar with i18n support |
| [SaCheckbox](src/components/SaCheckbox/SaCheckbox.md) | Accessible checkbox with custom styling |
| [SaFormField](src/components/SaFormField/SaFormField.md) | Form wrapper with label, error and hint |
| [SaInput](src/components/SaInput/SaInput.md) | Text input with label and error state |
| [SaRadio](src/components/SaRadio/SaRadio.md) | Radio button group |
| [SaSwitch](src/components/SaSwitch/SaSwitch.md) | Toggle switch with size variants |
| [SaTextarea](src/components/SaTextarea/SaTextarea.md) | Multi-line text input |
| [SaUploadArea](src/components/SaUploadArea/SaUploadArea.md) | Drag-and-drop file upload area |

### Data Display

| Component | Description |
| --- | --- |
| [SaAvatar](src/components/SaAvatar/SaAvatar.md) | User avatar with image or initials fallback |
| [SaBadge](src/components/SaBadge/SaBadge.md) | Small status indicator or label |
| [SaCarousel](src/components/SaCarousel/SaCarousel.md) | Slide-based carousel with autoplay |
| [SaTable](src/components/SaTable/SaTable.md) | Data table with sorting and empty state |
| [SaTag](src/components/SaTag/SaTag.md) | Small colored chip, optionally removable |
| [SaTooltip](src/components/SaTooltip/SaTooltip.md) | Hover/focus tooltip |

### Feedback

| Component | Description |
| --- | --- |
| [SaAlert](src/components/SaAlert/SaAlert.md) | Colored banner for important messages |
| [SaProgress](src/components/SaProgress/SaProgress.md) | Progress bar with label |
| [SaSkeleton](src/components/SaSkeleton/SaSkeleton.md) | Loading placeholder |
| [SaSpinner](src/components/SaSpinner/SaSpinner.md) | CSS-based loading spinner |
| [SaToast](src/components/SaToast/SaToast.md) | Programmatic toast notifications |

## Usage

### Option 1 – Vue Plugin (register all components globally)

```ts
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import SaUI from "@saali2901/sa-ui";
import "@saali2901/sa-ui/style.css";

const app = createApp(App);
app.use(SaUI);
app.mount("#app");
```

All components are now available in any template without additional imports:

```vue
<template>
  <SaButton color="primary" @click="handleClick">Click me</SaButton>
  <SaInput v-model="name" placeholder="Enter name" />
</template>
```

### Option 2 – Import individual components (tree-shaking)

```ts
// main.ts
import "@saali2901/sa-ui/style.css";
```

```vue
<script setup lang="ts">
import { SaButton, SaInput } from "@saali2901/sa-ui";
</script>

<template>
  <SaButton color="primary" @click="handleClick">Click me</SaButton>
  <SaInput v-model="name" placeholder="Enter name" />
</template>
```

> **Note:** The CSS (`@saali2901/sa-ui/style.css`) must be imported once in either variant – typically in `main.ts` or your root layout.

### TypeScript Types

All prop types are included and can be imported as needed:

```ts
import type {
  AccordionItem,
  BreadcrumbItem,
  DropdownOption,
  TabItem,
  TableColumn,
  StepperStep,
  RadioOption,
  ToastMessage,
} from "@saali2901/sa-ui";
```

### Composables

```ts
import { useClickOutside, useId, useToast } from "@saali2901/sa-ui";
```

| Composable        | Description                                      |
| ----------------- | ------------------------------------------------ |
| `useClickOutside` | Detect clicks/touches outside a target element   |
| `useId`           | Generate unique IDs for a11y attribute linkage   |
| `useToast`        | Programmatic toast API via provide/inject        |

#### Toast Plugin (optional)

Instead of using template refs, install the plugin globally:

```ts
import { SaToastPlugin } from "@saali2901/sa-ui";
app.use(SaToastPlugin);
```

Then use anywhere:

```vue
<script setup>
import { useToast } from "@saali2901/sa-ui";
const toast = useToast();
toast.add("success", "Saved!", 4000);
</script>
```

## Accessibility

All interactive components follow WAI-ARIA best practices:

- Proper `role`, `aria-*`, and keyboard support
- Auto-generated ID linkage (`for`/`id`, `aria-controls`, `aria-labelledby`)
- Focus management and restoration (modals, dropdowns)
- Screen reader announcements (`aria-live`, `role="alert"`)

See each component's `.md` file for specific a11y details.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding guidelines, and PR process.

## License

MIT