חוזה העיצוב
כל חלק ציבורי מקבל ישירות את className, את style, את ref, את מטפלי האירועים, את ה-props המובנים ואת מאפייני ה-data-* שלכם. הרכיבים מספקים גם מאפייני slot בעלי טיפוסים להעברת מחלקות, מאפייני בדיקה ו-props מובנים אחרים לאלמנטים שהם מייצרים מנתונים. אין props מקבילים כגון contentClassName או triggerClassName.
uiify אחראית למאפייני הזהות והמצב. הם נקודות חיבור לעיצוב: שנו מצב דרך props או התנהגות HTML מובנית, ולעולם לא באמצעות כתיבה ל-data-state. מרחב השמות --uiify-* שמור לגאומטריה, להנפשה ולערכים של מופע מסוים.
<Popover.Root>
<Popover.Trigger className="toolbar-trigger">Open</Popover.Trigger>
<Popover.Content className="toolbar-popover" data-layout="compact">
Actions
</Popover.Content>
</Popover.Root>השתמשו במאפיין המחלקה הרגיל של חלק כשאתם שולטים בו ב-JSX. השתמשו במאפייני ה-slot של הרכיב כשהוא יוצר את האלמנט, והתאימו פריט חוזר לפי המפתח שלו כשהדבר נתמך. כך מאפייני העיצוב והבדיקה נשארים צמודים לאלמנט שאליו הם שייכים.
שמות
| נקודת חיבור | מטרה | דוגמה |
|---|---|---|
| סמני זהות | זהות רכיב יציבה, באחריות uiify | data-uiify-popover |
| סמני מבנה | חלק ציבורי של רכיב מורכב, באחריות uiify | data-part="content" |
| מאפייני מצב | שיקוף מצב לקריאה בלבד עבור בוררים | data-state="open" |
| מאפיינים מותאמים | גאומטריה דינמית וערכים לכל מופע | --uiify-anchor-x |
לכל שורש שמחזיק מצב יש סמן יחיד מסוג data-uiify-<component>, שעצם נוכחותו היא הערך שלו. לכל חלק מורכב יש ערך data-part יחיד ב-kebab-case, כגון trigger, content, item או label. ה-props של הצרכן יכולים לדרוס את הערכים האלה; סמנים שנדרסו כבר לא יתאימו לסגנונות שסופקו.
CSS רגיל ו-Tailwind
הציבו מחלקות פריסה ועיצוב על החלק שאליו הן שייכות. השתמשו במאפייני המצב והמבנה של הרכיב כווריאציות כשהעיצוב תלוי במצב; הימנעו מעיצוב חלקים פנימיים באמצעות בוררים ארוכים על הורה שאינו קשור אליהם.
[data-uiify-popover][data-part="content"] {
min-inline-size: 12rem;
}
[data-uiify-popover][data-part="content"][data-state="open"] {
opacity: 1;
}
/* Tailwind uses the same attributes. */
<div className="data-[state=open]:opacity-100" />שמרו כללי CSS סטטיים קטנים לאפקטים שברורים או אמינים יותר שם, כמו פסאודו-אלמנטים מורכבים, מעברי starting-style, בוררים יחסיים מסובכים או הנפשה משותפת. Tailwind ו-CSS יכולים לדור יחד; השאירו כל מאפיין חזותי באחריות כלל אחד כדי שסדר הקדימויות יישאר צפוי.
פולימורפיזם
as ו-render מחליפים את האלמנט שמרונדר. מרנדר מותאם חייב להעביר את ה-props ואת ה-ref שהוא מקבל לאלמנט ה-DOM, אחרת הסמנים, המצב והעיצוב מפסיקים לעבוד.
behavior.css נדרש
גיליון הסגנונות הזה מכיל את הכללים שמאפשרים למצב לעבוד: מיקום חלוניות קופצות, קביעת גודל של ::details-content, הפצה באמצעות :has(), מיקום שדות קלט מוסתרים ומעברי @starting-style. הוא אינו מכיל צבעים, גופנים או מרווחים.
import "@gunkin/uiify/components/behavior.css";בלעדיו הרכיבים מתרנדרים, אבל המצב שלהם אינו עובד. ייבאו אותו פעם אחת, בכל מקום באפליקציה.
מצב הוא מאפיין, לא מחלקה
הרכיבים חושפים מצב באמצעות מאפייני data-* על האלמנט שמחזיק אותו, כך ש-CSS יכול לבחור בו ללא JavaScript או שמות מחלקות. כל עמוד רכיב מפרט את המאפיינים שהוא מפיק.
.my-trigger[data-state="open"] { … }
.my-item[data-disabled] { … }
/* Native state works the same way, because the state IS native */
.my-panel:popover-open { … }
details[open] > summary { … }גם וריאציות הן מאפייני data-*, ולא שאילתות סגנון של מכל, משום שמכל אינו יכול לתשאל את עצמו.
ערכים בתוך האלמנט, כללים בגיליון סגנונות
ערכים לכל מופע מגיעים כמאפיינים מותאמים בתוך האלמנט; כל כלל נמצא בגיליון סגנונות סטטי. סגנונות בתוך האלמנט אינם יכולים לבטא פסאודו-מחלקות, פסאודו-אלמנטים, שאילתות מכל או @starting-style, ומודל המצב תלוי בכולם.
מאפיינים בתוך האלמנט נשלחים בהזרמה עם ה-HTML ללא אי-התאמות בהידרציה, וגיליון סגנונות אחד מפוענח פעם אחת ונשמר במטמון. לעומתם, CSS-in-JS מזריק מקטעי <style> לכל גבול ואינו משתמש במטמון בין בקשות.
שלוש דרכים לעצב
CSS משלכם. בחרו את האלמנט ואת מאפייני ה-data-* שלו; אין סגנונות ברירת מחדל שצריך לדרוס.
Tailwind. הציבו מחלקות עזר על חלקים ציבוריים או העבירו אותן דרך מאפייני ה-slot של הרכיב לאלמנטים שנוצרים אוטומטית. אותם מאפיינים פועלים כווריאציות, למשל data-[state=open]:rotate-180. התצוגות המקדימות באתר עוברות למעטפת העיצוב של Tailwind דרך הגדרת הסגנון בכותרת העמוד.
@gunkin/uiify/styles. שכבת CSS רגיל אופציונלית עם סולמות של אסימוני עיצוב ב-OKLCH, ערכות עיצוב בהירה וכהה ומעטפת עיצוב לכל רכיב — נקודת פתיחה, לא חובה.
import "@gunkin/uiify/styles/reset";
import "@gunkin/uiify/styles";סדר הקדימויות
כל מה ש-uiify מספקת נמצא בשכבה בעלת שם מתחת לשלכם:
@layer ui.reset, ui.behavior, ui.tokens, ui.theme, app;השכבה שלכם תמיד גוברת: התאמות אינן דורשות !important או תחבולות ספציפיות, והן שורדות ארגון מחדש של הספרייה.
כל עמוד רכיב מפרט את המאפיינים ואת משתני ה-CSS שלו, עם CSS מוכן להעתקה לשתי מעטפות העיצוב.