แนวทาง
วิธีใช้ระบบให้สม่ำเสมอทุกหน้า ทั้งสองแบรนด์ อ่านก่อนสร้างหน้าใหม่หรือเพิ่มคอมโพเนนต์
ติดตั้ง
เลือกวิธีที่เหมาะกับโปรเจกต์ ทั้งสามวิธีใช้ CSS ชุดเดียวกัน
<link rel="stylesheet" href="https://components.aswinology.com/ds/v1/ds.css">
<html lang="th" data-brand="aswinology">// app/layout.tsx: load only the fonts of the brand you ship
import { Archivo, Anuphan, Geist_Mono } from "next/font/google"; // ASWINOLOGY°
import { Inter_Tight, Geist, Noto_Sans_Thai, Geist_Mono } from "next/font/google"; // Lurnelle
const archivo = Archivo({ subsets: ["latin"], axes: ["wdth"], variable: "--f-archivo" });
const anuphan = Anuphan({ subsets: ["thai", "latin"], variable: "--f-anuphan" });
const mono = Geist_Mono({ subsets: ["latin"], variable: "--f-geist-mono" });
<html lang="th" data-brand="aswinology" className={`${archivo.variable} ${anuphan.variable} ${mono.variable}`}>โค้ด React อยู่ในโฟลเดอร์ DESIGN-SYSTEM/ui ของ repo ASWINOLOGY คัดลอกทั้งโฟลเดอร์ไปเป็น @/ui แล้ว import สไตล์สามไฟล์ใน layout
หลักการ
- โทเคนก่อนค่าสี ทุกสี มุมโค้ง เงา และระยะ อ่านจากโทเคน ความต้องการใหม่กลายเป็นโทเคนใหม่ ไม่ใช่ค่าลอยๆ
- ใช้ของเบราว์เซอร์ก่อน dialog, details, select, input ได้การเข้าถึงและมือถือมาฟรี
- หนึ่งหน้าจอ หนึ่งเป้าหมาย ปุ่ม primary หนึ่งปุ่ม หัวข้อหนึ่งเรื่อง
- ไทยก่อน เขียน ทดสอบ และวัดระยะด้วยข้อความไทยจริง ไม่ใช่ lorem ipsum
- ซื่อตรง ไม่แต่งตัวเลข รีวิว ราคา หรือภาพบุคคล
รายการตรวจการเข้าถึง
ทุกคอมโพเนนต์ในไลบรารีผ่านรายการนี้แล้ว หน้าใหม่ต้องผ่านด้วย
ตัวอักษรไทย
ภาษาไทยมีสระบน สระล่าง และวรรณยุกต์ซ้อนกันได้สามชั้น ระยะที่ดีสำหรับอังกฤษจึงมักแน่นเกินไปสำหรับไทย
ช่องไฟติดลบ บรรทัด 1.0
ผู้เรียนที่กำลังเติบโต
ทุกวันไม่หยุดนิ่ง
ช่องไฟ 0 บรรทัด 1.25
ผู้เรียนที่กำลังเติบโต
ทุกวันไม่หยุดนิ่ง
- หัวข้อไทยใช้ line-height อย่างน้อย 1.2 เนื้อหา 1.6 base.css ตั้งให้อัตโนมัติผ่าน :lang(th)
- ไม่ใช้ตัวเอียงและไม่ใช้ตัวพิมพ์ใหญ่ทั้งคำกับข้อความไทย ใช้น้ำหนักหรือสีแทน
- ใช้ text-wrap: balance กับหัวข้อ และตัดคำด้วยเว้นวรรคหรือ <wbr> เมื่อจำเป็น
- ตัวเลขในตารางใช้เลขอารบิกและ tabular-nums
การเขียนใน UI
ใช้เมื่อไร
ควรทำ
- ปุ่มขึ้นต้นด้วยกริยา ไม่เกินสามคำ: บันทึก, เริ่มเรียน
- ข้อผิดพลาดบอกว่าเกิดอะไรและแก้อย่างไร
- ใช้คำเดียวกันกับสิ่งเดียวกันทุกหน้า: คอร์ส ไม่ใช่สลับกับหลักสูตร
- Lurnelle เรียกผู้ใช้ว่า คุณ
ไม่ควรทำ
- ใช้เครื่องหมายตกใจในข้อความระบบ
- ใช้ขีดยาว em dash ในข้อความ ใช้จุลภาคหรือขึ้นประโยคใหม่
- เขียนว่า คลิกที่นี่ หรือ ดูเพิ่มเติม โดยไม่บอกปลายทาง
- สัญญาผลลัพธ์ที่วัดไม่ได้ เช่น สอบติดแน่นอน
ลำดับของปุ่ม
หนึ่งหน้าจอมี primary ได้หนึ่งปุ่ม การกระทำรองใช้ secondary หรือ outline ยกเลิกใช้ ghost
- ใน Dialog และฟอร์ม ปุ่มยืนยันอยู่ขวาสุด ปุ่มยกเลิกอยู่ทางซ้ายของมัน
- danger ใช้เฉพาะการกระทำที่ย้อนกลับไม่ได้ และบอกผลในข้อความปุ่ม เช่น ลบถาวร
- ถ้าย้อนกลับได้ ให้ทำทันทีแล้วแสดง Toast ที่มีปุ่มเลิกทำ แทนการถามยืนยัน
เลือก overlay ให้ถูก
| คอมโพเนนต์ | ใช้เมื่อ | ไม่ใช้เมื่อ |
|---|---|---|
| Dialog | ต้องหยุดผู้ใช้ เช่น ยืนยัน หรือฟอร์มสั้น | เนื้อหายาว หรือข้อมูลที่ไม่เร่งด่วน |
| Sheet | ตัวกรอง เมนูมือถือ รายละเอียดข้างรายการ | การยืนยันสั้นๆ |
| Menu | รายการคำสั่งของสิ่งหนึ่ง | การนำทางหลักของเว็บ |
| Tooltip | ชื่อของปุ่มไอคอน คำอธิบายศัพท์ | ข้อมูลจำเป็น หรือสิ่งที่กดได้ |
| Toast | ผลของสิ่งที่ผู้ใช้เพิ่งทำ | ข้อผิดพลาดของฟอร์ม ใช้ข้อความใต้ช่องแทน |
สิ่งที่ไม่ควรทำ
ค่า hex ไม่เปลี่ยนตามแบรนด์และธีม
style={{ background: "#cdf46e" }}แทนด้วย
style={{ background: "var(--accent)" }}placeholder หายเมื่อพิมพ์ และคอนทราสต์ต่ำ
<input placeholder="อีเมล" />แทนด้วย
<Field label="อีเมล"><Input /></Field>โปรแกรมอ่านหน้าจอไม่รู้ว่าเปิดอะไรขึ้นมา
<Dialog trigger={…}>…</Dialog> // no titleแทนด้วย
<Dialog title="ลบคอร์สนี้ถาวร?" …>ปุ่มไม่มีชื่อ
<Button iconOnly><Trash /></Button>แทนด้วย
<Button iconOnly aria-label="ลบ"><Trash aria-hidden="true" /></Button>วรรณยุกต์ชนกัน ตัวเอียงอ่านยาก
.thai-title { letter-spacing: -0.04em; font-style: italic; }แทนด้วย
:lang(th) .title { letter-spacing: 0; }ทำงานทุกเฟรมและไม่ล้างเมื่อออกจากหน้า
window.addEventListener("scroll", animate)แทนด้วย
useGSAP(() => { /* ScrollTrigger */ }, { scope })เพิ่มโทเคนหรือคอมโพเนนต์
แก้ที่ต้นทางเท่านั้น ไฟล์ CSS ของโทเคนและไฟล์ใน public/ds ถูกสร้างใหม่ทุกครั้งที่ dev หรือ build
// tokens/tokens.mjs
semantic: {
"highlight": ["tint-butter", "#2a2410"], // [light, dark]
}
// then
npm run tokens // writes ui/styles/tokens.css and public/ds/v1/tokens.json
// the contrast table on /tokens updates on the next build- เขียนคอมโพเนนต์ใน
ui/อ่านเฉพาะ semantic และ component token - เพิ่มสไตล์ใน
ui/styles/components.cssคลาสขึ้นต้นด้วยds-variant เป็นdata-* - เพิ่มหน้าเอกสารใน
docs/components/และรายการในdocs/registry.ts - ตรวจทั้งสองแบรนด์ สองธีม จอ 375 px และคีย์บอร์ดอย่างเดียว