Tarkibga o'tish

09 β€” Nuxt UI: asoslar, o'rnatish va theming

⬅️ Oldingi: 08 β€” Data & Server Β· 🏠 README


Bu va keyingi (10-) modul Nuxt UI ga bag'ishlangan β€” Nuxt jamoasining rasmiy komponentlar kutubxonasi. Ikki qismga bo'ldim: - 09 (shu modul) β€” Nuxt UI nima, o'rnatish, UApp, design system (rang/variant/size), theming (3 qatlamli tizim), :ui prop. Ya'ni "tizimni tushunish". - 10 β€” har bir komponentni kategoriya bo'yicha batafsil ko'rib chiqamiz (props, slot, misol).

Avval tizimni tushun, keyin komponentlarga o't. Aks holda har bir komponentda bir xil rang/variant tushunchalarini qayta-qayta o'qiysan.


1. Nuxt UI nima va nega v4 muhim

Nuxt UI β€” Vue/Nuxt uchun tayyor, accessible, Tailwind asosidagi komponentlar kutubxonasi. Button, Input, Modal, Table, butun Dashboard sidebar β€” hammasi tayyor.

Laravel analogiyasi. Nuxt UI β‰ˆ Filamentning UI qatlami, lekin Vue/Nuxt uchun. Filament Laravel'da admin panel komponentlarini tayyor beradi; Nuxt UI ham xuddi shunday tayyor komponentlar beradi β€” lekin headless va to'liq sozlanuvchi. EduCore admin panelini noldan div/css yozmasdan yig'ish uchun aynan shu kerak.

v4 nima o'zgartirdi (2025 sentyabr): - Nuxt UI va Nuxt UI Pro birlashdi β€” endi hammasi bitta bepul, MIT @nuxt/ui paketda. Ilgari pullik bo'lgan Dashboard, Page, Auth, Pricing komponentlari endi bepul. (NuxtLabs Vercel'ga qo'shilgani sabab.) - 125+ komponent, 12 ta bepul template, Figma kit. - Asosi: Reka UI (accessibility/primitivlar) + Tailwind CSS v4 + Tailwind Variants (class tizimi). - Faqat Nuxt emas β€” toza Vue (Vite) loyihalarda ham ishlaydi.

Hozirgi versiya: v4.8+ (tez yangilanadi).


2. O'rnatish (Nuxt)

pnpm add @nuxt/ui tailwindcss
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui'],
  css: ['~/assets/css/main.css'],
})
/* app/assets/css/main.css */
@import "tailwindcss";
@import "@nuxt/ui";

Tamom. Nuxt UI o'zi avtomatik o'rnatadi: @nuxt/icon (ikonkalar), @nuxt/fonts (shriftlar), @nuxtjs/color-mode (dark mode). Ularni alohida modules ga qo'shma β€” konflikt bo'ladi.

Toza Vue (Nuxt'siz)

// vite.config.ts
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [vue(), ui()],
})

3. ⚠️ UApp β€” eng muhim wrapper (buni unutsang, yarmi ishlamaydi)

Butun ilovani <UApp> ichiga o'rab qo'yish shart. U global provayderlarni o'rnatadi: Toast (useToast), Overlay (useOverlay), Tooltip, dark mode konteksti.

<!-- app/app.vue -->
<template>
  <UApp>
    <NuxtLayout>
      <NuxtPage />
    </NuxtLayout>
  </UApp>
</template>

Why. useToast() yoki useOverlay() ishlamasa β€” 90% holatda sabab shu: UApp yo'q. U Toaster va OverlayProvider'ni daraxtning tepasiga joylaydi (Vue'ning provide/inject mexanizmi β€” 03-modul). Laravel analogiyasi: bu app-level "service provider"ni register qilishga o'xshaydi β€” global servislar shu yerda ulanadi.

UApp qabul qiladigan foydali proplar: :toaster (toast joylashuvi), :tooltip (global tooltip sozlamalari), locale (i18n).

Bu provide/inject, reaktivlik va SSR Nuxt ostida aniq qanday ishlashini bir rasmda jamlab ko'rsataman β€” keyingi bo'limlardagi "runtime-reaktiv tema" va @click xulqi shu mexanizmlardan kelib chiqadi.

Vue 3 / Nuxt semantikasi: Proxy reaktivlik, bir tomonlama props/emits, SSR va hydration


4. Design System β€” rang, variant, size

Bu β€” Nuxt UI'ning yuragi. Deyarli har bir komponent bir xil 3 ta propni qabul qiladi: color, variant, size. Buni bir marta tushunsang β€” 125 ta komponentni bilasan.

4.1. Semantik ranglar (color)

Nuxt UI to'g'ridan-to'g'ri red/blue ishlatmaydi. U semantik (ma'noga bog'langan) ranglarni ishlatadi:

Semantik rang Vazifasi
primary asosiy brend rangi (default: green)
secondary ikkilamchi aksent
success muvaffaqiyat (yashil)
info ma'lumot (ko'k)
warning ogohlantirish (sariq)
error xato (qizil)
neutral kulrang β€” fon, chegara, matn
<UButton color="primary">Saqlash</UButton>
<UButton color="error" variant="soft">O'chirish</UButton>
<UAlert color="warning" title="Diqqat" />

Class sifatida ham ishlatasan: bg-primary, text-primary, text-primary-500, ring-primary. primary ning DEFAULT soyasi temaga moslashadi β€” light'da 500, dark'da 400.

Why semantik. color="error" yozsang, keyin brendni o'zgartirsang (qizil β†’ to'q sariq) β€” faqat bitta config qatorini o'zgartirasan, butun ilova moslashadi. bg-red-500 yozsang β€” har joyda qo'lda almashtirasan. Bu design token falsafasi.

4.2. Variant (variant)

Bir rang β€” bir necha ko'rinish. Button uchun:

Variant Ko'rinish
solid to'liq to'ldirilgan (default)
outline faqat chegara
soft yengil fon (rangning och varianti)
subtle soft + nozik chegara
ghost fonsiz, hover'da paydo bo'ladi
link havola ko'rinishi
<UButton color="primary" variant="solid">Asosiy</UButton>
<UButton color="primary" variant="outline">Ikkilamchi</UButton>
<UButton color="neutral" variant="ghost">Bekor qilish</UButton>

Form-input komponentlarida variant boshqacha bo'ladi (outline, soft, subtle, ghost, none) β€” lekin g'oya bir xil.

4.3. Size (size)

xs Β· sm Β· md (default) Β· lg Β· xl β€” barcha komponentlarda bir xil shkala. Bitta size butun komponentning padding, font, ikonka o'lchamini muvofiq o'zgartiradi.

<UButton size="xs">Kichik</UButton>
<UInput size="lg" placeholder="Katta input" />

Quyidagi rasm uchala propni bitta o'qda jamlaydi β€” bu uch o'q mustaqil, ularni xohlagancha kombinatsiya qilasan.

Nuxt UI design system uchlamasi: color, variant va size uchta mustaqil o'q


5. Theming β€” 3 qatlamli tizim

Nuxt UI theming aynan 3 qatlamdan iborat. Har birining aniq vazifasi bor β€” adashtirma.

Qatlam 1: main.css        β†’ xom dizayn tokenlar (@theme) β€” "brend DNA"
Qatlam 2: app.config.ts   β†’ semantik mapping (qaysi rang primary)
Qatlam 3: app.config.ts   β†’ komponent override (default stillarni o'zgartirish)

Qatlam 1 β€” @theme (Tailwind v4 dizayn tokenlari)

Tailwind v4 "CSS-first" β€” sozlash JS config'da emas, CSS'da @theme ichida:

/* app/assets/css/main.css */
@import "tailwindcss";
@import "@nuxt/ui";

@theme {
  /* O'z brend rangingni 50–950 to'liq shkala bilan ber */
  --color-brand-50:  #eff6ff;
  --color-brand-500: #2563eb;
  --color-brand-950: #172554;

  /* Shrift */
  --font-sans: 'Inter', sans-serif;
}

Muhim: custom rang qo'shsang, 50 dan 950 gacha barcha soyalarni berishing kerak β€” komponentlar ularning hammasini ishlatadi. Hex'dan to'liq shkala uchun uicolors.app yoki Tailwind palitrasidan foydalan.

Qatlam 2 β€” semantik mapping (app.config.ts)

Xom tokenlarni semantik rolga ulaysan. Bu runtime-reaktiv β€” qayta build qilmasdan, hatto ish vaqtida temani almashtirib bo'ladi (HMR bilan):

// app/app.config.ts
export default defineAppConfig({
  ui: {
    colors: {
      primary: 'brand',    // 1-qatlamdagi custom rang
      secondary: 'purple',
      success: 'green',
      info: 'blue',
      warning: 'amber',
      error: 'red',
      neutral: 'zinc',     // kulranglar
    },
  },
})

Laravel analogiyasi. app.config.ts β‰ˆ config/ papkasidagi config fayllar β€” markazlashgan sozlamalar. Farqi: bu runtime'da reaktiv (Laravel config build/cache'lanadi).

Qatlam 3 β€” komponent override (app.config.ts)

Har bir komponentning default ko'rinishini global o'zgartirish. Masalan, "barcha button'lar default neutral + subtle bo'lsin":

// app/app.config.ts
export default defineAppConfig({
  ui: {
    button: {
      slots: {
        base: 'font-bold rounded-lg',   // har bir button'ga
      },
      defaultVariants: {
        color: 'neutral',
        variant: 'subtle',
        size: 'lg',
      },
    },
    card: {
      slots: {
        root: 'rounded-xl',
        body: 'p-6',
      },
    },
  },
})

Compound variants β€” ma'lum rang+size kombinatsiyasiga maxsus stil:

button: {
  compoundVariants: [
    { color: 'primary', size: 'sm', class: 'ring-2 ring-primary/60' },
  ],
}

6. :ui prop va class β€” bitta instansiyani sozlash

Global config butun ilovaga ta'sir qiladi. Bitta joyda o'zgartirish kerak bo'lsa β€” :ui prop (slot'larni nishonga oladi) yoki class (root slot):

<UCard :ui="{ header: 'p-8 text-xl', body: 'p-8 space-y-4', footer: 'border-t' }">
  <template #header>Sarlavha</template>
  Asosiy kontent
  <template #footer>Pastki qism</template>
</UCard>

<!-- class β€” root/base slot uchun -->
<UButton class="w-full" trailing-icon="i-lucide-arrow-right">Davom etish</UButton>

Ustuvorlik (priority):

class prop  >  :ui prop  >  app.config.ts global  >  komponent default

Why bu ishlaydi. Nuxt UI ostida Tailwind Variants + tailwind-merge bor. Ya'ni sening class'ing core class bilan aqlli birlashadi (konflikt bo'lsa seniki yutadi), CSS cascade bilan urishmaysan. p-8 bersang β€” komponentning p-4 i o'rniga qo'yiladi, ikkalasi qo'shilib ketmaydi.

Quyidagi rasm uchala theming qatlamini va bitta instansiyaga tushadigan to'liq ustuvorlik zanjirini bir joyda ko'rsatadi.

Nuxt UI theming: 3 qatlamli tizim va class > :ui > app.config > komponent default ustuvorligi

Laravel analogiyasi. :ui bilan slot override β‰ˆ vendor:publish qilingan paket view'ini o'zgartirish β€” asl paketni buzmasdan ustiga o'z stilingni qo'yasan.

Komponentni qayerdan o'rganish: slot'larni bilish

Har bir komponentning qanday slot'lari (base, header, body, trailingIcon...) borligini hujjatdagi Theme bo'limidan ko'rasan β€” :ui da aynan o'sha kalitlarni ishlatasan. 10-modulda muhim komponentlarning asosiy slot'larini ko'rsataman.


7. Dark mode

@nuxtjs/color-mode avtomatik ulangan. Class-strategiya (dark: Tailwind). Komponentlar o'zi moslashadi. Tugma:

<UColorModeButton />   <!-- tayyor light/dark toggle -->

Yoki qo'lda:

<script setup>
const colorMode = useColorMode()
// colorMode.preference = 'dark' | 'light' | 'system'
</script>

bg-default, text-default, text-muted, border-default kabi semantik klasslar ham bor β€” ular light/dark'da o'zi to'g'ri rangga o'tadi (qo'lda dark:bg-... yozish shart emas).


8. Ikonkalar (Icon)

@nuxt/icon + Iconify β€” 200,000+ ikonka. Format: i-{collection}-{name}.

<UIcon name="i-lucide-rocket" class="size-5 text-primary" />
<UButton icon="i-lucide-plus">Qo'shish</UButton>
<UButton leading-icon="i-lucide-arrow-left" trailing-icon="i-lucide-arrow-right" />

Mashhur to'plamlar: i-lucide-* (Lucide β€” toza, tavsiya), i-heroicons-*, i-simple-icons-* (brendlar: github, google). Loading ikonkasini globalda o'zgartirish: app.config.ts β†’ ui.icons.loading.


Xulosa β€” mental model

@nuxt/ui o'rnatish:
  1. modules: ['@nuxt/ui'] + css faylga @import
  2. app.vue ni <UApp> ga o'ra (Toast/Overlay uchun SHART)

Har komponent: color + variant + size
  color   β†’ semantik (primary/success/error/neutral...)
  variant β†’ solid/outline/soft/subtle/ghost/link
  size    β†’ xs/sm/md/lg/xl

Theming (3 qatlam):
  @theme (main.css)         β†’ xom token (rang 50–950, shrift)
  ui.colors (app.config)    β†’ semantik mapping (runtime-reaktiv)
  ui.<component> (app.config) β†’ default override

Bitta instansiya:
  :ui prop (slotlar) yoki class (root) β€” Tailwind Variants aqlli merge qiladi

🎯 Masalalar (20 ta)

npx nuxi init ui-lab β†’ Nuxt UI o'rnat β†’ app.vue ni <UApp> ga o'ra. Hamma masalani shu loyihada bajar.

A β€” setup va asoslar

  1. β˜… Yangi Nuxt loyiha och, @nuxt/ui o'rnat, main.css ni to'g'ri sozla. <UButton>Salom</UButton> ekranga chiqsin. βœ…
  2. β˜… app.vue ni <UApp> ga o'ra. Keyin useToast().add({ title: 'Test' }) ni tugmaga ulab, toast chiqishini tekshir. (Avval UAppsiz sinab ko'r β€” nima bo'ladi?) βœ…
  3. β˜… Bitta qatorda 7 ta button yarat, har birida boshqa color (primaryβ†’neutral). Vizual farqni ko'r.
  4. β˜… Bitta color="primary" button'ning 6 ta variantini (solidβ†’link) yonma-yon chiqar.
  5. β˜… size ni xs dan xl gacha o'zgartirib, button va input qanday kattalashishini kuzat.

B β€” theming

  1. β˜…β˜… @theme ichida o'z brand rangingni (50–950) e'lon qil, app.config.ts da primary: 'brand' qil. Button rangi o'zgardimi? βœ…
  2. β˜…β˜… app.config.ts orqali barcha button'larni default variant: 'soft', size: 'lg' qil. Endi <UButton> (propsiz) qanday ko'rinadi?
  3. β˜…β˜… app.config.ts da card.slots.root ga rounded-2xl ber. Barcha kartalar o'zgardimi?
  4. β˜…β˜… Bitta UCard ga :ui="{ body: 'p-10' }" ber. Global config'ni emas, faqat shu kartani o'zgartirdimi? Ustuvorlikni tushuntir. βœ…
  5. ❓ class="p-8" bilan :ui="{ base: 'p-2' }" urishsa, qaysi biri yutadi va nega? tailwind-merge roli nima?
  6. β˜…β˜… secondary va success ranglarini boshqacha Tailwind ranglarga map qil (app.config.ts). Alert'larda sina.

C β€” dark mode va ikonka

  1. β˜… <UColorModeButton /> qo'shib, light/dark almashtir. Komponentlar o'zi moslashdimi?
  2. β˜…β˜… bg-default, text-muted, border-default klasslari bilan oddiy div yasab, dark mode'da rangi o'zgarishini kuzat (dark: yozmasdan).
  3. β˜…β˜… useColorMode() bilan o'z toggle tugmangni yoz (colorMode.preference ni almashtir).
  4. β˜… 5 xil ikonka chiqar: i-lucide-* to'plamidan 3 ta, i-simple-icons-github, i-heroicons-bell. class bilan rang/o'lcham ber.
  5. β˜…β˜… Button'ga loading prop ber β€” loading ikonkasi paydo bo'ladimi? Keyin loading-auto bilan form submit'da avtomatik loading'ni sina (08/Form bilan bog'la).

D β€” EduCore tematik

  1. β˜…β˜… EduCore brendini o'rnat: primary = o'z rangin, neutral = slate, shrift = Inter. Bosh sahifada brendlangan button + card ko'rsat. βœ…
  2. β˜…β˜… "O'quvchi qo'shish" (primary, solid), "Tahrirlash" (neutral, outline), "O'chirish" (error, soft) β€” 3 ta amaliy button'ni to'g'ri rang/variant bilan yasab, ButtonGroup'ga joyla. (ButtonGroup β€” 10-modulda.)
  3. ❓ Nega EduCore'da bg-red-500 o'rniga color="error" ishlatish strategik jihatdan to'g'ri? Kelajakda brend o'zgarsa nima yutasan?
  4. β˜…β˜…β˜… app.config.ts da to'liq EduCore "design preset" yoz: ranglar + button default'lari + card default'lari + input default size. Buni bitta faylda jamlab, "tema" sifatida hujjatlashtir. βœ…

βœ… Tanlangan yechimlar

1 β€” o'rnatish

pnpm dlx nuxi@latest init ui-lab
cd ui-lab
pnpm add @nuxt/ui tailwindcss
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui'],
  css: ['~/assets/css/main.css'],
})
/* app/assets/css/main.css */
@import "tailwindcss";
@import "@nuxt/ui";
<!-- app/app.vue -->
<template>
  <UApp>
    <div class="p-8">
      <UButton>Salom</UButton>
    </div>
  </UApp>
</template>
pnpm dev β†’ button chiroyli ko'rinadi. Agar style yo'q bo'lsa β€” main.css ni css: [...] ga qo'shishni unutgansan.

2 β€” UApp va toast

<script setup>
const toast = useToast()
function notify() {
  toast.add({ title: 'Test', description: 'Toast ishladi!', color: 'success' })
}
</script>
<template>
  <UApp>
    <UButton @click="notify">Toast chiqar</UButton>
  </UApp>
</template>
UAppsiz: useToast() ishlaydi, lekin toast ekranda ko'rinmaydi (Toaster provayderi yo'q) β€” yoki konsolda inject ogohlantirishi chiqadi. UApp Toaster'ni daraxtga qo'shadi (provide/inject, 03-modul). Shuning uchun u shart.

6 β€” custom brand rang

/* main.css */
@import "tailwindcss";
@import "@nuxt/ui";

@theme {
  --color-brand-50:  #eef2ff;
  --color-brand-100: #e0e7ff;
  --color-brand-200: #c7d2fe;
  --color-brand-300: #a5b4fc;
  --color-brand-400: #818cf8;
  --color-brand-500: #6366f1;
  --color-brand-600: #4f46e5;
  --color-brand-700: #4338ca;
  --color-brand-800: #3730a3;
  --color-brand-900: #312e81;
  --color-brand-950: #1e1b4b;
}
// app.config.ts
export default defineAppConfig({
  ui: { colors: { primary: 'brand' } },
})
Endi <UButton> indigo-brend rangida. Soyalardan birortasini qoldirib ketsang (masalan 300) β€” o'sha soyani ishlatadigan komponent buziladi. Shuning uchun to'liq 50–950.

9 β€” :ui prop ustuvorligi

<UCard :ui="{ body: 'p-10' }">Faqat shu karta p-10</UCard>
<UCard>Bu karta default padding'da</UCard>
:ui faqat shu instansiyaga ta'sir qiladi β€” global config'ni o'zgartirmaydi. Ustuvorlik: class > :ui > app.config.ts global > komponent default. Ya'ni: umumiy qoidani app.config.ts da, istisnoni :ui/class da. Bu Laravel'da global config vs runtime override'ga o'xshaydi.

17 β€” EduCore brend

/* main.css */
@import "tailwindcss";
@import "@nuxt/ui";
@theme {
  --font-sans: 'Inter', sans-serif;
  --color-edu-50: #ecfeff;  --color-edu-500: #0891b2;  --color-edu-950: #083344;
  /* ... to'liq shkala ... */
}
// app.config.ts
export default defineAppConfig({
  ui: {
    colors: { primary: 'edu', neutral: 'slate' },
  },
})
<template>
  <div class="p-8 space-y-4">
    <UCard>
      <template #header><h2 class="font-bold">EduCore</h2></template>
      <p class="text-muted">Multi-tenant ta'lim platformasi</p>
      <template #footer>
        <UButton color="primary">Boshlash</UButton>
      </template>
    </UCard>
  </div>
</template>
Brend bir joyda (app.config.ts + @theme) β€” butun ilova avtomatik moslashadi.

20 β€” EduCore design preset

// app/app.config.ts β€” EduCore "tema"
export default defineAppConfig({
  ui: {
    colors: {
      primary: 'edu',
      secondary: 'indigo',
      neutral: 'slate',
      error: 'red',
      success: 'emerald',
      warning: 'amber',
    },
    button: {
      slots: { base: 'font-medium rounded-lg' },
      defaultVariants: { size: 'md' },
    },
    card: {
      slots: { root: 'rounded-xl ring-default', body: 'p-6' },
    },
    input: {
      defaultVariants: { size: 'md' },
    },
    formField: {
      slots: { label: 'font-medium text-default' },
    },
  },
})
Bu β€” EduCore'ning yagona "manba" temasi. Yangi sahifa yozganda hech narsa sozlashing shart emas β€” barcha komponentlar shu presetdan keladi. Laravel'da config/educore.php ga o'xshaydi, lekin runtime-reaktiv.


➑️ Keyingi: 10 β€” Nuxt UI komponentlari (to'liq ma'lumotnoma)