IlmHamroh
JavaScript Full-stack/20-qism. React: UI kutubxonalar va animatsiya5/30-dars22 daqiqa
Mundarija (32)

MUI (Material UI) React'da: tema, sx, styled, Grid va MUI X

Qisqacha: MUI — Google'ning Material Design uslubidagi tayyor komponentlar to'plami. Ranglar, burchaklar va oraliqlar bitta tema obyektida (createTheme) turadi va ThemeProvider orqali hamma komponentga yetadi. Tezkor uslub — sx prop, qayta ishlatiladigani — styled(). Jadval va sana tanlash — MUI X'da. Uslublarni Emotion JavaScript'da hisoblab, sahifaga <style> qo'shadi — shuning uchun MUI qattiq CSP bilan to'qnashadi.

Bu darsda

  • MUI'ni o'rnatasiz va createTheme qanday hosila ranglar yasashini haqiqiy chiqishda ko'rasiz.
  • sx, styled() va theme.components — uchta uslub yo'lini farqlaysiz.
  • Qorong'i rejim, Grid va MUI X (DataGrid, Date Pickers) bilan ishlaysiz.
  • npm i @mui/x-data-grid nega xato berishini va qanday tuzatilishini bilasiz.
  • MUI'ning narxini o'lchov bilan aytasiz: hajm, CSP, Pigment CSS holati — va qachon u to'g'ri tanlov ekanini.

Oldin bilishingiz kerak: UI kutubxonalar xaritasi, Radix Primitives chuqur, Dizayn tizimi asoslari: tokenlar va variantlar, Context.

1. Nega bu kerak?

«Bahor» oshxonasi kengaydi: endi uchta filial. Jasur aka ichki panel so'radi — buyurtmalar jadvali, sana bo'yicha filtr, oddiy forma. "Dizayner yo'q, chiroyli bo'lsa bo'ldi, keyingi haftaga kerak".

Sardor vazifalar dagi yo'lni takrorlamoqchi edi: Radix, Tailwind, o'z tokenlari. Lekin bu yerda vaziyat boshqa. Panelni faqat xodimlar ko'radi, dizayn tizimi yo'q, jadval esa saralash, sahifalash va filtr bilan kerak. Shunday paytda styled kit (tayyor dizaynli kutubxona) kuchli: tugma, jadval, sana tanlash — hammasi bir uslubda, bir kunda.

Eng mashhur styled kit — MUI (Material UI). UI kutubxonalar xaritasi darsida u bilan bir oynani yasaganmiz: 32 qator kod, to'qqiz yo'lning eng qisqasi. Bugun ichkariga kiramiz: tema qanday ishlaydi, uslub qayerdan keladi va bu qulaylik qanchaga tushadi.

Hayotiy o'xshatish: MUI — tayyor mebel do'koni. Bir kunda uy jihozlanadi, lekin hamma narsa bitta katalog uslubida. Rangni tanlash mumkin, shkafning shaklini o'zgartirish esa qiyin.

2. O'rnatish va birinchi komponent

2.1 Uchta paket

MUI uslublarni Emotion kutubxonasi orqali beradi. Emotion — CSS-in-JS (JavaScript ichida CSS): uslub JS obyekti sifatida yoziladi, sahifa ochilganda CSS'ga aylanadi. Shuning uchun uchta paket kerak:

bash
npm i -E @mui/material@9.4.0 \
  @emotion/react@11.14.0 @emotion/styled@11.14.1

-E (--save-exact) — package.json ga ^ siz aniq versiya yoziladi (Semver darsidagi qoida). Versiyalar — kanon tajribasidagi (tajriba/kitlar/package.json).

Birinchi komponent:

tsx
import { Button } from "@mui/material";

export function OrderButton() {
  return <Button variant="contained">Buyurtma berish</Button>;
}

variant — uchta ko'rinish: contained (to'liq rangli), outlined (chegarali), text (faqat matn). Ekranda ko'k tugma chiqadi, ustiga bosganda to'lqin (ripple) effekti tarqaladi.

2.2 Ikki kutilmagan narsa

Birinchi ishga tushirishda ikki narsa ko'zga tashlanadi. Ularni MUI'ning standart temasidan o'qiymiz (Node'da, createTheme() ni chaqirib):

text
fontFamily: "Roboto", "Helvetica", "Arial", sans-serif
button textTransform: uppercase
primary.main (standart): #1976d2
  1. Matn KATTA harflarda — «BUYURTMA BERISH». Material Design tugma matnini katta harf qiladi. O'zbekcha uzun so'zlarda bu o'qishni qiyinlashtiradi. Qanday o'chirish — «Uchinchi yo'l: theme.components» bo'limida.
  2. Shrift — Roboto, lekin MUI uni o'zi yuklamaydi. Ulamasangiz, brauzer ro'yxatdagi keyingisini oladi (Helvetica yoki Arial). Shriftni loyihaga o'zingiz qo'shasiz (Web shriftlar darsidagi qoidalar bilan).

Yana bir komponent — CssBaseline. U brauzerlarning standart uslublarini tekislaydi: body chetidagi bo'shliq, fon rangi va shrift. Bu Tailwind'dagi preflight ga o'xshaydi (shadcn/ui I darsida vazifalar da uni o'chirgan edik). Odatda ilova ildiziga bir marta qo'yiladi.

3. Tema: createTheme va ThemeProvider

3.1 Tokenlar bitta obyektda

Tema (theme) — ilovaning barcha dizayn qarorlari bitta obyektda: ranglar, shrift, oraliq qadami, burchak radiusi, ekran chegaralari. Bu Dizayn tokenlari darsidagi tokenlarning MUI'dagi shakli.

«Bahor» yashil rangi va yumaloqroq burchaklar bilan tema:

tsx
import { createTheme, ThemeProvider } from "@mui/material/styles";

const theme = createTheme({
  palette: { primary: { main: "#0f7b3f" } },
  shape: { borderRadius: 12 },
});

export function App() {
  return (
    <ThemeProvider theme={theme}>
      <OrderButton />
    </ThemeProvider>
  );
}

Biz faqat ikkita qiymat berdik. createTheme qolganini o'zi to'ldiradi. O'z kompyuterimizda (Node 24, @mui/material 9.4.0) temani konsolga chiqardik:

text
primary.main: #0f7b3f
primary.light: rgb(63, 149, 101)
primary.dark: rgb(10, 86, 44)
contrastText: #fff
spacing(2): 16px
spacing(1, 2): 8px 16px
borderRadius: 12
md breakpoint: 900
up('md'): @media (min-width:900px)

Har qatorni o'qiymiz:

  • light va dark — biz bermadik. MUI asosiy rangdan och va to'q variantlarni hisobladi: tugma ustiga kelganda, bosilganda shular ishlatiladi.
  • contrastText: #fff — yashil fon ustidagi matn rangi. MUI kontrastni hisoblab, oq rangni tanladi.
  • spacing(2) → 16px — oraliq qadami 8 piksel. spacing(1, 2) — "tepa-past 8, chap-o'ng 16".
  • md — 900 piksel. MUI'da beshta ekran chegarasi bor: xs (0), sm (600), md (900), lg (1200), xl (1536). up("md") tayyor media so'rov qaytaradi.

ThemeProvider temani Context orqali hamma komponentga yetkazadi. Ichkaridagi har Button, TextField, Dialog o'z rangini shu obyektdan o'qiydi.

3.2 O'quv modeli: tema Context bilan

MUI natija oynasida yo'q (u CSS-in-JS dvigatelini talab qiladi). Lekin g'oyani kutubxonasiz ko'rsa bo'ladi. Quyidagi — o'quv modeli, MUI'ning kodi emas: createTheme ning soddalashgan nusxasi, Context va uni o'qiydigan tugma.

jsx
import { createContext, use } from "react";

// O'quv modeli: MUI'dagi createTheme + ThemeProvider g'oyasi
function createTheme({ primary = "#1976d2", radius = 4 } = {}) {
  return {
    palette: { primary },
    shape: { borderRadius: radius },
    spacing: (n) => `${n * 8}px`,
  };
}

const ThemeContext = createContext(createTheme());

function Button({ children }) {
  const theme = use(ThemeContext);
  const style = {
    padding: `${theme.spacing(1)} ${theme.spacing(2)}`,
    background: theme.palette.primary,
    color: "#fff",
    border: 0,
    borderRadius: theme.shape.borderRadius,
  };
  console.log(children, "→", style.background, style.padding);
  return <button style={style}>{children}</button>;
}

const bahor = createTheme({ primary: "#0f7b3f", radius: 12 });

export default function App() {
  return (
    <div>
      <Button>Standart</Button>{" "}
      <ThemeContext value={bahor}>
        <Button>Bahor</Button>
      </ThemeContext>
    </div>
  );
}

Konsolda:

text
Standart → #1976d2 8px 16px
Bahor → #0f7b3f 8px 16px

Ekranda:

text
Standart Bahor

Bir xil Button ikki xil ko'rindi. Tashqaridagisi Context'ning standart qiymatini oldi, ichkaridagisi — bahor temasini. use(ThemeContext) — use() darsidagi Context o'qish usuli. MUI'da buning nomi useTheme().

Haqiqiy MUI farqi: u tugmaga style emas, sinf (class) beradi va CSS qoidasini sahifaga yozadi. Bu farq «CSS-in-JS narxi» bo'limida muhim bo'ladi.

Tekshirib ko'ring: Ilovada ikki ThemeProvider ichma-ich turibdi: tashqisida yashil, ichkarisida qizil. Ichkaridagi tugma qaysi rangda?

Javob

Qizil. Context'da eng yaqin ta'minlovchi (Provider) yutadi — bu oddiy React qoidasi (Context). MUI shu xususiyatdan foydalanadi: masalan, butun panel yashil, faqat "xavfli zona" bo'limi qizil temada. Ichki tema tashqisini to'liq almashtirmasligi uchun MUI'da funksiya ham berish mumkin: theme={(outer) => createTheme({ ...outer, ... })} — tashqi temani kengaytirib.

3.3 Qorong'i rejim: har sxemaga o'z palitrasi

MUI'da qorong'i rejim uchun colorSchemes bor. cssVariables: true bilan tema qiymatlari CSS o'zgaruvchilariga aylanadi — sxema almashganda sahifa qayta chizilmaydi, faqat o'zgaruvchilar o'zgaradi.

Sardorning birinchi urinishi:

tsx
const theme = createTheme({
  cssVariables: true,
  colorSchemes: { dark: true },
  palette: { primary: { main: "#0f7b3f" } },
});

Natija (Node'da theme.colorSchemes ni o'qidik):

text
vars primary: var(--mui-palette-primary-main, #0f7b3f)
colorSchemes: light, dark
dark primary: #90caf9
dark background: #121212

Qorong'i rejimda asosiy rang #90caf9 — MUI'ning standart ko'ki! palette faqat yorug' sxemaga tushdi. Xato ham, ogohlantirish ham yo'q. To'g'risi — har sxemaga o'z palitrasi:

tsx
const theme = createTheme({
  cssVariables: { colorSchemeSelector: "class" },
  colorSchemes: {
    light: { palette: { primary: { main: "#0f7b3f" } } },
    dark: { palette: { primary: { main: "#5cc28a" } } },
  },
});
text
light primary: #0f7b3f
dark primary: #5cc28a

Qorong'i fonda och yashil — kontrast yetarli bo'lishi uchun (Qorong'i rejim darsidagi qoida). Foydalanuvchi tanlovini almashtirish — useColorScheme() hooki (mode, setMode). colorSchemeSelector: "class" — sxema <html> dagi sinf bilan almashadi. Yuklanishdagi "oq miltillash"ga qarshi MUI'da InitColorSchemeScript komponenti bor — g'oyasi o'sha darsdagi <head> skripti bilan bir xil.

4. Uslub berishning uch yo'li

4.1 Birinchi yo'l: sx prop

sx — har MUI komponentida bor uslub prop'i. Tashqi ko'rinishi style ga o'xshaydi, lekin uch narsani biladi: temani, qisqa nomlarni va ekran chegaralarini.

tsx
<Box
  sx={{
    p: 2,
    bgcolor: "primary.main",
    color: "#fff",
    display: { xs: "none", md: "block" },
  }}
>
  Bahor
</Box>

Box — MUI'ning oddiy div i, sx uchun qulay quti. Bu kod qanday CSS'ga aylanadi? O'z kompyuterimizda komponentni jsdom'da chizdik (Node 24, @mui/material 9.4.0, tema — «Bahor») va sahifadagi qoidani o'qidik:

text
box class: MuiBox-root css-f9c62m
<style> soni: 0 -> 1
data-emotion: css
.css-f9c62m { padding: 16px; background-color: rgb(15, 123, 63); color: rgb(255, 255, 255); }
@media (min-width:0px) {
  .css-f9c62m { display: none; }
}
@media (min-width:900px) {
  .css-f9c62m { display: block; }
}

Uchta "sehr":

  1. p: 2 → padding: 16px — p qisqartma (m — margin, px — chap-o'ng padding), 2 esa theme.spacing(2).
  2. "primary.main" → yashil — satr tema ichidagi yo'l. Rang kodini yod bilish shart emas.
  3. { xs: "none", md: "block" } — telefonda yashirin, 900 pikseldan katta ekranda ko'rinadi. Media so'rovni MUI o'zi yozdi.

Natijaga e'tibor bering: sx inline style ga aylanmadi. Emotion css-f9c62m nomli sinf yasadi (nomi — uslub matnining xeshi) va sahifaga <style> tegi qo'shdi. Shuning uchun sx da media so'rov va :hover ishlaydi, oddiy style da esa yo'q.

style sx
Tema qiymatlari yo'q "primary.main", p: 2
Media so'rov, :hover yo'q bor
Natija style atributi sinf + <style> tegi

Tekshirib ko'ring: Sardor sx={{ bgcolor: "primary.mian" }} deb yozdi (harf adashgan). Nima bo'ladi?

Javob

Xato chiqmaydi. MUI tema ichida primary.mian yo'lini topmaydi va satrni CSS'ga o'zgarishsiz beradi: background-color: primary.mian. Brauzer bunday rangni bilmaydi va qoidani tashlab yuboradi — fon rangsiz qoladi. TypeScript ham ushlamaydi: sx ichidagi rang satri oddiy string. Shuning uchun ko'p ishlatiladigan rang yo'llarini tema obyektidan olish ishonchliroq: bgcolor: theme.palette.primary.main (funksiya ko'rinishida — sx={(theme) => ({ … })}).

4.2 Ikkinchi yo'l: styled()

sx bitta joy uchun qulay. Bir xil uslub o'n joyda takrorlansa — komponent yasash kerak. Buning uchun styled():

tsx
import { styled } from "@mui/material/styles";
import Paper from "@mui/material/Paper";

// O'z komponentimiz: Paper + tema qiymatlari
const OrderCard = styled(Paper)(({ theme }) => ({
  padding: theme.spacing(2),
  borderInlineStart: `4px solid ${theme.palette.primary.main}`,
  [theme.breakpoints.up("md")]: {
    padding: theme.spacing(3),
  },
}));

<OrderCard>Buyurtma №12 — osh, 35 000 so'm</OrderCard>

styled(Paper) yangi komponent qaytaradi. Ichidagi funksiya temani oladi va uslub obyektini qaytaradi. [theme.breakpoints.up("md")] — kalit sifatida media so'rov (hisoblangan kalit — computed kalitlar darsidagi [ ]).

Bu — Komponent API'sini loyihalash darsidagi g'oya: takrorlanadigan qaror bitta nomga yig'iladi. styled Emotion'ning API'si, MUI uni temaga ulab bergan.

4.3 Uchinchi yo'l: theme.components

Butun ilovadagi har tugma katta harfsiz bo'lsin desak-chi? Har joyga sx yozish — xato manbai. Buning uchun tema ichida komponentning standart props'i va uslubi bor:

tsx
const theme = createTheme({
  palette: { primary: { main: "#0f7b3f" } },
  components: {
    MuiButton: {
      defaultProps: { disableElevation: true },
      styleOverrides: {
        root: { textTransform: "none", fontWeight: 600 },
      },
    },
  },
});
  • defaultProps — har Button ga avtomatik beriladigan props (bu yerda — soyasiz).
  • styleOverrides.root — komponent ildiz elementining uslubi. «BUYURTMA BERISH» endi «Buyurtma berish».

Qaysi yo'l qachon:

Vaziyat Yo'l
Bitta joydagi kichik o'zgarish sx
Takrorlanadigan o'z komponentingiz styled()
Butun ilovadagi MUI komponenti xulqi theme.components

Diqqat: MUI ichki sinflari (.MuiButton-root, .MuiButtonBase-root) bilan CSS fayldan "ustidan yozish" ham mumkin. Lekin bu UI kutubxonalar xaritasi darsidagi "styled kit bilan kurashish" tuzog'i: keyingi versiyada ichki tuzilma o'zgarsa, qoidangiz jim ishlamay qoladi. Avval tema, keyin sx/styled, eng oxiri — ichki sinflar.

5. Joylashuv: Grid

Panelning bosh sahifasi: kompyuterda uchta karta yonma-yon, telefonda ustma-ust. MUI'da buning uchun Grid — 12 ustunli to'r:

tsx
import Grid from "@mui/material/Grid";

<Grid container spacing={2}>
  <Grid size={{ xs: 12, md: 4 }}>Bugungi buyurtmalar</Grid>
  <Grid size={{ xs: 12, md: 4 }}>Tushum</Grid>
  <Grid size={{ xs: 12, md: 4 }}>Filiallar</Grid>
</Grid>
  • container — to'rning o'zi, spacing={2} — kataklar orasi theme.spacing(2), ya'ni 16 piksel.
  • size={{ xs: 12, md: 4 }} — telefonda 12 ustunning 12 tasi (butun qator), 900 pikseldan katta ekranda 4 tasi (uchdan bir).

Ichida bu CSS Flexbox va gap. 12 raqami tasodifiy emas: 12 ga 2, 3, 4 va 6 bo'linadi — yarim, uchdan bir, chorak qilish oson.

Maslahat: Eski maqolalarda <Grid item xs={12} md={4}> ni uchratasiz. Bu eski API: 9.4.0 versiyasining Grid turlarida item va xs props'lari yo'q — size bor. Eski kodni ko'chirsangiz, TypeScript shu joyda xato beradi. Oddiy ustun yoki qator kerak bo'lsa, Stack komponenti yetadi (direction, spacing).

6. MUI X: jadval va sana

6.1 DataGrid

Jasur akaning asosiy talabi — buyurtmalar jadvali. MUI'ning murakkab komponentlari alohida loyihada: MUI X. Uning DataGrid i saralash, filtr, sahifalash va qatorlarni tanlashni tayyor beradi:

tsx
import { DataGrid, type GridColDef } from "@mui/x-data-grid";

const columns: GridColDef[] = [
  { field: "taom", headerName: "Taom", flex: 1 },
  {
    field: "narx",
    headerName: "Narx",
    type: "number",
    valueFormatter: (v: number) => `${v} so'm`,
  },
  { field: "filial", headerName: "Filial" },
];

const rows = [
  { id: 1, taom: "Osh", narx: 35000, filial: "Chilonzor" },
  { id: 2, taom: "Lag'mon", narx: 28000, filial: "Yunusobod" },
  { id: 3, taom: "Manti", narx: 30000, filial: "Chilonzor" },
];

<DataGrid
  rows={rows}
  columns={columns}
  pageSizeOptions={[10, 25]}
  checkboxSelection
/>
  • columns — ustunlar: field (qator obyektidagi kalit), sarlavha, tur, formatlash.
  • rows — ma'lumot. Har qatorda noyob id bo'lishi shart.
  • type: "number" — son bo'yicha saralash va o'ngga tekislash.

DataGrid'ning uch nashri bor. Ularning litsenziyasini npm'dan o'qidik:

Paket Litsenziya Qo'shimcha nima beradi
@mui/x-data-grid MIT (bepul) asosiy jadval
@mui/x-data-grid-pro pullik ("SEE LICENSE IN LICENSE") Pro rejasi funksiyalari
@mui/x-data-grid-premium pullik Premium rejasi funksiyalari

Bepul nashr ko'p admin panelga yetadi. Pro yoki Premium funksiyasini ishlatsangiz — litsenziya kalitisiz ekranda ogohlantirish suv belgisi chiqadi. Qaysi funksiya qaysi rejada ekanini loyiha boshida hujjatdan tekshiring: keyin bilib qolish qimmatga tushadi.

Diqqat: O'zbekcha tarjima yo'q. @mui/x-data-grid 9.15.0 ning locales papkasida ruRU bor, uzUZ yo'q (MUI'ning o'zida ham shunday). Matnlarni localeText prop'i bilan o'zingiz berasiz: localeText={{ noRowsLabel: "Buyurtma yo'q" }}.

6.2 Date Pickers

Sana tanlash uchun @mui/x-date-pickers. U sanalar bilan ishlaydigan kutubxonani adapter orqali oladi — dayjs, date-fns, Luxon yoki Moment:

tsx
import { LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import "dayjs/locale/uz-latn";

<LocalizationProvider
  dateAdapter={AdapterDayjs}
  adapterLocale="uz-latn"
>
  <DatePicker label="Bron sanasi" />
</LocalizationProvider>

adapterLocale="uz-latn" — oy va hafta kunlari nomlari dayjs'ning o'zbek lotin tilidan olinadi (dayjs'da uz-latn va uz — kirill — fayllari bor). Pickers'ning o'z matnlari («Cancel», «OK») uchun esa yana localeText kerak. Sana kutubxonalari va Temporal — Temporal API va sana kutubxonalari darsida.

6.3 Versiya tuzog'i: npm i @mui/x-data-grid

Sardor DataGrid'ni versiyasiz o'rnatdi. O'z kompyuterimizda (2026-10-17, @mui/material 9.4.0 o'rnatilgan loyihada) takrorladik:

text
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: mui-sinov@undefined
npm error Found: @mui/material@9.4.0
npm error node_modules/@mui/material
npm error   @mui/material@"9.4.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer @mui/material@"^5.15.14 || ^6.0.0 || ^7.0.0" from @mui/x-data-grid@8.29.5

Tarjimasi: "bog'liqliklar daraxtini yechib bo'lmadi. Topildi: @mui/material@9.4.0. @mui/x-data-grid@8.29.5 esa peer sifatida ^5.15.14 || ^6.0.0 || ^7.0.0 ni talab qiladi". Peer bog'liqlik — paket o'zi o'rnatmaydigan, lekin loyihada bo'lishini kutadigan paket (React versiyasini yangilash darsida tanishgan).

Nega 8.29.5? npm versiyasiz buyruqda latest belgisidagi versiyani oladi. Bizda tekshirdik: latest — 8.29.5 (2026-10-16 da chiqqan 8-qator tuzatishi), holbuki 9-qator ham bor — 9.15.0 (2026-10-06). Kim oxirgi chiqarsa, latest o'shanga o'tishi mumkin. Davosi — aniq versiya:

bash
npm i -E @mui/x-data-grid@9.15.0 @mui/x-date-pickers@9.15.0

9.15.0 ning peer talabi — ^7.3.0 || ^9.0.0, MUI 9.4.0 ga mos. Saboq kengroq: latest — "eng yangi major" degani emas. npm view <paket> dist-tags bilan qarang. Xatoni --legacy-peer-deps bilan "o'chirish" esa ishlamaydigan juftlikni o'rnatadi — xato yo'qolmaydi, ishlash paytiga ko'chadi.

7. CSS-in-JS narxi va CSP

7.1 Uslub qayerdan keladi

«sx prop» bo'limida ko'rdik: MUI uslubni sahifa ochilganda JavaScript'da hisoblaydi. Butun yo'l:

flowchart LR
  A["sx / styled<br/>JS obyekt"] --> B["Emotion:<br/>CSS matni"]
  B --> C["xesh → sinf<br/>css-f9c62m"]
  C --> D["head'ga<br/>style tegi"]
  D --> E{"CSP<br/>style-src 'self'"}
  E -->|ruxsat yo'q| F["uslub<br/>bloklanadi"]

Nimaga qarang: oxirgi qadamda <style> tegi JavaScript yasagan teg. Radix chuqur darsida xuddi shunday tegni vazifalar ning CSP'si to'sganini ko'rganmiz.

7.2 O'lchov: bir xil ekran

Kanon tajribasida (tajriba/kitlar/, Chrome 155, vazifalar CSP'si ostida) MUI varianti — ro'yxat, Dialog va Snackbar:

Bir xil ekran: JS + CSS (gzip)
  • native <dialog> (kanon)CSP 066,8 KB
  • shadcn (Radix + sonner)CSP 490,8 KB
  • MUI 9.4.0CSP 1112,9 KB

Manba: O'lchandi: tajriba/kitlar, Vite 8.3.3, React 19.3.0, Chrome 155, natijalar/tajriba/kitlar-hajm.txt va kitlar-ishlat.txt, 2026-10-14

O'lchov MUI native (kanon)
JS + CSS gzip 112.9 KB 66.8 KB
Kod 32 qator 44 qator
CSP buzilishi 1 (style-src-elem inline) 0
Klaviatura: Enter → fokus → Esc fokus «Bekor qilish», Esc'da qaytdi

Xom yozuvdan (kitlar-ishlat.txt):

text
{"v":"mui","boshida":3,"ochildi":{"rol":"dialog","fokusIchida":true,"fokus":"Bekor qilish"},"escdanKeyin":{"oyna":false,"fokus":"O'chirish"},"toast":true,"qoldi":2,"csp":["style-src-elem inline"],...}

Ikki xulosa:

  1. Xulq a'lo. Dialog to'g'ri rol oldi, fokus ichkariga kirdi (autoFocus «Bekor qilish» da), Esc'da tugmaga qaytdi, toast chiqdi. MUI — a11y'ni jiddiy oladigan kit.
  2. Narx — +46.1 KB va bitta CSP buzilishi. Kodi esa eng qisqa. Bu UI kutubxonalar xaritasi darsidagi ayirboshlash: dasturchi vaqti yoki foydalanuvchi interneti.

"Ilova ishladi, lekin buzilish bor" — nima degani? CSP Emotion'ning <style> tegini to'sdi, demak MUI uslubining bir qismi qo'llanmadi. Tugmalar bosiladi, lekin ko'rinishi buzilishi mumkin.

7.3 Davo yo'llari va ularning narxi

1. nonce. Nonce (bir martalik raqam) — server har so'rovda yangi tasodifiy satr yasaydi va uni ham CSP sarlavhasiga (style-src 'nonce-…'), ham ruxsat berilgan teglarga yozadi. Emotion buni qo'llaydi:

tsx
import createCache from "@emotion/cache";
import { CacheProvider } from "@emotion/react";

// nonce — server shu so'rov uchun yaratgan qiymat
const cache = createCache({ key: "css", nonce });

<CacheProvider value={cache}>
  <ThemeProvider theme={theme}>…</ThemeProvider>
</CacheProvider>

createCache ning turlarida nonce?: string bor (@emotion/cache 11). Lekin shart — server: nonce har javobda yangi bo'lishi kerak, aks holda u himoya emas. vazifalar esa statik fayllar (Vercel, GitHub Pages) — har so'rovga HTML yasaydigan server yo'q. Server bilan ishlaydigan ilovalarda (Next.js kabi, keyingi qismlarda) bu yo'l ochiq.

2. Pigment CSS. MUI jamoasining zero-runtime (ishlash paytida nolga teng) CSS-in-JS kutubxonasi: uslub build paytida .css faylga chiqariladi, sahifada <style> yasalmaydi — style-src 'self' bilan chiqishadi. @mui/material 9.4.0 da PigmentGrid, PigmentStack, PigmentContainer komponentlari ham bor. Lekin holati: npm'da @pigment-css/react ning versiyasi — 0.0.31 (2026-05-22), undan oldingisi 0.0.30 (2025-01-14). Bir yarim yilda bitta reliz — 1.0 ga yetmagan. Yangi loyihani bunga tayantirish xavfli: avval hujjatda uning holatini (barqarormi yoki tajribami) tekshiring.

3. 'unsafe-inline'. CSP'ga qo'shilsa, xato yo'qoladi — himoya qatlami ham. Nega bunday qilmaymiz — Radix chuqur darsidagi «Hujumchi nigohi».

Tekshirib ko'ring: «Bahor» ichki paneli faqat ofis tarmog'ida, login orqasida, CSP'siz ishlaydi. MUI ni tanlash xatomi?

Javob

Yo'q, bu MUI kuchli bo'lgan vaziyat. Foydalanuvchilar — xodimlar, kompyuterda, tez tarmoqda: +46 KB sezilmaydi. Dizayn tizimi yo'q, jadval va sana kerak — MUI X ularni tayyor beradi. Faqat bir narsani yozib qo'ying: "CSP qo'yilsa, Emotion uchun nonce kerak bo'ladi" — keyin panel internetga chiqsa, bu qaror qayta ko'riladi. Xato — tanlovning o'zida emas, narxini bilmay tanlashda.

8. Biz sinab ko'rdik: nega vazifalar da MUI yo'q

Bu darsda vazifalar kodi o'zgarmaydi. Kanon MUI'ni sinab ko'rdi va qabul qilmadi (kanon qaydi, #05–#07): "CSS-in-JS (MUI, Chakra) style-src 'self' bilan ziddiyatda; o'lcham +46…+108 KB".

Bizning sabablarimiz:

  1. CSP. vazifalar 13-qismdan beri style-src 'self' va Trusted Types bilan ishlaydi. Statik ilovada nonce yo'q.
  2. Hajm. Bitta oyna uchun +46.1 KB — bu 20-qismdagi butun Radix menyusidan (+27.2) ham ko'p.
  3. Dizayn tili. vazifalar ning o'z tokenlari bor (shadcn/ui I darsida @theme ga ko'chdi). MUI Material'ni beradi — o'z ko'rinishimizga moslash uchun kit bilan kurashish kerak bo'lardi.

MUI qachon to'g'ri tanlov:

  • ichki admin panel, CRM, hisobotlar — DataGrid va Date Pickers'ning o'zi haftalab ishni tejaydi;
  • dizayner yo'q, Material ko'rinishi maqbul;
  • jamoa MUI'ni biladi (bozor bo'yicha keng tarqalgan — vakansiyalarda tez-tez uchraydi);
  • CSP talabi yo'q yoki server nonce bera oladi.

9. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
ERESOLVE … peer @mui/material@"… ^7.0.0" versiyasiz npm i @mui/x-… → 8-qator aniq versiya: @9.15.0
tugma matni KATTA harfda Material standarti textTransform: uppercase theme.components.MuiButton.styleOverrides
qorong'i rejimda standart ko'k palette faqat yorug' sxemaga tushadi colorSchemes.dark.palette
sx dagi rang ishlamaydi, xato yo'q tema yo'li xato (primary.mian) yo'lni tekshiring; funksiya ko'rinishi
<Grid item xs={12}> — TS xatosi eski API size={{ xs: 12 }}
Applying inline style violates … 'style-src 'self'' Emotion <style> qo'shadi server nonce yoki boshqa kit

10. Mashqlar

Mashqlar kurs/mashqlar/20/05-mui/ da. Jonli yechimlarni «Ishga tushir» bilan sinang.

1-mashq (oson): sx nimaga aylanadi?

Standart tema (oraliq qadami 8 piksel, md — 900 piksel). To'ldiring:

  • p: 2 → padding:
  • mt: 0.5 → margin-top:
  • bgcolor qaysi CSS xususiyati?
  • display: { xs: "none", md: "block" } — necha pikseldan boshlab ko'rinadi?
Yechim
  • p: 2 → theme.spacing(2) → 16px.
  • mt: 0.5 → 0.5 × 8 = 4px. Kasr ham mumkin.
  • bgcolor → background-color. MUI'da qisqa nomlar: p, m, px, mt, bgcolor.
  • md chegarasi — 900px: undan kichikda none, 900 va kattada block («sx prop» bo'limidagi haqiqiy CSS'da @media (min-width:900px)).

2-mashq (o'rta): o'z spacing funksiyangiz

MUI'dagi theme.spacing ning o'quv modelini yozing. createSpacing(8) funksiya qaytarsin: u bitta yoki bir nechta son oladi va har birini qadamga ko'paytirib, px bilan, bo'shliq orqali birlashtiradi.

Ishora: qolgan argumentlar — rest parametr (...values), birlashtirish — map va join(" ").

js
function createSpacing(step) {
  // yozing
}

const spacing = createSpacing(8);
console.log(spacing(2));
console.log(spacing(1, 2));
console.log(spacing(0.5, 1, 2, 3));

Kutilgan natija:

text
16px
8px 16px
4px 8px 16px 24px
Yechim
js
function createSpacing(step) {
  return (...values) =>
    values.map((v) => `${v * step}px`).join(" ");
}

const spacing = createSpacing(8);
console.log(spacing(2));
console.log(spacing(1, 2));
console.log(spacing(0.5, 1, 2, 3));

Konsolda:

text
16px
8px 16px
4px 8px 16px 24px

createSpacing funksiya qaytaradi — closure: step qaytarilgan funksiya ichida "eslab qolinadi". MUI'da createTheme({ spacing: 4 }) desangiz, xuddi shunday qadam 4 bo'ladi. To'rtta qiymat — CSS'dagi padding tartibi: tepa, o'ng, past, chap.

3-mashq (qiyin): yorug' va qorong'i tema — o'quv modeli

«O'quv modeli: tema Context bilan» bo'limidagi kodni kengaytiring:

  1. Ikki tema: light (asosiy #0f7b3f, fon #ffffff) va dark (asosiy #5cc28a, fon #121212).
  2. App da holat mode ("light" yoki "dark") va «Rejimni almashtirish» tugmasi.
  3. Panel komponenti temani Context'dan o'qiydi, fon rangini qo'llaydi va matnda Rejim: light, asosiy: #0f7b3f ko'rinishida yozadi.

Bir marta bosilgandan keyingi ekran:

text
Rejimni almashtirish
Rejim: dark, asosiy: #5cc28a

Ishora: createContext, use — «O'quv modeli» bo'limidagi kabi; holat — useState.

Yechim
jsx
import { createContext, use, useState } from "react";

const themes = {
  light: { mode: "light", primary: "#0f7b3f", bg: "#ffffff" },
  dark: { mode: "dark", primary: "#5cc28a", bg: "#121212" },
};

const ThemeContext = createContext(themes.light);

function Panel() {
  const theme = use(ThemeContext);
  const color = theme.mode === "dark" ? "#fff" : "#111";
  return (
    <p style={{ background: theme.bg, color, padding: 8 }}>
      Rejim: {theme.mode}, asosiy: {theme.primary}
    </p>
  );
}

export default function App() {
  const [mode, setMode] = useState("light");
  function toggle() {
    setMode((m) => (m === "light" ? "dark" : "light"));
  }
  return (
    <ThemeContext value={themes[mode]}>
      <button onClick={toggle}>Rejimni almashtirish</button>
      <Panel />
    </ThemeContext>
  );
}

Ekranda:

text
Rejimni almashtirish
Rejim: dark, asosiy: #5cc28a

Panel rejim haqida hech narsa bilmaydi — u faqat Context'dagi temani o'qiydi. Rejim almashganda Context qiymati yangilanadi va Panel qayta chiziladi. MUI'da useColorScheme() ning setMode("dark") i xuddi shu ishni qiladi, faqat cssVariables bilan: qayta chizish o'rniga CSS o'zgaruvchilari almashadi.

4-mashq: tajriba qadami (ixtiyoriy)

vazifalar ga tegmang. Alohida papkada (kurs/tajriba/mui/) Vite + React loyiha oching va «Bahor» buyurtmalar jadvalini DataGrid bilan yasang: uchta ustun, type: "number" li narx, localeText da o'zbekcha noRowsLabel. Keyin ikki narsani o'lchang: npm run build dagi gzip hajm va index.html ga vazifalar dagi CSP <meta> ini qo'shgandan keyin DevTools konsolidagi xatolar soni.

Yechim

Tekshiruv ro'yxati:

  • O'rnatish: npm i -E @mui/material@9.4.0 @emotion/react@11.14.0 @emotion/styled@11.14.1 @mui/x-data-grid@9.15.0 — ERESOLVE chiqmadi.
  • Har qatorda id bor; narx ustuni o'ngga tekislangan, sarlavhani bosganda son bo'yicha saralanadi.
  • Ma'lumot bo'sh bo'lsa — «Buyurtma yo'q» (o'zbekcha noRowsLabel).
  • Build: Vite oxirida har faylning gzip hajmini chiqaradi — shu raqamni yozing.
  • CSP bilan: konsolda Applying inline style violates… xatolari chiqadi va jadval uslubi buziladi — «CSS-in-JS narxi» bo'limidagi kanon o'lchovi bilan bir xil sabab.

Raqamingiz kanondagidan farq qiladi — DataGrid bitta oynadan ancha katta. Muhimi — raqamni o'zingiz o'lchab, qaror yozuvida qoldirishingiz.

11. Real ishda

  • Ichki tizimlar — CRM, ombor, hisobot panellari ko'pincha MUI + MUI X da: jadval, filtr va sana tayyor. Bunday loyihaga qo'shilsangiz, birinchi navbatda theme.ts faylini o'qing — butun ilovaning ko'rinishi o'sha yerda.
  • Versiya yangilash — MUI har major versiyada API'ni o'zgartiradi (Grid dagi item → size kabi). Jamoalar buni codemod bilan ko'chiradi (React versiyasini yangilash darsidagi yondashuv).
  • Intervyu savollari: "sx va style farqi?", "MUI'da temani qanday sozlaysiz?", "CSS-in-JS'ning kamchiliklari?", "peer dependency xatosini qanday hal qilasiz?".

Xulosa

  • MUI — Material Design'dagi styled kit; uslub Emotion orqali (CSS-in-JS).
  • createTheme bir nechta qiymatdan to'liq tema yasaydi (light/dark, contrastText); ThemeProvider uni Context bilan tarqatadi.
  • Uslub: bitta joy — sx, takroriy komponent — styled(), butun ilova — theme.components.
  • Qorong'i rejim — colorSchemes, har sxemaga o'z palette; joylashuv — Grid (size), murakkab komponentlar — MUI X.
  • Versiyasiz npm i latest belgisini oladi — u eng yangi major bo'lmasligi mumkin.
  • Narx: bir xil ekranda +46.1 KB va CSP 1 buzilish; davo — server nonce, Pigment CSS esa hali 0.0.x.

Keyingi dars: Ant Design: korporativ admin panellar — ConfigProvider va tema tokenlari, o'zbekcha uz_UZ tarjima, Form va Table, nega message ni App.useApp() orqali chaqirish kerak va Trusted Types ostida nima bo'ladi.

Manbalar

  • MUI: Theming, The sx prop, Grid, CSS theme variables — mui.com/material-ui (9.4.0)
  • MUI X: Data Grid, Date and Time Pickers, Licensing — mui.com/x (9.15.0)
  • Emotion: @emotion/cache (nonce) — emotion.sh/docs/@emotion/cache
  • Pigment CSS — github.com/mui/pigment-css (npm @pigment-css/react 0.0.31)
  • MDN: Content-Security-Policy style-src, nonce — developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
  • O'z o'lchovimiz: natijalar/tajriba/05-mui-x-eresolve.txt (2026-10-17); kitlar — natijalar/tajriba/kitlar-hajm.txt, kitlar-ishlat.txt (2026-10-14)
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
MUI (Material UI) React'da: tema, sx, styled, Grid va MUI X — IlmHamroh