[{"data":1,"prerenderedAt":368},["ShallowReactive",2],{"docs:\u002Fdocs":3},{"id":4,"title":5,"body":6,"component":357,"dependsOn":358,"description":359,"emitDescriptions":360,"extension":361,"meta":362,"navigation":110,"order":63,"path":363,"seo":364,"status":365,"stem":366,"__hash__":367},"docs\u002Fdocs\u002Findex.md","Вступ",{"type":7,"value":8,"toc":353},"minimark",[9,18,32,35,40,43,50,334,338,341,349],[10,11,12,13,17],"p",{},"У кількох продуктових кодових базах незалежно написано по кілька версій тих\nсамих компонентів: Button, Modal, Drawer, Menu, Table, Select, Toast,\n",[14,15,16],"code",{},"$confirm",". Жодна з них не використовує готову UI-бібліотеку — усе зроблено\nруками на Tailwind.",[10,19,20,21,23,24,27,28,31],{},"Патерни збіглися самі собою: тости всюди тримають стан у module-scope\nsingleton, ",[14,22,16],{}," всюди повертає ",[14,25,26],{},"Promise\u003Cboolean>",", оверлеї всюди\nрахують z-index стеком, таблиці всюди зберігають налаштування колонок у\n",[14,29,30],{},"localStorage",". Але якість реалізацій різна, а документація роз'їхалася з\nкодом — подекуди довідники описують props, яких у компонентах уже немає.",[10,33,34],{},"Ця бібліотека збирає найкращу версію кожного компонента в одному місці.",[36,37,39],"h2",{"id":38},"як-цим-користуватися","Як цим користуватися",[10,41,42],{},"Компоненти не встановлюються пакетом. Ви відкриваєте сторінку компонента,\nнатискаєте «Копіювати» і вставляєте файл у свій проєкт — так само, як у\nshadcn\u002Fui. Код стає вашим, і ви вільні його змінювати.",[10,44,45,46,49],{},"Єдина вимога — щоб у проєкті були оголошені ті самі токени. Для цього\nдостатньо скопіювати один файл, ",[14,47,48],{},"tokens.css","; він написаний чистим CSS і\nпрацює однаково на Tailwind v3 і v4.",[51,52,57],"pre",{"className":53,"code":54,"language":55,"meta":56,"style":56},"language-vue shiki shiki-themes github-light github-dark","\u003Cscript setup lang=\"ts\">\nimport UiButton from '~\u002Fcomponents\u002Fui\u002FUiButton.vue'\n\nconst saving = ref(false)\n\nasync function save() {\n  saving.value = true\n  try {\n    await $fetch('\u002Fapi\u002Fsave', { method: 'POST' })\n  } finally {\n    saving.value = false\n  }\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CUiButton variant=\"solid\" :loading=\"saving\" @click=\"save\">\n    Зберегти\n  \u003C\u002FUiButton>\n\u003C\u002Ftemplate>\n","vue","",[14,58,59,89,105,112,137,142,157,168,177,200,211,222,228,234,244,249,259,309,315,325],{"__ignoreMap":56},[60,61,64,68,72,76,79,82,86],"span",{"class":62,"line":63},"line",1,[60,65,67],{"class":66},"sVt8B","\u003C",[60,69,71],{"class":70},"s9eBZ","script",[60,73,75],{"class":74},"sScJk"," setup",[60,77,78],{"class":74}," lang",[60,80,81],{"class":66},"=",[60,83,85],{"class":84},"sZZnC","\"ts\"",[60,87,88],{"class":66},">\n",[60,90,92,96,99,102],{"class":62,"line":91},2,[60,93,95],{"class":94},"szBVR","import",[60,97,98],{"class":66}," UiButton ",[60,100,101],{"class":94},"from",[60,103,104],{"class":84}," '~\u002Fcomponents\u002Fui\u002FUiButton.vue'\n",[60,106,108],{"class":62,"line":107},3,[60,109,111],{"emptyLinePlaceholder":110},true,"\n",[60,113,115,118,122,125,128,131,134],{"class":62,"line":114},4,[60,116,117],{"class":94},"const",[60,119,121],{"class":120},"sj4cs"," saving",[60,123,124],{"class":94}," =",[60,126,127],{"class":74}," ref",[60,129,130],{"class":66},"(",[60,132,133],{"class":120},"false",[60,135,136],{"class":66},")\n",[60,138,140],{"class":62,"line":139},5,[60,141,111],{"emptyLinePlaceholder":110},[60,143,145,148,151,154],{"class":62,"line":144},6,[60,146,147],{"class":94},"async",[60,149,150],{"class":94}," function",[60,152,153],{"class":74}," save",[60,155,156],{"class":66},"() {\n",[60,158,160,163,165],{"class":62,"line":159},7,[60,161,162],{"class":66},"  saving.value ",[60,164,81],{"class":94},[60,166,167],{"class":120}," true\n",[60,169,171,174],{"class":62,"line":170},8,[60,172,173],{"class":94},"  try",[60,175,176],{"class":66}," {\n",[60,178,180,183,186,188,191,194,197],{"class":62,"line":179},9,[60,181,182],{"class":94},"    await",[60,184,185],{"class":74}," $fetch",[60,187,130],{"class":66},[60,189,190],{"class":84},"'\u002Fapi\u002Fsave'",[60,192,193],{"class":66},", { method: ",[60,195,196],{"class":84},"'POST'",[60,198,199],{"class":66}," })\n",[60,201,203,206,209],{"class":62,"line":202},10,[60,204,205],{"class":66},"  } ",[60,207,208],{"class":94},"finally",[60,210,176],{"class":66},[60,212,214,217,219],{"class":62,"line":213},11,[60,215,216],{"class":66},"    saving.value ",[60,218,81],{"class":94},[60,220,221],{"class":120}," false\n",[60,223,225],{"class":62,"line":224},12,[60,226,227],{"class":66},"  }\n",[60,229,231],{"class":62,"line":230},13,[60,232,233],{"class":66},"}\n",[60,235,237,240,242],{"class":62,"line":236},14,[60,238,239],{"class":66},"\u003C\u002F",[60,241,71],{"class":70},[60,243,88],{"class":66},[60,245,247],{"class":62,"line":246},15,[60,248,111],{"emptyLinePlaceholder":110},[60,250,252,254,257],{"class":62,"line":251},16,[60,253,67],{"class":66},[60,255,256],{"class":70},"template",[60,258,88],{"class":66},[60,260,262,265,268,271,273,276,279,282,284,287,290,292,295,298,300,302,305,307],{"class":62,"line":261},17,[60,263,264],{"class":66},"  \u003C",[60,266,267],{"class":70},"UiButton",[60,269,270],{"class":74}," variant",[60,272,81],{"class":66},[60,274,275],{"class":84},"\"solid\"",[60,277,278],{"class":66}," :",[60,280,281],{"class":74},"loading",[60,283,81],{"class":66},[60,285,286],{"class":84},"\"",[60,288,289],{"class":66},"saving",[60,291,286],{"class":84},[60,293,294],{"class":66}," @",[60,296,297],{"class":74},"click",[60,299,81],{"class":66},[60,301,286],{"class":84},[60,303,304],{"class":66},"save",[60,306,286],{"class":84},[60,308,88],{"class":66},[60,310,312],{"class":62,"line":311},18,[60,313,314],{"class":66},"    Зберегти\n",[60,316,318,321,323],{"class":62,"line":317},19,[60,319,320],{"class":66},"  \u003C\u002F",[60,322,267],{"class":70},[60,324,88],{"class":66},[60,326,328,330,332],{"class":62,"line":327},20,[60,329,239],{"class":66},[60,331,256],{"class":70},[60,333,88],{"class":66},[36,335,337],{"id":336},"чому-не-пакет","Чому не пакет",[10,339,340],{},"Пакет доводиться версіонувати, а компоненти інтерфейсу майже завжди\nпотребують дрібних правок під конкретний екран. Форк через npm-пакет\nболючий; форк через копіювання — це просто редагування файлу.",[10,342,343,344,348],{},"Натомість документація бере на себе те, чого копіювання не дає: пояснює,\n",[345,346,347],"strong",{},"чому"," компонент написаний саме так, і які баги кожне рішення закриває.",[350,351,352],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":56,"searchDepth":91,"depth":91,"links":354},[355,356],{"id":38,"depth":91,"text":39},{"id":336,"depth":91,"text":337},null,[],"Канонічна бібліотека UI-компонентів, зібрана з найкращих реалізацій у кількох продуктових кодових базах.",{},"md",{},"\u002Fdocs",{"title":5,"description":359},"stable","docs\u002Findex","IT0B0jDbjbdI4lVPXw1asinDgdsOJ6dJiDeO8Lh8CFM",1788072641409]