Tokens
สี 4 ตัวจาก moodboard เป็นค่าดิบ (--palette-*) ส่วน component ใช้ token เชิงความหมาย (--color-*) ซึ่งปรับเฉดให้ข้อความผ่าน WCAG AA ทั้งธีมสว่างและมืด
Spacing
ใช้เป็น gap / padding ทั้งหมด ห้ามใช้ค่าที่ไม่อยู่ในสเกล
Radius
sm สำหรับปุ่ม/ช่องกรอก · md สำหรับกล่อง/ตาราง · lg สำหรับ Card และ Modal
Shadow
มี 2 ระดับเท่านั้น: sm สำหรับสิ่งที่วางบนหน้า, md สำหรับสิ่งที่ลอยเหนือหน้า
Typography
IBM Plex Sans Thai ทุกระดับ ภาษาไทยมีสระบน-ล่างและวรรณยุกต์ จึงตั้ง line-height ของ Body ไว้ 1.7 เพื่อไม่ให้บรรทัดชนกัน
หนังสือที่จองไว้จะถูกเก็บไว้ที่เคาน์เตอร์ 3 วันทำการนับจากวันที่ได้รับแจ้ง หากไม่มารับภายในกำหนด ระบบจะยกเลิกการจองและส่งต่อให้ผู้ที่รอคิวถัดไปโดยอัตโนมัติ
ISBN 978-616-7800-12-4 · เลขเรียก 720.9593 ส134 · ชั้น 2 โซน B
Button
4 แบบ × 3 ขนาด พร้อมสถานะ Hover / Focus / Disabled / Loading ลองกดปุ่มในคอลัมน์ Loading เพื่อดูการทำงานจริง หรือกด Tab เพื่อดู focus ring
| แบบ | S · 32px | M · 40px | L · 48px |
|---|---|---|---|
| Primary | |||
| Secondary | |||
| Ghost | |||
| Destructive |
| แบบ | Default | Hover | Focus | Disabled | Loading |
|---|---|---|---|---|---|
| Primary | |||||
| Secondary | |||||
| Ghost | |||||
| Destructive |
✓ ใช้เมื่อไหร่
- Primary — การกระทำหลักของหน้า 1 ปุ่มต่อหน้าจอ เช่น "จองเล่มนี้", "ยืนยันการจอง"
- Secondary — ทางเลือกที่สำคัญรองลงมา เช่น "เพิ่มในรายการอยากอ่าน"
- Ghost — การกระทำเสริมที่ไม่ควรแย่งสายตา เช่น "ดูรายละเอียด", "ยกเลิก" ใน Modal
- Destructive — การกระทำที่ย้อนกลับไม่ได้ เช่น ยกเลิกการจอง ควรมี Modal ยืนยันก่อนเสมอ
- Loading — ระหว่างส่งข้อมูล ให้คงความกว้างปุ่มและปิดการกดซ้ำ
✕ ไม่ควรใช้เมื่อไหร่
- อย่าวาง Primary หลายปุ่มในกลุ่มเดียวกัน ผู้ใช้จะไม่รู้ว่าควรกดอะไร
- อย่าใช้ Destructive กับการกระทำที่ย้อนกลับได้ เช่น "ล้างตัวกรอง" ให้ใช้ Ghost
- อย่าใช้ปุ่มแทนลิงก์ไปหน้าอื่น ถ้าพาไปหน้าใหม่ให้ใช้
<a> - อย่าเขียนข้อความกว้าง ๆ อย่าง "ตกลง" หรือ "ส่ง" ให้บอกสิ่งที่จะเกิดขึ้นจริง
- อย่าปิดปุ่ม (Disabled) โดยไม่บอกเหตุผลใกล้ ๆ ปุ่ม
Input · Select · Checkbox
ทุกช่องมี label อยู่ด้านบนเสมอ ข้อความ error ผูกกับช่องด้วย aria-describedby และบอกวิธีแก้ ลองพิมพ์รหัสสมาชิกแล้วกด Tab ออกจากช่อง
✓ ใช้เมื่อไหร่
- Input — ข้อมูลที่ผู้ใช้ต้องพิมพ์เอง เช่น รหัสสมาชิก เบอร์โทร คำค้นหา
- Select — ตัวเลือก 5–15 รายการที่รู้ชุดแน่นอน เช่น สาขา หมวดหนังสือ
- Checkbox — ตัวเลือกเปิด/ปิดที่เลือกได้หลายข้อพร้อมกัน หรือยอมรับเงื่อนไข
- Error — แสดงหลังผู้ใช้ออกจากช่องหรือกดส่ง พร้อมบอกวิธีแก้ที่ทำได้ทันที
✕ ไม่ควรใช้เมื่อไหร่
- อย่าใช้ placeholder แทน label ข้อความจะหายเมื่อเริ่มพิมพ์
- อย่าใช้ Select ถ้ามีแค่ 2–3 ตัวเลือก ให้แสดงเป็นตัวเลือกให้เห็นทั้งหมด
- อย่าใช้ Select ถ้ามีเกิน 15 รายการ เช่น รายชื่อหนังสือ ให้ใช้ช่องค้นหาแทน
- อย่าแสดง error ตั้งแต่ผู้ใช้ยังพิมพ์ไม่จบ และอย่าบอกแค่ด้วยสีแดง ต้องมีข้อความกำกับ
Badge สถานะ
สถานะของหนังสือและการจองใน Hono สื่อด้วยทั้งสี จุดนำหน้า และข้อความ จึงอ่านได้แม้ไม่เห็นสี
✓ ใช้เมื่อไหร่
- บอกสถานะที่เปลี่ยนได้ของสิ่งหนึ่ง เช่น สถานะเล่ม สถานะการจอง
- ในตารางหรือ Card ที่ผู้ใช้ต้องกวาดตาหาสิ่งที่ต้องทำต่อ
- ข้อความสั้น 1–3 คำ
✕ ไม่ควรใช้เมื่อไหร่
- อย่าใช้ Badge เป็นปุ่มหรือลิงก์ เพราะหน้าตาไม่บอกว่ากดได้
- อย่าใช้แสดงหมวดหมู่หรือแท็กหนังสือ ใช้สีสถานะกับสิ่งที่ไม่ใช่สถานะจะทำให้สับสน
- อย่าเพิ่มสีใหม่นอก 5 สถานะนี้ ถ้ามีสถานะใหม่ให้จัดเข้ากลุ่มที่ใกล้ที่สุด
Card
Card หนังสือ 1 ใบ = 1 เล่ม ปกเล่มใช้สีจาก palette หมุนเวียนเมื่อไม่มีรูปปก
✓ ใช้เมื่อไหร่
- แสดงรายการหนังสือแบบ grid ที่ผู้ใช้เลือกดูด้วยภาพปก
- เนื้อหาแต่ละใบเป็นหน่วยเดียวกัน มีการกระทำหลักของตัวเอง 1 อย่าง
- หน้าค้นหา หน้าแนะนำหนังสือ หน้าหนังสือใหม่
✕ ไม่ควรใช้เมื่อไหร่
- อย่าใช้เมื่อต้องเปรียบเทียบหลายคอลัมน์ เช่น ประวัติการจอง ให้ใช้ Table
- อย่าซ้อน Card ใน Card
- อย่าใส่ปุ่ม Primary มากกว่า 1 ปุ่มในใบเดียว
Modal
ใช้ <dialog> ของเบราว์เซอร์ focus จะอยู่ใน Modal ปิดได้ด้วย Esc ปุ่ม ✕ หรือคลิกพื้นหลัง และคืน focus ให้ปุ่มที่เปิด
✓ ใช้เมื่อไหร่
- ยืนยันก่อนทำสิ่งที่สำคัญหรือย้อนกลับไม่ได้ เช่น ยืนยันการจอง ยกเลิกการจอง
- งานสั้น ๆ ที่ต้องทำให้เสร็จก่อนกลับไปหน้าเดิม
- หัวข้อ Modal ต้องเป็นคำถามหรือสิ่งที่จะเกิดขึ้น ปุ่มบอกผลลัพธ์ชัดเจน
✕ ไม่ควรใช้เมื่อไหร่
- อย่าใช้แจ้งผลสำเร็จทั่วไป ให้ใช้ Toast ที่หายเองแทน
- อย่าใส่ฟอร์มยาวหรือหลายขั้นตอน ให้ทำเป็นหน้าแยก
- อย่าเปิด Modal ซ้อน Modal
- อย่าเปิดเองโดยที่ผู้ใช้ไม่ได้กดอะไร
Table
ตัวเลขและรหัสใช้ตัวเลขความกว้างเท่ากันเพื่อให้เรียงตรงคอลัมน์ บนมือถือตารางเลื่อนแนวนอนในกรอบของตัวเอง
| รหัสการจอง | หนังสือ | ผู้จอง | วันรับ | สถานะ | |
|---|---|---|---|---|---|
| HN-2569-0142 | สถาปัตยกรรมพื้นถิ่นล้านนา720.9593 ส134 | ปิยะนุช ส. | 08 พ.ย. 2569 | พร้อมรับที่สาขา | |
| HN-2569-0139 | ทะเลในฤดูฝน895.913 ว252 | ธนากร ม. | 10 พ.ย. 2569 | จองแล้ว | |
| HN-2569-0131 | เศรษฐศาสตร์ข้าวไทย338.17 ป213 | ณัฐชา ร. | 02 พ.ย. 2569 | เกินกำหนดรับ | |
| HN-2569-0127 | ครัวไทยสี่ภาค641.5959 ก412 | อรุณี ท. | 30 ต.ค. 2569 | รับแล้ว | |
| HN-2569-0120 | ประวัติศาสตร์สยามฉบับย่อ959.3 ช521 | กิตติพัฒน์ จ. | — | ยกเลิกแล้ว |
✓ ใช้เมื่อไหร่
- ข้อมูลหลายแถวที่ต้องเทียบกันตามคอลัมน์ เช่น ประวัติการจอง รายการรอรับ
- หน้าสำหรับเจ้าหน้าที่ที่ต้องเรียง ค้นหา และจัดการทีละหลายรายการ
- ใส่ caption บอกว่าตารางนี้คืออะไร
✕ ไม่ควรใช้เมื่อไหร่
- อย่าใช้จัด layout หน้า ให้ใช้ grid/flex
- อย่าใช้เมื่อมีแค่ 1–2 คอลัมน์ ให้ใช้รายการธรรมดา
- บนมือถือ ถ้าผู้ใช้ทั่วไปต้องดู ให้พิจารณาเปลี่ยนเป็น Card แทนการเลื่อนแนวนอน
tokens.css
คัดลอกไฟล์นี้ไปวางในโปรเจกต์ แล้ว import ก่อน stylesheet อื่น ทุกค่าบนหน้านี้มาจากไฟล์เดียวกันนี้