IlmHamroh
JavaScript Full-stack/20-qism. React: UI kutubxonalar va animatsiya6/30-dars21 daqiqa
Mundarija (36)

Ant Design React'da: korporativ admin panel — ConfigProvider, Form, Table

Qisqacha: Ant Design (AntD) — admin panel va ichki tizimlar uchun qurilgan styled kit: kuchli Form, Table, DatePicker tayyor. Ko'rinish ConfigProvider dagi tokenlar bilan sozlanadi: bitta asosiy rang bersangiz, hover, bosilgan va fon ranglari algoritm bilan hisoblanadi. O'zbekcha tarjima bor (uz_UZ). message va notification ni App.useApp() orqali chaqiring — aks holda ular temangizni ko'rmaydi. Uslublar JavaScript'da innerHTML bilan yoziladi — Trusted Types bor ilovada AntD umuman ochilmaydi.

Bu darsda

  • ConfigProvider bilan temani sozlaysiz va bitta rangdan qanday "oila" hosil bo'lishini haqiqiy chiqishda ko'rasiz.
  • O'zbekcha uz_UZ tarjimani ulaysiz va uning kamchiliklarini bilasiz.
  • Form (qoidalar, useForm) va Table (saralash, sahifalash) bilan «Bahor» bron panelini yasaysiz.
  • message nega App.useApp() orqali chaqirilishini o'quv modelida tushunasiz.
  • ProComponents va Refine'ni bilasiz, AntD 6 bilan versiya mosligini tekshirasiz.
  • CSP va Trusted Types ostidagi o'lchovni o'qiysiz va AntD qachon to'g'ri tanlov ekanini aytasiz.

Oldin bilishingiz kerak: MUI (Material UI), UI kutubxonalar xaritasi, Dizayn tizimi asoslari: tokenlar va variantlar, Context.

1. Nega bu kerak?

O'tgan darsda MUI'ni ko'rdik: Material uslubi, sx, MUI X. Bugun uning eng yaqin raqibi — Ant Design. U Alibaba guruhi ichida yaratilgan va boshidanoq "korporativ ilovalar uchun" deb loyihalangan: ko'p ma'lumot, ko'p forma, ko'p jadval.

O'zbekistondagi ichki tizimlarda — bank, sug'urta, logistika, davlat xizmatlari panellarida — AntD'ni tez-tez uchratasiz. Sabab oddiy: bunday panelning 80 foizi forma va jadvaldan iborat, AntD esa aynan shu ikkisida kuchli.

«Bahor» uchun Jasur aka yangi talab qo'ydi: bron paneli. Administrator mijoz ismini, telefonini va odam sonini kiritadi, pastda bronlar jadvali. Telefon formati tekshirilsin, odam soni 1 dan 20 gacha. Sardor buni AntD'da qanday qurishini ko'ramiz — va qaysi joyda AntD bizning vazifalar ga mos kelmasligini.

Hayotiy o'xshatish: AntD — idora mebeli katalogi. Stol, shkaf, kartoteka — hammasi bir-biriga mos, yig'ish tez. Lekin hammasi "idora uslubi"da: uyga qo'ysangiz, uy idoraga o'xshab qoladi.

2. O'rnatish va ConfigProvider

2.1 Bitta paket

AntD bitta paket — uslub tizimi ichida:

bash
npm i -E antd@6.6.5

MUI'dan farqi: Emotion alohida o'rnatilmaydi. AntD'ning o'z CSS-in-JS dvigateli bor (@ant-design/cssinjs), u bog'liqlik sifatida o'zi keladi. Versiya — kanon tajribasidagi (tajriba/kitlar/package.json).

Birinchi komponent:

tsx
import { Button } from "antd";

<Button type="primary">Bron qilish</Button>

type="primary" — asosiy (to'ldirilgan) tugma. Boshqalari: default, dashed, text, link. Matn o'zgarmaydi — MUI'dagidek katta harfga o'tmaydi.

2.2 ConfigProvider — butun ilova sozlamasi

ConfigProvider — AntD'ning "boshqaruv pulti". Uning ichidagi hamma komponent undan uchta narsani o'qiydi: tema, til va umumiy sozlamalar (o'lcham, yo'nalish, CSP).

tsx
import { ConfigProvider, theme } from "antd";
import uzUZ from "antd/locale/uz_UZ";

<ConfigProvider
  locale={uzUZ}
  theme={{
    token: { colorPrimary: "#0f7b3f", borderRadius: 8 },
    algorithm: theme.defaultAlgorithm,
  }}
>
  <BronPaneli />
</ConfigProvider>

MUI'ning ThemeProvider i bilan g'oya bir xil — Context orqali tarqatish. Farqi — tema tuzilmasida. Keyingi bo'lim shu haqda.

3. Tokenlar: bitta rangdan butun oila

3.1 Uch qavat: seed, map, alias

AntD tokenlari uch qavatli:

flowchart LR
  S["Seed token<br/>colorPrimary"] -->|algoritm| M["Map token<br/>colorPrimaryHover,<br/>colorPrimaryBg"]
  M --> A["Alias token<br/>colorLink,<br/>controlOutline"]
  A --> C["Komponent<br/>Button, Table"]
  • Seed token (urug' token) — siz beradigan boshlang'ich qiymat: colorPrimary, borderRadius, fontSize.
  • Map token (hosila token) — algoritm urug'dan hisoblaydi: hover rangi, bosilgan holat rangi, och fon.
  • Alias token — ma'noli nomlar: havola rangi, fokus chizig'i. Ular map tokenlardan olinadi.

Nimaga qarang: o'q bitta yo'nalishda. Siz faqat chap tomonni o'zgartirasiz, qolgani zanjir bo'ylab o'zi yangilanadi. Bu Dizayn tizimi asoslari darsidagi "birlamchi va semantik tokenlar" g'oyasining AntD'dagi shakli.

3.2 Haqiqiy chiqish

AntD'da temani komponentsiz ham hisoblab ko'rish mumkin — theme.getDesignToken(). O'z kompyuterimizda (Node 24, antd 6.6.5) «Bahor» yashilini berdik:

tsx
import { theme } from "antd";

const t = theme.getDesignToken({
  token: { colorPrimary: "#0f7b3f" },
});
text
colorPrimary: #0f7b3f
colorPrimaryHover: #26874e
colorPrimaryActive: #06542c
colorPrimaryBg: #abbaaf
borderRadius: 6 borderRadiusLG: 8
dark colorBgContainer: #141414
dark colorPrimary: #106c39

O'qiymiz:

  • colorPrimaryHover — biroz ochroq yashil (sichqoncha ustida), colorPrimaryActive — to'qroq (bosilganda). Biz ularni bermadik.
  • colorPrimaryBg — tanlangan qator, belgi foni uchun. Bizning to'q yashilimizdan algoritm kulrang-yashil #abbaaf ni chiqardi. Kutilmagan natija — shuning uchun hosila ranglarni ko'z bilan tekshirish kerak. Yoqmasa, map tokenni ham qo'lda berish mumkin: token: { colorPrimaryBg: "#e7f2ec" }.
  • borderRadiusLG: 8 — katta elementlar (karta, oyna) uchun radius ham urug'dan hosil bo'ldi.
  • Oxirgi ikki qator — algorithm: theme.darkAlgorithm bilan: fon #141414, asosiy rang esa qorong'i fonga moslab o'zgardi (#106c39).

algorithm — temaning "hisoblash usuli". AntD'da uchta: defaultAlgorithm, darkAlgorithm, compactAlgorithm (zichroq — kichik oraliqlar). Ularni massivda birlashtirish mumkin: [theme.darkAlgorithm, theme.compactAlgorithm].

3.3 O'quv modeli: urug'dan hosila

AntD natija oynasida yo'q. Algoritm g'oyasini esa oddiy JavaScript bilan ko'rsa bo'ladi. Quyidagi — o'quv modeli: rangni oq yoki qora bilan aralashtirib hosila tokenlar yasaydi. AntD'ning haqiqiy algoritmi murakkabroq (rang g'ildiragi bo'yicha 10 ta ton yasaydi), shuning uchun raqamlar boshqacha chiqadi:

js
function toRgb(hex) {
  const n = parseInt(hex.slice(1), 16);
  return [n >> 16, (n >> 8) & 255, n & 255];
}
function toHex(rgb) {
  const parts = rgb.map((c) => c.toString(16).padStart(2, "0"));
  return "#" + parts.join("");
}
// a rangni b rangga "amount" ulushda aralashtiradi (0…1)
function mix(a, b, amount) {
  const x = toRgb(a);
  const y = toRgb(b);
  return toHex(x.map((c, i) => Math.round(c + (y[i] - c) * amount)));
}
function deriveTokens(seed) {
  return {
    colorPrimary: seed.colorPrimary,
    colorPrimaryHover: mix(seed.colorPrimary, "#ffffff", 0.15),
    colorPrimaryActive: mix(seed.colorPrimary, "#000000", 0.3),
    colorPrimaryBg: mix(seed.colorPrimary, "#ffffff", 0.9),
    borderRadiusLG: seed.borderRadius + 2,
  };
}
const seed = { colorPrimary: "#0f7b3f", borderRadius: 6 };
console.log(deriveTokens(seed));

Konsolda:

text
{
  colorPrimary: '#0f7b3f',
  colorPrimaryHover: '#338f5c',
  colorPrimaryActive: '#0b562c',
  colorPrimaryBg: '#e7f2ec',
  borderRadiusLG: 8
}

toRgb — #0f7b3f ni uchta songa ajratadi: bitlar siljishi >> va & (Bitwise operatorlar darsida). mix har kanalni ikkinchi rang tomon amount ulushda suradi: 0.15 — biroz oqartirish, 0.9 — deyarli oq. Bizning colorPrimaryBg — och yashil #e7f2ec, AntD'niki — kulrangroq. Algoritm boshqa, g'oya bir xil: bitta urug' → izchil oila.

Tekshirib ko'ring: Dizayner "hover rangi boshqacha bo'lsin" dedi. colorPrimary ni o'zgartirasizmi yoki boshqa narsani?

Javob

Faqat colorPrimaryHover map tokenini qo'lda berasiz: token: { colorPrimary: "#0f7b3f", colorPrimaryHover: "#1a9a52" }. colorPrimary ni o'zgartirsangiz, butun oila (bosilgan, fon, havola) siljiydi. Qo'lda berilgan map token algoritm natijasidan ustun turadi — qolgan hosilalar esa avvalgidek hisoblanadi.

3.4 Komponent tokenlari

Faqat bitta komponentni o'zgartirish — components kaliti:

tsx
<ConfigProvider
  theme={{
    token: { colorPrimary: "#0f7b3f" },
    components: {
      Table: { headerBg: "#e7f2ec", rowHoverBg: "#f3faf6" },
      Button: { controlHeight: 44 },
    },
  }}
>

controlHeight: 44 — tugma balandligi 44 piksel (React'da accessibility darsidagi bosish maydoni talabi). MUI'dagi theme.components bilan bir xil vazifa, faqat AntD'da tokenlar orqali. Har komponentning token ro'yxati hujjatda "Design Token" bo'limida.

4. O'zbekcha: uz_UZ

AntD'da o'zbek lotin tarjimasi bor: antd/locale/uz_UZ. MUI'da yo'q edi (MUI darsida localeText ni qo'lda bergan edik). Tarjima ichidan bir nechta qator (o'z kompyuterimizda o'qidik):

text
locale: uz-latn
Modal: {"okText":"OK","cancelText":"Yopish","justOkText":"OK"}
Pagination items_per_page: / sah.
Form required: Iltimos, ${label} kiriting
DatePicker placeholder: Sanani tanlang
Empty: {"description":"Maʼlumot topilmadi"}

Ishlatishdan oldin uchta narsaga e'tibor bering:

  1. Ma'no. Tasdiq oynasidagi «Bekor qilish» o'rnida «Yopish» turibdi. "O'chirilsinmi? — OK / Yopish" — foydalanuvchi uchun noaniq.
  2. Apostrof. «Maʼlumot» da oddiy ' emas, boshqa belgi (U+02BC). Qidiruvda "Ma'lumot" bilan solishtirsangiz, mos kelmaydi — Matn algoritmlari darsidagi normalla aynan shuning uchun apostroflarni bir xil qiladi.
  3. Grammatika. Iltimos, ${label} kiriting — label «Ism» bo'lsa, «Iltimos, Ism kiriting». Qo'shimcha (ni) yo'q.

Tarjimani o'zgartirish oson — obyektni kengaytirasiz:

tsx
import uzUZ from "antd/locale/uz_UZ";

const bahorUz = {
  ...uzUZ,
  Modal: { ...uzUZ.Modal, cancelText: "Bekor qilish" },
};

<ConfigProvider locale={bahorUz}>…</ConfigProvider>

DatePicker oy nomlarini dayjs kutubxonasidan oladi, shuning uchun uning tilini ham ulash kerak: import "dayjs/locale/uz-latn" va dayjs.locale("uz-latn").

5. Forma: Form va qoidalar

5.1 Bron formasi

AntD'ning eng kuchli tomoni — Form. Maydon, qoidalar, xato matnlari va yuborish — hammasi bitta joyda:

tsx
import { Button, Form, Input, InputNumber } from "antd";

type Bron = { ism: string; telefon: string; odam?: number };

export function BronFormasi() {
  const [form] = Form.useForm<Bron>();
  return (
    <Form
      form={form}
      layout="vertical"
      onFinish={(qiymatlar) => console.log("onFinish:", qiymatlar)}
    >
      <Form.Item label="Ism" name="ism" rules={[{ required: true }]}>
        <Input />
      </Form.Item>
      <Form.Item
        label="Telefon"
        name="telefon"
        rules={[
          { required: true, message: "Telefon raqamini kiriting" },
          {
            pattern: /^\+998 \d{2} \d{3} \d{2} \d{2}$/,
            message: "Format: +998 90 000 00 00",
          },
        ]}
      >
        <Input />
      </Form.Item>
      <Form.Item
        label="Odam soni"
        name="odam"
        rules={[{ type: "number", min: 1, max: 20 }]}
      >
        <InputNumber />
      </Form.Item>
      <Button type="primary" htmlType="submit">
        Bron qilish
      </Button>
    </Form>
  );
}

Uchta g'oya:

  • name — qiymat qaysi kalitga tushadi. onFinish ga { ism, telefon, odam } obyekti keladi — faqat hamma qoida o'tganda.
  • rules — massiv: required, pattern (RegExp asoslari darsida), type + min/max. message bermasangiz, tarjimadagi standart matn olinadi.
  • Form.useForm() — forma "pulti": form.setFieldsValue(…), form.resetFields(), form.validateFields() — tashqaridan boshqarish uchun.

Bo'sh formani yuborganda nima chiqadi? O'z kompyuterimizda (jsdom, uz_UZ bilan) shu formani chizib, «Bron qilish» ni bosdik:

text
ekranda xatolar: Iltimos, Ism kiriting | Telefon raqamini kiriting

Birinchi xato — tarjimadagi standart shablon, ikkinchisi — biz bergan matn. Odam soni maydoni bo'sh bo'lsa xato yo'q: unda required yo'q.

5.2 RHF bilan farqi

React Hook Form da maydonlar uncontrolled edi: qiymat DOM'da, React har harfda qayta chizmaydi. AntD Form esa qiymatlarni o'z ichki omborida (store) saqlaydi va har maydonni alohida yangilaydi — butun forma qayta chizilmaydi. Natija: o'nlab maydonli forma ham sekinlashmaydi.

Tanlov qoidasi: loyihada AntD bo'lsa — uning Form i (komponentlar bilan ulanishi tayyor). AntD'siz loyihada — RHF + Zod (RHF + Zod). Ikkalasini aralashtirish shart emas.

Tekshirib ko'ring: Telefon maydoniga +998901234567 (bo'shliqsiz) yozildi. Qaysi xabar chiqadi va nega?

Javob

«Format: +998 90 000 00 00». required o'tdi (maydon bo'sh emas), lekin pattern — ^\+998 \d{2} \d{3} \d{2} \d{2}$ — bo'shliqlarni talab qiladi. Qoidalar massiv tartibida tekshiriladi va birinchi yiqilgan qoidaning message i chiqadi. Real loyihada bunday qat'iylik foydalanuvchini qiynaydi — yaxshisi, kiritilgan qiymatni avval normallashtirish (bo'shliqlarni olib tashlab, keyin tekshirish).

6. Jadval: Table

Bronlar ro'yxati:

tsx
import { Table, type TableProps } from "antd";

type Taom = { id: number; taom: string; narx: number };

const columns: TableProps<Taom>["columns"] = [
  { title: "Taom", dataIndex: "taom" },
  {
    title: "Narx",
    dataIndex: "narx",
    sorter: (a, b) => a.narx - b.narx,
    render: (narx: number) => `${narx} so'm`,
  },
];

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

<Table
  rowKey="id"
  columns={columns}
  dataSource={data}
  pagination={{ pageSize: 2 }}
/>
  • dataIndex — qator obyektidagi kalit (MUI DataGrid'dagi field).
  • sorter — saralash funksiyasi (sort darsidagi solishtiruvchi). Sarlavhani bosganda o'sish → kamayish → asl tartib.
  • render — katakni qanday chizish: matn, tugma, belgi.
  • rowKey — har qatorning kaliti (key darsidagi talab). Bermasangiz, AntD key maydonini qidiradi.

uz_UZ bilan chizilganda (o'z kompyuterimizda, jsdom):

text
jadval: Osh35000 | Lag'mon28000
sahifalash: Orqaga , 1 , 2 , Oldinga

Birinchi sahifada ikkita qator (pageSize: 2), sahifalash tugmalari o'zbekcha. Filtr (filters, onFilter), qator tanlash (rowSelection), kengaytiriladigan qator (expandable) — hammasi props bilan. Katta ma'lumotda esa saralash va sahifalash serverda bo'ladi — Jadvallar II darsida.

7. message va App.useApp()

7.1 Ogohlantirish

Sardor saqlangandan keyin xabar chiqardi:

tsx
import { message } from "antd";

<Button onClick={() => message.success("Bron saqlandi")}>
  Saqlash
</Button>

Ishladi, lekin xabar ko'k — «Bahor» yashili emas. Konsolda esa (o'z kompyuterimizda, ConfigProvider ichida tema bilan):

text
Warning: [antd: message] Static function can not consume context like dynamic theme. Please use 'App' component instead.

Tarjimasi: "Statik funksiya dinamik tema kabi Context'ni o'qiy olmaydi. Uning o'rniga App komponentidan foydalaning". Statik funksiya — komponent emas, oddiy import qilingan funksiya (message.success). U React daraxtidan tashqarida yashaydi, shuning uchun ConfigProvider ni "ko'rmaydi": na temani, na tilni.

7.2 O'quv modeli: nega statik funksiya Context'ni ko'rmaydi

Buni kutubxonasiz ko'raylik. Bitta Context va ikki xil "xabar" funksiyasi:

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

const ThemeContext = createContext({ primary: "#1677ff" });

// Statik: modul darajasidagi oddiy funksiya
const message = {
  success(text) {
    console.log("statik:", text, "— rang yo'q (Context'siz)");
  },
};

// Hook: komponent ichida chaqiriladi, Context'ni o'qiy oladi
function useApp() {
  const theme = use(ThemeContext);
  return {
    message: {
      success(text) {
        console.log("hook:", text, "— rang", theme.primary);
      },
    },
  };
}

function SaveButtons() {
  const app = useApp();
  return (
    <div>
      <button onClick={() => message.success("Saqlandi")}>
        Statik
      </button>{" "}
      <button onClick={() => app.message.success("Saqlandi")}>
        Hook orqali
      </button>
    </div>
  );
}

export default function App() {
  return (
    <ThemeContext value={{ primary: "#0f7b3f" }}>
      <SaveButtons />
    </ThemeContext>
  );
}

Konsolda:

text
statik: Saqlandi — rang yo'q (Context'siz)
hook: Saqlandi — rang #0f7b3f

Statik funksiya modul darajasida yaratilgan — u qaysi ThemeContext ichida chaqirilganini bilishning yo'li yo'q. Hook esa komponent ichida chaqiriladi va use() orqali eng yaqin Provider qiymatini oladi (hooklar qoidalari). Bu React'ning asosiy qoidasi, AntD'ning xatosi emas.

7.3 AntD'dagi to'g'ri yo'l

tsx
import { App, Button, ConfigProvider } from "antd";

function SaqlashTugmasi() {
  const { message, notification, modal } = App.useApp();
  return (
    <Button onClick={() => message.success("Bron saqlandi")}>
      Saqlash
    </Button>
  );
}

export function Ilova() {
  return (
    <ConfigProvider theme={{ token: { colorPrimary: "#0f7b3f" } }}>
      <App>
        <SaqlashTugmasi />
      </App>
    </ConfigProvider>
  );
}

<App> — message, notification va modal uchun joy ochadi va ularni Context bilan bog'laydi. App.useApp() uchtasini qaytaradi — endi xabar yashil va o'zbekcha. Kanon tajribasidagi AntD varianti ham aynan shunday yozilgan (tajriba/kitlar/src/antd.tsx: const { message } = App.useApp();).

  • message — tepada qisqa xabar (toast'ning AntD'dagi nomi).
  • notification — burchakda sarlavha va matnli kattaroq xabar.
  • modal — modal.confirm({ title, onOk }) — funksiya bilan tasdiq oynasi.

Toast qachon to'g'ri va qachon xato — Toast bildirishnomalar darsida.

8. ProComponents va Refine

8.1 Tayyor "bloklar"

AntD ustida ikki katta ekotizim bor:

  • ProComponents (@ant-design/pro-components) — AntD jamoasining yuqori darajali komponentlari: ProTable (qidiruv formasi + jadval + serverdan yuklash bitta komponentda), ProForm, ProLayout (yon menyu, sarlavha, non yo'li bilan admin karkasi).
  • Refine — admin panel uchun framework: ma'lumot manbai (REST, GraphQL, Supabase), CRUD sahifalari, ruxsatlar, routing. UI qatlami sifatida AntD, MUI, Mantine yoki Chakra'ni oladi (@refinedev/antd va boshqalar).

Ikkalasi ham "ro'yxat, ko'rish, tahrirlash, o'chirish" sahifalari yuzlab bo'lgan loyihada vaqtni tejaydi.

8.2 Versiya mosligi — tekshirib ko'ramiz

MUI darsida latest tuzog'ini ko'rgan edik. Bu yerda ham peer talablarni npm'dan o'qidik (2026-10-17):

Paket (latest) antd peer talabi AntD 6.6.5 bilan
@ant-design/pro-components 2.8.10 ^4.24.15 || ^5.11.2 mos emas
@ant-design/pro-components 3.1.15-7 (beta) ^6.0.0 , lekin beta
@refinedev/antd 6.0.3 ^5.23.0 mos emas

AntD 6.0.0 2025-11-21 da chiqqan. Bir yil o'tsa ham, ekotizimning barqaror versiyalari 5-qatorda qolgan. Amaliy xulosa: Refine yoki ProComponents kerak bo'lsa, loyiha AntD 5 da boshlanadi — yoki beta bilan yashashga rozi bo'linadi. Kutubxona tanlashda faqat asosiy paketga emas, siz ishlatadigan ekotizim butun zanjiriga qarang.

9. Narx va CSP: AntD ochilmadi

9.1 O'lchov

Kanon tajribasida (tajriba/kitlar/, Chrome 155, vazifalar CSP'si ostida) AntD varianti — ro'yxat, Modal, message:

Bir xil ekran: JS + CSS (gzip)
  • native <dialog> (kanon)CSP 066,8 KB
  • MUI 9.4.0CSP 1112,9 KB
  • Ant Design 6.6.5ochilmadi174,4 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

174.4 KB — to'qqiz variantning eng kattasi, native'dan +107.6 KB. Kod esa 37 qator. Lekin asosiy natija — hajm emas:

text
{"v":"antd","xato":"Waiting failed: 10000ms exceeded","csp":["require-trusted-types-for trusted-types-sink", …],"konsol":["This document requires 'TrustedHTML' assignment. The action has been blocked.", …,"pageerror: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment."]}

Sinov skripti 10 soniya ro'yxatni kutdi — ilova umuman chizilmadi. Konsolda 9 ta Trusted Types buzilishi. Shu sababli AntD'ning klaviatura va fokus xulqini bu o'lchovda tekshira olmadik. AntD'ni tanlasangiz, UI kutubxonalar xaritasi dagi klaviatura ssenariysini (Enter → fokus oynada → Esc → fokus qaytdimi) o'z ilovangizda yurgizing.

9.2 Nega aynan innerHTML

Trusted Types — brauzer himoyasi: innerHTML kabi "xavfli joylar"ga (sink) oddiy satr yozish taqiqlanadi, faqat maxsus tekshirilgan obyekt (XSS va DOM xavfsizligi). vazifalar da u require-trusted-types-for 'script' bilan yoqilgan.

AntD'ning uslub dvigateli CSS'ni sahifaga qanday yozadi? @rc-component/util paketidagi dynamicCSS.js faylida (o'z kompyuterimizda ochdik):

js
styleNode.innerHTML = css;

<style> tegini yaratadi va matnini innerHTML bilan beradi. Trusted Types buni to'sadi → istisno → React daraxti yiqiladi → oq ekran. MUI'da esa (Emotion) faqat <style> tegi CSP'da to'silgan edi, ilova ishlagan. Farq katta: "uslub buzildi" va "ilova ochilmadi".

Yana bir kuzatuv: bitta ConfigProvider + bitta Button ni jsdom'da chizganimizda <head> ga 8 ta <style> tegi qo'shildi (data-css-hash, data-token-hash atributlari bilan). Har komponent turi va token to'plami — alohida teg.

9.3 Yo'llari bormi?

  • ConfigProvider csp={{ nonce }} — AntD turlarida csp?: { nonce?: string } bor. MUI'dagidek, bu style-src 'nonce-…' uchun — server har so'rovda nonce bersa. Trusted Types muammosini esa nonce hal qilmaydi: innerHTML baribir chaqiriladi.
  • Trusted Types siyosati — trustedTypes.createPolicy(...) bilan "standart siyosat" yozib, innerHTML ga satrni o'tkazish. Bu himoyani o'zingiz zaiflashtirish demak: siyosat noto'g'ri yozilsa, XSS yo'li ochiladi.
  • Yoki — Trusted Types'siz ilova.

Tekshirib ko'ring: Bank ichki tizimi uchun AntD tanlangan. Xavfsizlik jamoasi "Trusted Types yoqilsin" dedi. Nima qilasiz?

Javob

Avval o'lchaysiz: CSP Report-Only rejimida (buzilishlar yoziladi, lekin to'silmaydi) ilovani ochib, nechta va qaysi joydan buzilish kelishini ko'rasiz — bizning o'lchov 9 ta deydi. Keyin jamoa bilan qaror: AntD uchun Trusted Types siyosati (createPolicy) yozish va uni kod ko'rigida qattiq nazorat qilish — yoki Trusted Types'ni boshqa himoyalar (qat'iy script-src, sanitizatsiya) bilan almashtirish. Muhimi — "shunchaki o'chirib qo'yish" emas, yozma qaror va o'lchov. Kutubxonani ertaroq tanlash bosqichida bu savolni berish esa eng arzon yo'l.

10. Biz sinab ko'rdik: nega vazifalar da AntD yo'q

Bu darsda vazifalar kodi o'zgarmaydi. Kanon AntD'ni sinab ko'rdi (kanon qaydi, #05–#07): "Mantine/AntD style-src 'self' / Trusted Types bilan ziddiyatda; o'lcham +46…+108 KB. AntD — O'zbekiston korporativ loyihalari uchun darsda qoladi (tajriba sifatida)".

Sabablar qisqa: Trusted Types ostida ilova ochilmaydi, eng katta hajm (+107.6 KB), vazifalar da forma va jadval kam — AntD'ning kuchli tomoni bizga kerak emas.

AntD qachon to'g'ri tanlov:

  • forma va jadvalga to'la ichki tizim (ERP, CRM, bank back-office, davlat xizmati operatori paneli);
  • jamoa AntD'ni biladi va loyihada allaqachon bor — tanish kutubxona ham kuchli dalil;
  • o'zbekcha tarjima kerak (tayyor uz_UZ, kamchiliklarini to'g'rilab);
  • ProComponents yoki Refine bilan tez CRUD kerak (AntD 5 da);
  • Trusted Types talabi yo'q.

11. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
Static function can not consume context like dynamic theme message.success to'g'ridan import qilingan <App> + App.useApp()
xabar ko'k, tarjima yo'q o'sha sabab o'sha davo
This document requires 'TrustedHTML' assignment cssinjs innerHTML Trusted Types siyosati yoki boshqa kit
«OK / Yopish» tasdiq oynasida uz_UZ dagi Modal.cancelText tarjimani kengaytiring
ERESOLVE … antd@"^5…" ProComponents/Refine AntD 6 ni qo'llamaydi AntD 5 yoki beta
jadvalda key ogohlantirishi rowKey yo'q, ma'lumotda key yo'q rowKey="id"
hosila rang yoqmadi algoritm natijasi map tokenni qo'lda bering

12. Mashqlar

Mashqlar kurs/mashqlar/20/06-antd/ da.

1-mashq (oson): qaysi qavat?

To'ldiring:

  • Siz beradigan boshlang'ich rang tokeni:
  • Algoritm hisoblaydigan, sichqoncha ustidagi rang:
  • Qorong'i rejim uchun algoritm: theme.
  • message ni temaga ulash uchun hook: App.
Yechim
  • colorPrimary — seed (urug') token.
  • colorPrimaryHover — map (hosila) token, urug'dan hisoblanadi.
  • theme.darkAlgorithm — algorithm kalitiga beriladi; compactAlgorithm bilan massivda birlashadi.
  • App.useApp() — <App> ichida message, notification, modal ni Context bilan qaytaradi.

2-mashq (o'rta): qoidalar o'quv modeli

AntD rules ning soddalashgan modelini yozing. validate(label, value, rules) xatolar massivini qaytarsin. Qoidalar:

  • { required: true } — qiymat bo'sh ("", undefined) bo'lsa: Iltimos, <label> kiriting;
  • { pattern, message } — satr naqshga mos kelmasa: message;
  • { min, max } — son chegaradan tashqarida bo'lsa: <label>: <min>–<max> oralig'ida bo'lsin.

AntD'dagidek, birinchi yiqilgan qoidada to'xtang. Bo'sh qiymatda faqat required tekshirilsin.

Ishora: qoidalar ustidan for…of va erta return (for...of, erta qaytish).

js
function validate(label, value, rules) {
  // yozing
}

const phone = /^\+998 \d{2} \d{3} \d{2} \d{2}$/;
console.log(validate("Ism", "", [{ required: true }]));
console.log(validate("Telefon", "+998901234567", [
  { required: true },
  { pattern: phone, message: "Format: +998 90 000 00 00" },
]));
console.log(validate("Odam soni", 25, [{ min: 1, max: 20 }]));
console.log(validate("Odam soni", 4, [{ min: 1, max: 20 }]));
Yechim
js
function validate(label, value, rules) {
  const empty = value === "" || value === undefined;
  for (const rule of rules) {
    if (rule.required && empty) {
      return [`Iltimos, ${label} kiriting`];
    }
    if (empty) continue;
    if (rule.pattern && !rule.pattern.test(value)) {
      return [rule.message];
    }
    const { min, max } = rule;
    if (min !== undefined && (value < min || value > max)) {
      return [`${label}: ${min}–${max} oralig'ida bo'lsin`];
    }
  }
  return [];
}

const phone = /^\+998 \d{2} \d{3} \d{2} \d{2}$/;
console.log(validate("Ism", "", [{ required: true }]));
console.log(validate("Telefon", "+998901234567", [
  { required: true },
  { pattern: phone, message: "Format: +998 90 000 00 00" },
]));
console.log(validate("Odam soni", 25, [{ min: 1, max: 20 }]));
console.log(validate("Odam soni", 4, [{ min: 1, max: 20 }]));

Konsolda:

text
[ 'Iltimos, Ism kiriting' ]
[ 'Format: +998 90 000 00 00' ]
[ "Odam soni: 1–20 oralig'ida bo'lsin" ]
[]

Uchinchi qatorda qo'shtirnoq boshqacha — satr ichida ' bor, Node uni "…" bilan ko'rsatadi. Bo'sh qiymat uchun continue: required bo'lmagan maydon bo'sh qolishi mumkin, uni pattern bilan tekshirish shart emas — AntD'da ham shunday.

3-mashq (qiyin): o'z App.useApp() ingiz

«Statik funksiya Context'ni ko'rmaydi» bo'limidagi modelni haqiqiy xabarlar ro'yxatiga aylantiring:

  1. AppProvider komponenti: ichida messages holati (massiv) va Context.
  2. useApp() — { message: { success(text) } } qaytaradi; success ro'yxatga ✓ <text> qo'shadi.
  3. Xabarlar AppProvider ichida, bolalardan keyin, <ul> da chiziladi.
  4. «Saqlash» tugmasi ikki marta bosilganda ekranda ikki xabar.
text
Saqlash
✓ Bron saqlandi
✓ Bron saqlandi

Ishora: Context qiymati — funksiyali obyekt; holatni yangilash — updater funksiya (State II).

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

const AppContext = createContext(null);

function AppProvider({ children }) {
  const [messages, setMessages] = useState([]);
  const api = {
    message: {
      success(text) {
        setMessages((list) => [...list, `✓ ${text}`]);
      },
    },
  };
  return (
    <AppContext value={api}>
      {children}
      <ul>
        {messages.map((m, i) => (
          <li key={i}>{m}</li>
        ))}
      </ul>
    </AppContext>
  );
}

function useApp() {
  return use(AppContext);
}

function SaveButton() {
  const { message } = useApp();
  return (
    <button onClick={() => message.success("Bron saqlandi")}>
      Saqlash
    </button>
  );
}

export default function App() {
  return (
    <AppProvider>
      <SaveButton />
    </AppProvider>
  );
}

Ekranda:

text
Saqlash
✓ Bron saqlandi
✓ Bron saqlandi

SaveButton xabarlar qayerda chizilishini bilmaydi — u faqat useApp() dan funksiya oladi. AntD'ning <App> i ham shunday: xabarlar uchun joy ochadi va funksiyalarni Context bilan beradi. Updater (list => …) — ikki bosish ketma-ket bo'lsa ham ikkala xabar saqlanadi. key={i} bu yerda yetarli: ro'yxat faqat oxiriga qo'shiladi, o'chirilmaydi (key).

4-mashq: tajriba qadami (ixtiyoriy)

vazifalar ga tegmang. Alohida papkada «Bahor» bron panelini AntD 6.6.5 da yasang: ConfigProvider (uz_UZ + «Bahor» yashili, Modal.cancelText tuzatilgan), bron formasi va jadval, saqlanganda App.useApp() dagi message. So'ng index.html ga vazifalar CSP'sini qo'shib oching.

Yechim

Tekshiruv ro'yxati:

  • Konsolda Static function can not consume context yo'q — message hook orqali.
  • Bo'sh forma yuborilganda «Iltimos, Ism kiriting» va o'zingiz bergan telefon xabari chiqadi.
  • Sahifalash tugmalari «Orqaga / Oldinga», tasdiq oynasida «Bekor qilish».
  • CSP <meta> qo'shilgach: sahifa oq, konsolda This document requires 'TrustedHTML' assignment — kanon o'lchovidagi natija. require-trusted-types-for qatorini olib tashlasangiz, ilova ochiladi, lekin style-src xatolari qoladi.

Shu ikki natijani qaror yozuvingizga qo'shing: "AntD — faqat Trusted Types'siz va nonce bilan".

13. Real ishda

  • Korporativ panellar — AntD + ProComponents (yoki Refine) + AntD'ning dizayn qo'llanmasi: ko'p jamoalar dizaynersiz ham izchil panel quradi.
  • Mavjud loyihaga qo'shilish — avval ConfigProvider sozlamasini va AntD versiyasini (5 yoki 6) toping: ProComponents va Refine qaysi versiyada ishlashini aynan shu belgilaydi.
  • Intervyu savollari: "AntD'da temani qanday o'zgartirasiz (seed, map, alias)?", "message nega App.useApp() orqali?", "AntD Form va React Hook Form farqi?", "CSS-in-JS va Trusted Types qanday to'qnashadi?".

Xulosa

  • AntD — forma va jadvalga kuchli styled kit; uslub — o'z CSS-in-JS dvigateli (@ant-design/cssinjs).
  • ConfigProvider — tema, til va umumiy sozlamalar; tokenlar uch qavat: seed → map → alias, algorithm (default, dark, compact).
  • uz_UZ tarjima bor, lekin tekshirib, kengaytirib ishlating («Yopish», ʼ, grammatika).
  • Form — name, rules, useForm; Table — dataIndex, sorter, render, rowKey.
  • message/notification/modal — <App> va App.useApp() orqali, aks holda Context ko'rinmaydi.
  • ProComponents va Refine barqarori AntD 5 da; Trusted Types ostida AntD ochilmaydi (innerHTML), hajm 174.4 KB.

Keyingi dars: Mantine, Chakra, HeroUI va React Aria: boshqa kitlar — to'rtta kit, Ark UI, Park UI va DaisyUI. Har birining CSP o'lchovi bilan.

Manbalar

  • Ant Design: Customize Theme (Design Token, algorithm), Internationalization, Form, Table, App — ant.design (6.6.5)
  • Ant Design: ConfigProvider csp — ant.design/components/config-provider
  • ProComponents — procomponents.ant.design; Refine — refine.dev/docs (@refinedev/antd)
  • MDN: Trusted Types API — developer.mozilla.org/docs/Web/API/Trusted_Types_API
  • O'z o'lchovimiz: natijalar/tajriba/06-antd-token-locale.txt, 06-antd-peer-jadval.txt, 06-antd-forma-jsdom.txt (2026-10-17); kitlar — 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!
Ant Design React'da: korporativ admin panel — ConfigProvider, Form, Table — IlmHamroh