@asdfprah/doro-ui
v2.0.0
Published
Collection of Vue 3 components to copy into your project and use as the base for your own UI
Maintainers
Readme
doro-ui
A personal collection of Vue 3 components that you copy into your project and own. A small CLI adds the source of each component, with its dependencies and imports already adapted, to the folders you choose. From there your team can use them as they are or change them freely.
Documentation and live examples
Requirements
- Vue 3.5 or newer
- Tailwind CSS 4
- Node 22.18 or newer to run the CLI
- TypeScript is recommended; components are written in TypeScript with
<script setup>
Getting started
npm install -D @asdfprah/doro-ui
npx doro-ui initinit asks where components, composables and utilities go, the import alias of your source
folder (@ for src by default) and how dark mode is enabled. It writes the answers to
doro.json, copies the theme and installs the base packages.
Import the theme right after Tailwind in your main CSS file:
@import 'tailwindcss';
@import './assets/doro-theme.css';Then add components:
npx doro-ui add button select modal<script setup lang="ts">
import { ref } from 'vue'
import { Button } from '@/components/ui/Button'
import { Select } from '@/components/ui/Select'
const fruit = ref<string | null>(null)
</script>
<template>
<Select v-model="fruit" :options="['Apple', 'Banana']" placeholder="Choose a fruit" />
<Button :disabled="!fruit">Continue</Button>
</template>Strict templates
Components use data-* attributes for their state. If your project type-checks templates with
strictTemplates, allow them in tsconfig.json:
{ "vueCompilerOptions": { "strictTemplates": true, "dataAttributes": ["data-*"] } }CLI
| Command | What it does |
| ------------------------- | ------------------------------------------------------------------------------------------------------ |
| doro-ui init | Creates doro.json and adds the base items (cn and theme) |
| doro-ui add [items...] | Copies items and the items they depend on, and installs their packages. Without names it lets you pick |
| doro-ui list | Lists the available items and marks the ones in your project |
| doro-ui diff [items...] | Shows how your copies differ from doro-ui; exits with 1 when they do |
| doro-ui theme check | Checks that every text color of your theme reaches WCAG AA contrast in light and dark mode |
| Option | |
| -------------------- | ------------------------------------------------------------------------------------------------------ |
| --cwd <dir> | Project root |
| -y, --yes | Use the default answers in init |
| --dark-mode <mode> | Dark mode in init: both (system preference, overridable with .dark/.light), class or media |
| -o, --overwrite | Replace files that differ from doro-ui |
| --with-tests | Also copy each item's tests |
| --no-install | Print the install command instead of running it |
Copied files are never overwritten unless you pass --overwrite; use diff to review upstream
changes first.
Theme
Every color is a CSS variable you can change in the copied theme file:
:root {
--primary: #0070e0;
}The 50–950 scale of primary, secondary and accent is computed from that one color, unless
you define some or all steps yourself (--primary-200, …). Text on each color (--primary-foreground)
is chosen automatically and can also be set. Run npx doro-ui theme check after changing colors.
Items
| Item | Type | Description |
| ----------------- | ---------- | -------------------------------------------------------------------------------------------------------------------- |
| cn | lib | Joins class values and resolves conflicting Tailwind utilities |
| theme | theme | Color tokens with scales computed from one base color, plus light and dark modes |
| spinner | component | Spinning indicator for work in progress, announced to screen readers |
| button | component | Native button with colors, variants, sizes and a loading state |
| button-group | component | Joins buttons visually and shares color, variant and size with them |
| chip | component | Pill-shaped label or badge for statuses, categories and counts |
| use-form-field | composable | Context shared between a form field and the control inside it |
| form-field | component | Label, help text and error for a form control, connected for assistive technologies |
| checkbox | component | Native checkbox with boolean or array model, indeterminate state and form field support |
| checkbox-group | component | Group of checkboxes sharing one array of selected values |
| switch | component | Animated on/off switch on a native checkbox, with form field support |
| radio-group | component | Group of native radios with one selected value, keyboard navigation and form field support |
| validator | lib | Optional rule-based validation ('required\|min_length:3') with custom rules |
| mask | lib | Pattern and number masks plus a composable that applies them to native inputs |
| input | component | Native text input with prefix and suffix slots, typed model and optional mask |
| field-styles | lib | Border, focus, error, disabled and read-only classes shared by text fields |
| textarea | component | Native multi-line text input with optional autosize between a minimum and maximum of rows |
| transition | lib | Waits for CSS transitions to end, with a timeout and reduced-motion support |
| use-scroll-lock | composable | Locks the page scroll without layout shift, supporting nested locks |
| modal | component | Accessible modal on the native dialog element with Header, Body and Footer sections |
| typography | component | Title, Subtitle, Text and Label with theme sizes and colors |
| use-dialog | composable | Native dialog lifecycle: modal or non-modal, animations, Escape, backdrop and scroll lock |
| side-sheet | component | Panel sliding from the start or end edge, modal or non-modal, with Header, Body and Footer sections |
| bottom-sheet | component | Panel sliding up from the bottom, dismissible by dragging, modal or non-modal, with Header, Body and Footer sections |
| focus | lib | Focusable element queries and Tab-order helpers |
| use-floating | composable | Positions a floating element next to an element or point, with flip, shift and scroll tracking |
| popover | component | Floating panel with any content, opened by click or as a context menu, without trigger wrappers |
| dropdown-menu | component | Accessible action menu on the Popover, as a dropdown or a context menu, with items, labels, groups and separators |
| select | component | Select and MultiSelect comboboxes with keyboard support, local or remote search, chips and form field support |
| pagination | component | Page navigation with a stable range, edge buttons, compact view for narrow containers and optional links |
| confirm | component | Global alert, confirm and prompt functions shown one at a time by a ConfirmHost mounted once |
| timing | lib | Typed debounce and throttle with cancel, flush and maxWait, plus composables that cancel on unmount |
| table | component | Native table with Caption, Head, Body, Foot, Row, Header and Data parts, sizes and a sticky header |
| link | component | Themed link, underlined or with the look of a Button, with Vue Router support and safe external links |
Run npx doro-ui list for the list that matches your installed version.
Development
npm install
npm run check # lint, format, type check and tests
npm run build # builds the CLI into dist/cli
npm run doro-ui -- add button --cwd ../some-project # runs the CLI from source
npm run docs:dev # documentation site with live examplesComponents live in registry/, the CLI in cli/, the documentation in docs/, and
repository-only tests in test/. The API tables of the documentation are generated from the
JSDoc of each component's types.ts.
License
ISC
