# PRIMEVUE_COMPONENTS — PrimeVue Component Conventions for Crewli > Authoritative reference for PrimeVue component selection, theming, forms, > and DataTable conventions in the Crewli SPA. Read this before adding or > migrating a UI component during F4 of [RFC-WS-FRONTEND-PRIMEVUE](./RFC-WS-FRONTEND-PRIMEVUE.md). > This document encodes Crewli-specific conventions; for component > reference (props, slots, events) cross-reference https://primevue.org/. **Status:** Foundation (F2). Refined incrementally by F4 sub-packages as real migration experience surfaces gaps. **Aligned to:** PrimeVue 4.5.x with the Aura preset and `@primevue/forms`. PrimeVue is installed in F3; F2 documents intent only. **Replaces:** [`VUEXY_COMPONENTS.md`](./VUEXY_COMPONENTS.md) (now a deprecation stub; deletion in F6). --- ## 1. Purpose and scope This document defines: 1. Which PrimeVue component (or Tailwind / native equivalent) replaces each Vuetify component used in the SPA today 2. The Aura theme tokens that carry Crewli's brand (teal primary, dark mode) 3. The canonical form pattern (`@primevue/forms` + Zod resolver + `` wrapper) 4. The canonical DataTable pattern (lazy / virtual / column-template conventions) 5. When to use the `pt` (pass-through) API, Tailwind utilities, or Aura tokens for customization 6. How to navigate the migration phase where Vuetify and PrimeVue both ship in the SPA simultaneously (F4a–F4d) Out of scope here: - Dependency installation steps (see [F3](./RFC-WS-FRONTEND-PRIMEVUE.md#f3--foundation-2-days)) - Per-component props/slot reference (see https://primevue.org/) - The full 75-component Vuetify usage inventory (see [MIGRATION-AUDIT-PRIMEVUE.md §1](./MIGRATION-AUDIT-PRIMEVUE.md)) --- ## 2. When to read this document | Goal | Read | |---|---| | Picking a PrimeVue equivalent for a Vuetify usage during F4 | §3 | | Customizing Crewli's brand colors / dark mode | §4 | | Writing or migrating a form | §5 | | Migrating a `` or `` | §6 | | Deciding between `pt`, Tailwind utility, or Aura token override | §7, §8 | | Working on a not-yet-migrated surface during F4 | §9 | | Understanding the test-runtime story during migration | [ARCH-TESTING.md §7](./ARCH-TESTING.md) | Cross-document relations: - [RFC-WS-FRONTEND-PRIMEVUE.md](./RFC-WS-FRONTEND-PRIMEVUE.md) — full migration plan, sprint breakdown, architectural decisions (AD-1 through AD-12), risk register - [MIGRATION-AUDIT-PRIMEVUE.md](./MIGRATION-AUDIT-PRIMEVUE.md) — Vuetify usage inventory (§1), `@core` / `@layouts` surface area (§2), form-layer inventory (§4), DataTable inventory (§6) - [VUEXY_COMPONENTS.md](./VUEXY_COMPONENTS.md) — deprecation stub; its pre-F2 content is reachable via git history (commit `1c449ff6204cae6371da08c34ea8934d6b2ffcb8`) for reference on un-migrated surfaces - [ARCH-TESTING.md](./ARCH-TESTING.md) §7 — explains why Vuetify lives in test infrastructure during the migration --- ## 3. Component mapping by category The Crewli SPA uses ~73 distinct Vuetify components today (52 with ≥3 uses, 20 long-tail with <3 uses). The tables below group them into six functional categories. Each category is followed by one paragraph on the migration spirit — direct prop translation is rarely possible, since PrimeVue's customization model is `pt` + Tailwind, not Vuetify's deep-customization slots. For component-level prop and slot reference, follow the linked PrimeVue docs URL — this document does not duplicate them. ### 3.1 Form inputs | Vuetify | PrimeVue | Reference | Notes | |---|---|---|---| | `VTextField` | `InputText` | https://primevue.org/inputtext/ | `density='compact'` → `size='small'`; wrapped via `` for label + error | | `VTextarea` | `Textarea` | https://primevue.org/textarea/ | Auto-resize via `autoResize` prop | | `VSelect` | `Select` | https://primevue.org/select/ | Renamed from `Dropdown` in v4; `:items` → `:options`, `item-title` → `optionLabel`, `item-value` → `optionValue` | | `VAutocomplete` | `AutoComplete` | https://primevue.org/autocomplete/ | Server-side: bind `@complete` instead of `:items` | | `VCombobox` | `AutoComplete` with `:multiple` | https://primevue.org/autocomplete/ | Free-text + dropdown; PrimeVue uses one component for both | | `VCheckbox` | `Checkbox` | https://primevue.org/checkbox/ | `binary` prop for single-value checkboxes | | `VRadio` / `VRadioGroup` | `RadioButton` | https://primevue.org/radiobutton/ | No group component; bind `v-model` directly to each `RadioButton` | | `VSwitch` | `ToggleSwitch` | https://primevue.org/toggleswitch/ | Renamed from `InputSwitch` in v4 | | `VOtpInput` | `InputOtp` | https://primevue.org/inputotp/ | | | `VFileInput` (rare) | `FileUpload` | https://primevue.org/fileupload/ | `mode='basic'` for inline; default for full uploader | | `VColorPicker` (2 uses) | `ColorPicker` | https://primevue.org/colorpicker/ | | | `AppDateTimePicker` (Flatpickr) | unchanged | — | Flatpickr is retained per [RFC AD-4](./RFC-WS-FRONTEND-PRIMEVUE.md#ad-4-date-layer--flatpickr-retained-in-fase-1); a thin `DateTimePicker.vue` wrapper composes Flatpickr inside `` | **Migration spirit.** Form inputs are the highest-coverage area; nearly every input flows through `` (§5). Most prop renames are trivial (`density` → `size`, `:items` → `:options`). The bigger shift is the validation contract: Vuetify's `:rules` array per field is replaced by a single Zod schema at the form level, with field-level errors surfaced through ``. See §5 for the canonical pattern. ### 3.2 Layout | Vuetify | Replacement | Notes | |---|---|---| | `VContainer` | `
` | Tailwind utility composition; no PrimeVue equivalent | | `VRow` | `
` | Tailwind grid | | `VCol cols=N md=M` | `
` | Tailwind responsive prefixes | | `VCard` | `Card` | https://primevue.org/card/ — slots: `#title`, `#subtitle`, `#content`, `#footer` | | `VCardTitle` | Card `#title` slot | Compose inside `Card` | | `VCardSubtitle` | Card `#subtitle` slot | | | `VCardText` | Card `#content` slot or `
` | Most uses are pure padding | | `VCardActions` | Card `#footer` slot | | | `VCardItem` | manual flex layout inside `Card #content` | No direct equivalent | | `VDivider` | `Divider` | https://primevue.org/divider/ — `:vertical` → `layout='vertical'` | | `VSheet` | `
` with Tailwind | No equivalent component | | `VSpacer` | `
` or surrounding `justify-between` | | | `VApp`, `VMain`, `VAppBar`, `VFooter` | layout shell rewrites | See [RFC AD-3](./RFC-WS-FRONTEND-PRIMEVUE.md#ad-3-layout-shell--filename-match-preserved-contents-rewritten); filenames preserved, contents replaced | | `VLocaleProvider` | PrimeVue `` (or app-level `app.use(PrimeVue, { locale })`) | See [RFC AD-6](./RFC-WS-FRONTEND-PRIMEVUE.md#ad-6-locale--nl-nl-via-primelocale-vue-i18n-unused) | **Migration spirit.** Most layout in PrimeVue is Tailwind, not components. `VRow`/`VCol` translates 1:1 to a 12-column Tailwind grid. `VCard` is the biggest semantic preservation — its slot model maps to PrimeVue's `Card` slot model with minor renames. Plain `
` with Tailwind utilities replaces `VSheet`, `VSpacer`, and most uses of `VContainer`. ### 3.3 Data display | Vuetify | PrimeVue / Replacement | Reference | Notes | |---|---|---|---| | `VDataTable` | `DataTable` + `Column` | https://primevue.org/datatable/ | See §6 | | `VDataTableServer` | `DataTable` with `:lazy="true"` | https://primevue.org/datatable/#lazy_load | See §6 | | `VTable` | `DataTable` (no lazy) | — | For static / pre-loaded tables | | `VList` | `Listbox` (selectable) or `DataView` (cards) | https://primevue.org/listbox/ | Context-dependent; selection lists use `Listbox`, card grids use `DataView` | | `VListItem` / `VListItemTitle` / `VListItemSubtitle` | `MenuItem` (in menu) or `
  • ` (in list) | — | Inside a list, just compose the row markup directly | | `VListSubheader` | `
  • ` | — | Plain markup | | `VChip` | `Tag` (preferred) or `Chip` | https://primevue.org/tag/ | `Tag` for status badges; `Chip` for removable filters | | `VAvatar` | `Avatar` | https://primevue.org/avatar/ | `variant='tonal'` → `:style="{ background, color }"` (no built-in tonal) | | `VImg` | `` (native) | — | No wrapper needed; use `loading="lazy"` | | `VIcon` | `` | — | **Iconify-Tabler retained** per [RFC AD-5](./RFC-WS-FRONTEND-PRIMEVUE.md#ad-5-icons--iconify-tabler-retained-primeicons-not-installed); PrimeIcons is **not installed** | | `VLabel` | `