Mở đầu — vì sao bài này quan trọng
Ở Bài 12, bạn đã học cách tạo Components và Variants trong Figma — biết ghép nhiều trạng thái của một nút bấm vào chung một component set, biết thêm properties để chuyển đổi qua lại. Đó là kỹ năng "cơ khí": bạn biết cách bấm nút, kéo thả, cấu hình. Nhưng có một khoảng cách rất lớn giữa "biết tạo variant" và "thiết kế được một component mà cả đội — designer khác lẫn developer — dùng thích, dùng đúng, và không bao giờ phải hỏi lại bạn". Khoảng cách đó chính là tư duy thiết kế API cho component — chủ đề của bài học hôm nay.
Hãy dừng lại và nghĩ một chút. Khi một developer dùng một thư viện code, họ không quan tâm bên trong hàm viết thế nào. Họ chỉ quan tâm: hàm này nhận tham số gì? Trả về cái gì? Gọi thế nào? Tập hợp những "điểm chạm" đó gọi là API — Application Programming Interface, tức là bề mặt tương tác giữa người dùng và thứ họ đang dùng. Component trong Figma của bạn cũng có một API y hệt như vậy. Khi một designer khác kéo component Button của bạn ra từ thư viện, họ nhìn thấy panel Properties bên phải: có bao nhiêu tùy chọn, tên gọi ra sao, cái nào bật/tắt, cái nào chọn từ danh sách. Đó chính là API của bạn. Và cũng như trong lập trình, một API tồi sẽ khiến người dùng bối rối, dùng sai, hoặc tệ nhất là bỏ qua component của bạn để tự vẽ lại từ đầu — làm sụp đổ toàn bộ giá trị của một design system.
Bài này không dạy bạn thêm nút bấm nào trong Figma. Nó dạy bạn cách suy nghĩ như một engineer thiết kế interface — để mỗi component bạn tạo ra trở thành một sản phẩm có chủ đích, dễ dùng, khó dùng sai.
Khái niệm cốt lõi
Component là một sản phẩm có "người dùng"
Điều đầu tiên và quan trọng nhất cần khắc sâu: component của bạn có người dùng thật, và người dùng đó không phải là end-user của ứng dụng. Người dùng component của bạn là:
- Designer khác trong đội, những người kéo component ra để lắp ráp màn hình.
- Developer, những người đọc component trong Figma để hiểu cần code ra cái gì, có bao nhiêu trạng thái.
- Chính bạn của sáu tháng sau, khi quay lại và không nhớ mình đã nghĩ gì.
Surface API của một component gồm những gì
API — hay còn gọi là "surface", tức bề mặt mà người dùng chạm vào — của một component trong Figma bao gồm bốn loại property chính:
1. Variant properties (thuộc tính biến thể). Đây là những lựa chọn dạng "chọn một trong nhiều", ví dụ Type = Primary / Secondary / Ghost hoặc Size = Small / Medium / Large. Chúng thể hiện những khác biệt về hình thức mà mắt nhìn thấy được.
2. Boolean properties (thuộc tính bật/tắt). Đây là công tắc on/off cho những phần tùy chọn, ví dụ Show icon = true/false để ẩn hiện một icon trong nút.
3. Instance swap properties (thuộc tính hoán đổi instance). Cho phép người dùng thay một component con bên trong bằng component khác — ví dụ đổi icon trái của nút thành bất kỳ icon nào trong thư viện.
4. Text properties (thuộc tính văn bản). Phơi bày nội dung text ra ngoài để người dùng chỉnh trực tiếp trên panel mà không cần double-click vào sâu bên trong.
Bốn loại này chính là toàn bộ "ngôn ngữ" bạn dùng để nói chuyện với người dùng component. Nghệ thuật thiết kế API nằm ở chỗ: chọn đúng loại cho đúng nhu cầu, đặt tên rõ ràng, và giữ số lượng vừa đủ.
Nguyên tắc vàng: tối thiểu hóa bề mặt, tối đa hóa ý nghĩa
Trong thiết kế API, có một nguyên tắc mà mọi engineer đều thuộc lòng: API tốt nhất là API nhỏ nhất mà vẫn đủ dùng. Mỗi property bạn thêm vào là một quyết định bạn bắt người dùng phải đưa ra. Càng nhiều property, người dùng càng phải suy nghĩ nhiều, càng dễ chọn sai.
Hãy so sánh hai cách thiết kế nút:
- Cách A (bề mặt phình to):
Background color,Text color,Border color,Border width,Padding,Corner radius... — mười mấy property. Người dùng có toàn quyền, nhưng cũng có toàn quyền làm hỏng. Không có gì đảm bảo nút họ tạo ra đồng nhất với design system. - Cách B (bề mặt tinh gọn): chỉ
TypevàSize. Bên trong, mỗi tổ hợp Type/Size đã được bạn định nghĩa sẵn màu nền, màu chữ, padding, bo góc. Người dùng chỉ chọn "Primary + Medium" là xong, và luôn ra đúng.
Nghĩ theo trạng thái, không nghĩ theo giao diện
Một tư duy engineer quan trọng nữa: khi thiết kế API component, hãy liệt kê các trạng thái hợp lệ trước, rồi mới quyết định property. Một nút có thể ở trạng thái default, hover, pressed, disabled, loading. Một input có thể ở trạng thái empty, filled, focused, error, disabled. Việc của bạn là mô hình hóa các trạng thái này thành property một cách rõ ràng, để developer nhìn vào là biết chính xác họ cần code những state nào — không thiếu, không thừa.
Tình huống thực tế
Tình huống 1: Đội Momo và bài toán nút "Sản phẩm hóa"
Giả sử tại một fintech lớn ở Việt Nam như Momo, đội design system nhận phàn nàn: các designer sản phẩm mỗi người vẽ nút một kiểu, dev than phiền vì cùng một "nút chính" mà mười màn hình ra mười sắc thái xanh khác nhau. Khi rà lại, họ phát hiện component Button cũ có tới 14 property, bao gồm cả Fill color và Text color để trống cho designer tự điền.
Đội quyết định thiết kế lại API. Họ ngồi xuống và tự hỏi: "Một nút thực sự cần người dùng quyết định những gì?" Câu trả lời chỉ có ba thứ: nút này quan trọng đến đâu (Type), to nhỏ ra sao (Size), và có icon hay không (Show icon). Còn màu sắc, padding, bo góc — tất cả đều nên do design system quyết định, không phải designer từng màn hình.
API mới rút xuống còn: Type (Primary/Secondary/Ghost/Danger), Size (SM/MD/LG), State (Default/Hover/Disabled), một boolean Show icon, một instance swap cho icon, và một text property cho label. Kết quả sau một tháng: số biến thể màu nút "lạc" trên các màn hình giảm từ hàng chục xuống gần như bằng không. Bài học: phơi bày ít hơn không có nghĩa là kém linh hoạt — nó có nghĩa là bạn đã ra quyết định thay cho người dùng ở những chỗ họ không nên tự quyết.
Tình huống 2: Startup Đông Nam Á và property đặt tên mù mờ
Một startup thương mại điện tử ở Singapore có component Card với property tên Variant = 1 / 2 / 3. Designer mới vào team hoàn toàn không biết Variant 2 khác Variant 3 chỗ nào — họ phải kéo từng cái ra thử, hoặc nhắn hỏi người tạo. Tệ hơn, developer nhìn vào file Figma cũng chỉ thấy "Variant 3" và không biết đặt tên class hay component tương ứng thế nào trong code.
Sau khi audit, đội đổi tên: Variant trở thành Elevation = Flat / Raised / Floating, phản ánh đúng ý nghĩa (mức độ nổi của card qua shadow). Ngay lập tức, cả designer lẫn dev đều hiểu mà không cần giải thích. Bài học: tên property là một phần của API, và nó phải mô tả ý nghĩa chứ không phải số thứ tự vô nghĩa. Một cái tên tốt tiết kiệm hàng chục tin nhắn hỏi đáp. Quy tắc đơn giản: nếu người mới nhìn tên property mà không đoán được nó làm gì, tên đó đã thất bại.
Tình huống 3: Đội của bạn và cái bẫy "quá nhiều boolean"
Hãy tưởng tượng bạn thiết kế một component ListItem cho một app giao đồ ăn. Bạn thêm boolean cho mọi thứ tùy chọn: Show avatar, Show subtitle, Show badge, Show trailing icon, Show divider, Show checkbox. Sáu boolean nghĩa là 2 mũ 6 = 64 tổ hợp có thể xảy ra. Trong đó rất nhiều tổ hợp vô nghĩa hoặc trông vỡ layout — ví dụ vừa Show checkbox vừa Show trailing icon khiến hai thứ chồng lên nhau.
Một API tốt hơn sẽ nhóm những lựa chọn loại trừ nhau vào một variant property duy nhất: thay vì hai boolean checkbox/trailing icon xung đột, dùng Trailing = None / Icon / Checkbox / Toggle. Cách này biến 64 tổ hợp hỗn loạn thành một tập hợp trạng thái hữu hạn, rõ ràng, và không bao giờ vỡ. Bài học: khi hai boolean loại trừ lẫn nhau, hãy gộp chúng thành một variant. Boolean chỉ nên dùng cho những thứ thực sự độc lập, bật tắt tự do mà không ảnh hưởng nhau.
Hướng dẫn từng bước
Đây là quy trình thiết kế API cho một component mới, áp dụng được ngay với bất kỳ component nào bạn dựng trong Figma.
Bước 1 — Xác định người dùng và ngữ cảnh. Trước khi mở Figma, viết ra một câu: "Component này dùng ở đâu, ai lắp ráp nó, ai code nó?" Ví dụ: "Nút này dùng khắp app, designer sản phẩm lắp, đội frontend code bằng React." Câu này định hướng mọi quyết định sau.
Bước 2 — Liệt kê tất cả trạng thái hợp lệ. Viết ra mọi biến thể thực sự cần tồn tại: các loại (primary, secondary...), các cỡ, các trạng thái tương tác (default, hover, disabled, loading). Đây là "hợp đồng" giữa bạn và developer.
Bước 3 — Phân loại mỗi biến thể vào đúng loại property. Với mỗi thứ trong danh sách, hỏi: cái này là "chọn một trong nhiều" (→ variant), "bật/tắt độc lập" (→ boolean), "thay component con" (→ instance swap), hay "nội dung chữ" (→ text property)?
Bước 4 — Đặt tên theo ý nghĩa, không theo số. Đặt tên property và tên value bằng từ ngữ mô tả rõ ràng: Type, Size, Emphasis, Elevation — không dùng Variant 1/2/3. Dùng cùng một bộ từ vựng mà developer sẽ dùng trong code, để hai bên nói chung một ngôn ngữ.
Bước 5 — Cắt gọt không thương tiếc. Nhìn lại danh sách property và hỏi từng cái: "Nếu bỏ property này, người dùng có thực sự mất khả năng làm việc quan trọng không?" Nếu câu trả lời là không, hãy xóa. Mọi màu sắc, spacing, radius nên nằm bên trong component (nối với design token/variable từ Bài 14 và 15), không phơi ra ngoài.
Bước 6 — Gộp các boolean loại trừ nhau thành variant. Rà soát các boolean: có cặp nào không thể cùng bật một lúc không? Nếu có, gộp thành một variant property.
Bước 7 — Sắp xếp thứ tự và nhóm property. Trong Figma, đưa property quan trọng nhất lên trên. Người dùng nên gặp Type và Size trước, rồi mới đến các tùy chọn phụ. Thứ tự cũng là một phần của trải nghiệm API.
Bước 8 — Kiểm thử với người thật. Nhờ một đồng nghiệp chưa từng thấy component này kéo nó ra và dựng một ví dụ. Quan sát chỗ họ ngập ngừng, chỗ họ hỏi. Mỗi lần họ phải hỏi là một dấu hiệu API của bạn chưa đủ tự giải thích.
Lỗi thường gặp & mẹo
Lỗi 1 — Phơi bày quá nhiều. Đây là lỗi phổ biến nhất của người mới. Bạn nghĩ "cho người dùng nhiều tùy chọn = linh hoạt hơn = tốt hơn". Thực tế ngược lại: mỗi tùy chọn thừa là một cơ hội để phá vỡ tính đồng nhất. Mẹo: mặc định đặt mọi thứ vào bên trong component; chỉ phơi ra ngoài khi có nhu cầu thật, đã được kiểm chứng.
Lỗi 2 — Đặt tên theo hình thức thay vì mục đích. Blue button, Big card, Variant 3 — những cái tên này chết ngay khi design thay đổi. Nếu bạn đổi nút primary từ xanh sang tím, cái tên Blue button trở thành lời nói dối. Mẹo: đặt tên theo vai trò (Primary, Emphasis high), không theo thuộc tính hình ảnh cụ thể.
Lỗi 3 — Trộn lẫn nhiều trục quyết định vào một variant. Ví dụ tạo variant PrimarySmall, PrimaryLarge, SecondarySmall... — đây là gộp hai trục (type và size) vào một property, khiến số lượng bùng nổ và khó chọn. Mẹo: tách thành hai property độc lập Type và Size, để Figma tự tổ hợp.
Lỗi 4 — Bỏ quên trạng thái disabled và loading. Người mới thường chỉ làm default và hover, rồi dev phải tự đoán disabled trông thế nào. Mẹo: coi mọi trạng thái tương tác là một phần bắt buộc của hợp đồng với dev.
Lỗi 5 — API không khớp với code. Nếu designer gọi là Kind mà dev gọi là variant, mỗi lần handoff là một lần dịch thuật. Mẹo: ngồi cùng dev thống nhất bộ tên property ngay từ đầu — đây là khoản đầu tư nhỏ đổi lấy hàng tháng trơn tru.
Mẹo tổng quát: trước khi công bố một component, hãy tự viết một câu mô tả API của nó, kiểu: "Button có Type, Size, State, tùy chọn icon và label." Nếu câu đó dài dòng, rối rắm, API của bạn cũng vậy. Câu càng gọn, API càng tốt.
Bài tập thực hành
Bài tập 1 — Audit một component có sẵn. Lấy một component bất kỳ trong file Figma bạn đang làm (hoặc tải một UI kit miễn phí về). Liệt kê toàn bộ property của nó ra giấy. Với mỗi property, tự trả lời: (a) tên này có mô tả đúng ý nghĩa không? (b) property này có thực sự cần phơi ra ngoài không? (c) có boolean nào nên gộp thành variant không? Viết lại bản thiết kế API tinh gọn hơn.
Bài tập 2 — Thiết kế API cho một Badge từ đầu. Không mở Figma vội. Trên giấy, thiết kế API cho một component Badge (huy hiệu nhỏ hiển thị trạng thái như "Mới", "Hết hàng", "Giảm giá"). Xác định: cần bao nhiêu variant property? tên là gì? có cần boolean nào không? có text property không? Mục tiêu: API nhỏ nhất mà vẫn phủ hết nhu cầu thực tế. Sau đó dựng nó trong Figma và đối chiếu.
Bài tập 3 — Thử nghiệm với người thật. Đưa component Badge bạn vừa dựng cho một người bạn cùng học, không giải thích gì. Nhờ họ tạo một badge "Giảm 50%". Ghi lại mọi chỗ họ ngập ngừng hoặc hỏi. Đó chính là những điểm yếu trong API của bạn — hãy sửa lại và thử với người thứ hai.
Tóm tắt
Component không chỉ là một hình vẽ được đóng gói — nó là một sản phẩm có API, có người dùng thật là các designer và developer trong đội bạn. Bề mặt API đó gồm bốn loại property: variant, boolean, instance swap, và text. Tư duy engineer khi thiết kế API xoay quanh vài nguyên tắc cốt lõi: giữ bề mặt nhỏ nhất có thể mà vẫn đủ dùng, đặt tên theo ý nghĩa chứ không theo hình thức hay số thứ tự, mô hình hóa theo trạng thái hợp lệ thay vì theo giao diện rời rạc, và gộp các lựa chọn loại trừ nhau thành variant thay vì để boolean xung đột.
Ba tình huống thực tế — từ đội fintech gọn hóa nút xuống còn ba quyết định, đến startup đổi Variant 2/3 thành Elevation có nghĩa, đến cái bẫy 64 tổ hợp boolean — đều dẫn về một chân lý: một API tốt là API khó dùng sai. Khi bạn thiết kế component với tư duy này, bạn không còn chỉ là người vẽ giao diện; bạn trở thành người xây nền móng để cả đội chạy nhanh mà không vấp. Ở bài tiếp theo, chúng ta sẽ đi sâu vào Design Tokens — lớp foundation cho phép bạn nhét toàn bộ màu sắc, spacing, radius vào bên trong component để giữ cho API luôn tinh gọn như bài này vừa dạy.