وقتی یک Design System شروع به رشد میکند، معمولاً Tokenها هم همراه آن بیشتر میشوند. در ابتدا چند Color Token و Spacing Token داریم، بعد Typography، Radius و Shadow اضافه میشوند و کمی بعد برای اندازه Componentها، ارتفاعها، فاصلههای داخلی، Borderها و حتی بعضی مقادیر بسیار خاص هم Token تعریف میکنیم.
در ظاهر این اتفاق میتواند نشانه بلوغ سیستم باشد. بهجای اینکه مقدار 16px را مستقیماً در چند جای محصول استفاده کنیم، برای آن یک Token داریم و بهجای استفاده مستقیم از یک Hex Code، از یک نام Semantic استفاده میکنیم.
اما اگر این مسیر را بدون مرز ادامه دهیم، با سؤال مهمی روبهرو میشویم:
آیا واقعاً هر مقداری که در Interface وجود دارد باید Token داشته باشد؟
Token ساختن با حذف Hard-coded Value یکی نیست
یکی از برداشتهای رایج این است که هر Hard-coded Value باید در نهایت به Token تبدیل شود. اگر در یک Component مقدار 24px میبینیم، پس باید برایش Token داشته باشیم. اگر یک Width مشخص داریم، آن هم باید Token شود و اگر در جایی Radius متفاوتی وجود دارد، احتمالاً Token دیگری کم داریم.
اما صرف اینکه یک Value در Interface وجود دارد، دلیل کافی برای Token شدن آن نیست.
فرض کنید در یک صفحه خاص، Illustration باید حداکثر 320px عرض داشته باشد. میتوانیم Tokenی مثل illustration-max-width تعریف کنیم، اما سؤال مهمتر این است که این Token قرار است چه تصمیم مشترکی را در سیستم مدیریت کند؟
اگر این مقدار فقط در همان Context استفاده میشود، قرار نیست Theme آن را تغییر دهد، در محصولات دیگر تکرار نمیشود و هیچ تصمیم سیستمی پشت آن وجود ندارد، تبدیل کردنش به Token الزاماً ارزش جدیدی ایجاد نمیکند.
فقط یک مقدار را با یک اسم جایگزین کردهایم.
Token باید نماینده یک تصمیم باشد، نه فقط یک عدد
شاید یکی از بهترین راهها برای تصمیمگیری درباره Tokenها این باشد که به آنها بهعنوان Decision نگاه کنیم، نه Variable.
برای مثال، spacing-md فقط جایگزین 16px نیست. این Token میگوید در سیستم ما یک سطح مشخص از Spacing وجود دارد که در موقعیتهای مختلف میتوانیم به آن ارجاع دهیم و اگر روزی تصمیم سیستم درباره این فاصله تغییر کرد، میتوانیم آن تغییر را بهصورت کنترلشده مدیریت کنیم.
یک Semantic Color هم فقط جایگزین یک Hex Code نیست. مثلاً text-danger بیان میکند که این رنگ برای انتقال معنای مشخصی در Interface استفاده میشود و Themeهای مختلف میتوانند مقدار متفاوتی برای همان مفهوم داشته باشند.
در هر دو مثال، Token چیزی فراتر از Value را نگه میدارد؛ Token یک تصمیم قابل استفاده مجدد را نمایندگی میکند.
به همین دلیل، قبل از ساخت Token جدید شاید بهتر باشد بهجای اینکه بپرسیم «این مقدار Hard-coded است؟»، بپرسیم:
آیا این مقدار نماینده تصمیمی است که میخواهیم در سطح سیستم کنترل کنیم؟
Token بیشتر همیشه به معنی سیستم منعطفتر نیست
فرض کنید برای هر Spacing کوچک در Componentها یک Token جداگانه بسازیم. برای فاصله Icon تا Label یک Token داشته باشیم، برای Padding داخلی Button یکی دیگر، برای فاصله Header تا Content یکی دیگر و برای هر Component هم مجموعهای از Tokenهای اختصاصی تعریف کنیم.
در ابتدا این معماری بسیار Flexible به نظر میرسد، چون تقریباً هر چیزی را میتوان از طریق Token تغییر داد.
اما این انعطاف هزینه دارد.
Designer حالا باید بداند برای یک فاصله ساده از کدام Token استفاده کند. Developer باید تفاوت بین چندین Token نزدیک به هم را بفهمد. Documentation باید توضیح دهد هرکدام کجا استفاده میشوند و تیم Design System هم باید مطمئن شود تغییر یک Token اثر ناخواستهای روی بخش دیگری از محصول ایجاد نمیکند.
در چنین شرایطی ممکن است Complexity را حذف نکرده باشیم؛ فقط آن را از Componentها به Token Architecture منتقل کرده باشیم.
سؤال مهمتر این است که چه چیزی باید قابل تغییر باشد
یکی از دلایل اصلی استفاده از Tokenها این است که بعضی تصمیمها را بتوانیم در مقیاس سیستم تغییر دهیم.
فرض کنید چند Brand داریم. منطقی است که Color، Typography یا حتی Radius در بعضی شرایط از طریق Token کنترل شوند، چون احتمال دارد مقدار آنها بین Brandها متفاوت باشد.
یا اگر Light Mode و Dark Mode داریم، Semantic Color Tokenها اهمیت زیادی پیدا میکنند، چون یک مفهوم مثل Surface یا Text میتواند در Themeهای مختلف مقدار متفاوتی داشته باشد.
اما آیا Width یک Illustration خاص هم باید بین Themeها تغییر کند؟ آیا Padding یک Layout کاملاً اختصاصی باید بخشی از Token Architecture باشد؟
احتمالاً نه.
بنابراین یکی از معیارهای خوب برای Tokenization این است که بپرسیم:
آیا انتظار داریم این تصمیم در آینده بهصورت هماهنگ در چند نقطه تغییر کند؟
اگر پاسخ مثبت باشد، Token میتواند ابزار مناسبی باشد. اگر پاسخ منفی باشد، شاید نیازی نباشد یک لایه Abstraction دیگر ایجاد کنیم.
تکرار شدن هم بهتنهایی دلیل کافی نیست
ممکن است یک مقدار 12px در دهها جای محصول تکرار شده باشد، اما این لزوماً به این معنی نیست که تمام این موارد باید به یک Token متصل شوند.
چرا؟ چون ممکن است این مقادیر امروز اتفاقی برابر باشند.
برای مثال، فاصله Icon تا Label ممکن است 8px باشد و Padding یک Component دیگر هم 8px. از نظر عددی یکساناند، اما آیا از نظر معنایی هم یک تصمیم هستند؟
اگر فردا تصمیم بگیریم فاصله Icon تا Label را تغییر دهیم، آیا Padding Component دیگر هم باید تغییر کند؟
اگر جواب «نه» باشد، این دو مقدار با وجود یکسان بودن، الزاماً نباید به یک تصمیم مشترک متصل شوند.
این دقیقاً یکی از جاهایی است که Token Architecture میتواند بهاشتباه Dependency ایجاد کند.
برابری Value به معنی برابری Meaning نیست.
Token اضافی فقط هزینه پیدا کردن ندارد
زیاد شدن Tokenها مشکل دیگری هم ایجاد میکند: تغییر دادن سیستم سختتر میشود.
فرض کنید بعد از چند سال صدها Token داریم که بعضی Semantic هستند، بعضی مخصوص Component، تعدادی Legacy شدهاند و بعضی فقط در یک یا دو نقطه استفاده میشوند.
حالا میخواهیم ساختار Spacing سیستم را تغییر دهیم.
قبل از هر تغییری باید بفهمیم هر Token کجا استفاده شده، به چه Token دیگری Alias شده، حذف آن روی کدام Component اثر میگذارد و آیا تیمی خارج از Design System هم مستقیماً از آن استفاده کرده است یا نه.
در این مرحله، چیزی که قرار بود تغییرات را سادهتر کند خودش میتواند به شبکهای از Dependencyها تبدیل شود.
به همین دلیل، هزینه Token فقط زمانی که ساخته میشود نیست. هر Token جدید باید نامگذاری، مستندسازی، نگهداری، Migration و در نهایت شاید Deprecated یا حذف شود.
شاید برای ساخت Token به یک سؤال ساده نیاز داشته باشیم
قبل از اضافه کردن Token جدید میتوانیم چند سؤال مطرح کنیم:
آیا این مقدار یک تصمیم مشترک را نمایندگی میکند؟
آیا در چند Context واقعاً با یک Meaning استفاده میشود؟
آیا احتمال دارد بخواهیم آن را در سطح سیستم تغییر دهیم؟
آیا Theme، Brand یا Platform دیگری باید بتواند مقدار متفاوتی برای آن داشته باشد؟
اگر این مقدار تغییر کند، آیا تمام مصرفکنندگانش باید با هم تغییر کنند؟
آیا نام Token میتواند معنای آن را بدون وابستگی به یک صفحه یا Feature خاص توضیح دهد؟
اگر برای این مقدار Token نسازیم، واقعاً چه مشکلی ایجاد میشود؟
اگر پاسخ بیشتر این سؤالها منفی باشد، شاید آن Value اصلاً نیازی به Token شدن نداشته باشد.
حتی Tokenهای موجود هم باید گاهی زیر سؤال بروند
بحث Tokenization فقط درباره این نیست که چه Token جدیدی اضافه کنیم. گاهی باید بررسی کنیم چه Tokenهایی دیگر ارزش نگهداری ندارند.
ممکن است Tokenی سالها قبل برای Use Case خاصی ساخته شده باشد که دیگر وجود ندارد. ممکن است دو Token در طول زمان به یک Meaning رسیده باشند یا Tokenی آنقدر Product-specific باشد که عملاً فقط یک Component از آن استفاده کند.
همانطور که Component Library نیاز به Maintenance دارد، Token Architecture هم باید بتواند کوچک شود.
اینکه Tokenی قبلاً ساخته شده، دلیل کافی برای ماندن همیشگی آن نیست.
هدف Tokenization رسیدن به صفر Hard-code نیست
داشتن Hard-coded Value همیشه نشانه ضعف Design System نیست. گاهی یک مقدار واقعاً Local است و هیچ دلیلی برای قرار گرفتن آن در لایه سیستم وجود ندارد.
اگر هدف را «حذف تمام Hard-codeها» تعریف کنیم، احتمالاً در نهایت برای مقادیری Token میسازیم که هیچ ارزش سیستمی ندارند. Dashboard ما ممکن است نشان دهد ۱۰۰ درصد Valueها Tokenized شدهاند، اما تیمها برای پیدا کردن Token مناسب باید بین صدها گزینه جستوجو کنند.
در چنین شرایطی از نظر Metric موفق شدهایم، اما شاید تجربه استفاده از سیستم را بدتر کرده باشیم.
هدف بهتر میتواند این باشد که تصمیمهای مهم، مشترک و قابل تغییر سیستم را از طریق Tokenها مدیریت کنیم و اجازه دهیم تصمیمهای واقعاً Local همان Local باقی بمانند.
جمعبندی
Tokenها یکی از قدرتمندترین ابزارهای Design System هستند، چون کمک میکنند تصمیمهای طراحی را از Valueهای پراکنده جدا کنیم و آنها را در سطح سیستم مدیریت کنیم. اما همین قدرت میتواند باعث شود تصور کنیم هر چیزی باید به Token تبدیل شود.
هر عدد، رنگ یا اندازهای الزاماً یک تصمیم سیستمی نیست و هر تکراری هم الزاماً نیازمند Abstraction نیست.
شاید قبل از ساخت Token جدید، سؤال اصلی نباید این باشد که:
برای این Value چه اسمی انتخاب کنیم؟
بلکه بهتر است ابتدا بپرسیم:
چرا اصلاً میخواهیم این Value را Token کنیم و قرار است چه تصمیمی را با آن مدیریت کنیم؟
چون یک Token خوب فقط یک اسم برای یک مقدار نیست؛ نماینده تصمیمی است که ارزش مدیریت شدن در مقیاس Design System را دارد.
کامنتها
…