บทความ
เอา Design Token มาใช้กับ Native iOS กันเถอะ: ตอนที่ 1
ช่วงนี้คนที่อยู่ในวงการ Web Application อาจจะเริ่มได้ยินคำว่า Design System, Design Token กันบ่อยขึ้น หรือบางทีมอาจจะเริ่มนำมาใช้งานกันบ้างแล้ว
อะไรคือ Design System
ปกติแล้วทีม Designer จะใช้โปรแกรมในการออกแบบ UI เช่น Figma, Sketch, Zeplin หรือ Adobe XD มาทำ UI ให้เรา แล้ว Developer ก็เอาเมาส์ไปจิ้มดูว่ากล่องนี้มันขนาดเท่าไหร่ ใช้โค้ดสีอะไร ขอบมี radius เท่าไหร่ ฯลฯ เพื่อให้ได้ UI บนแอปพลิเคชันของเราออกมาตรงกับดีไซน์ที่สุด
แต่ทีนี้ถ้าหากว่าระบบของเราใหญ่มากและมีทีมที่ใหญ่ แถมในแต่ละแพลตฟอร์มดันใช้ทีมออกแบบคนละทีมกันอีก เมื่อเป็นแบบนี้มันจะมีปัญหาด้านการออกแบบขึ้นมาเช่น
บน Mobile App กับบนเว็บใช้โค้ดสีไม่ตรงกัน
ระยะห่างของ padding ไม่เหมือนกัน
บนเว็บใช้ Font หนึ่งแต่บน Mobile App ดันใช้อีก Font หนึ่ง แถม iOS กับ Android ยังใช้ Font ต่างกันอีกต่างหาก
และอาจมีปัญหาทางด้านดีไซน์ต่าง ๆ ตามมาอีกมากมาย ลองนึกดูว่าเวลาเปิดเว็บกับเปิดแอปขึ้นมาแล้วได้ UI อย่างกับอยู่คนละบริษัท อีกทั้งหากถ้าเราปล่อยโปรดักต์ใหม่ๆ ออกมาแล้วหน้าตามันอย่างกับมาจากคนละบริษัทมันจะยุ่งเหยิงขนาดไหน
ดังนั้น การนำ Design System เข้ามาใช้มันจะช่วยแก้ปัญหาตรงจุดนี้ได้ เพราะมันจะเป็นแบบแผนในการออกแบบระบบทั้งหมดในทุก ๆ แพลตฟอร์มให้ได้ Look & Feel ที่เหมือนกัน มีภาพลักษณ์และทิศทางในการออกแบบที่สอดคล้องกันทั้งหมด (มี Consistency นั่นเอง) และเมื่อมันมีแบบแผนที่ดี เหล่า Developer ก็สามารถสร้าง Component ต่างๆ ไว้ล่วงหน้าเพื่อเอามา Reuse ได้อย่างสบาย ๆ อีกด้วย อีกทั้งโปรดักต์ใหม่ ๆ ที่ออกมาก็จะมีการออกแบบไปในทิศทางเดียวกันทั้งหมด
Design Token
ตัว Design Token นี่เรียกว่าเป็นมิตรรักของ Developer ได้เลยนะ ลองคิดดูว่าถ้าเราทำ UI ไปตามดีไซน์เสร็จไปหลายอัน แล้วอยู่ ๆ ทีม Designer บอกว่า ขอเปลี่ยนระยะห่าง space ทั้งหมด เปลี่ยนโทนสีต่าง ๆให้อ่อนลง เปลี่ยน Typography ด้วยนะ รับรองว่างานเข้าแน่ ๆ เพราะเราต้องมาไล่แก้โค้ดสีใหม่ทั้งหมด แก้ Typography ใหม่อีก เลือดสาดแน่นอน
พวก Designing Tool สมัยนี้มันเลยมี Plugin ที่สามารถสร้าง Token ขึ้นมาจากตัว Design System เพื่อให้ Developer สามารถเอาตัว Token นี้ไปใช้ได้ ซึ่ง Token นี้มันก็เป็นแค่ไฟล์ JSON หรือ XML ธรรมดา ๆ นี่แหละครับ แต่เราสามารถเอามันไป Generate เป็น CSS หรือ Native Code สำหรับ iOS และ android โดยที่หน้าตาของมันก็จะออกมาเป็นประมาณนี้
ซึ่งมันก็มี Library ที่ช่วยแปลงเจ้า Design Token นี้ให้เป็นไฟล์ที่เราเอามาใช้งานได้เรียบร้อยแล้วนั่นก็คือ StyleDictionary จาก Amazon นั่นเอง
ซึ่งตัว StyleDictionary เนี่ยมันทำงานกับ CSS ได้ดีมากเลย ซึ่งเอาจริง ๆ แล้วจุดเริ่มต้นของเรื่องนี้คือ ผมไปเห็นทีม Front end เค้าใช้ตัว Design Token กัน ผมก็เลยอยากเอามาใช้ในทีม Mobile บ้าง
เข้าเรื่องกันเลยดีกว่า
อย่างที่บอกข้างบน เห็นเค้าใช้แล้วดูดีมากเลยอยากดูดีแบบเค้าบ้าง ก็มา POC ดูว่ามันจะพอไปรอดมั้ย เลยสร้าง JS โปรเจกต์ขึ้นมาแล้วจัดการติดตั้งตัว style-dictionary ใน package.json
จัดการ Config ตาม Document แล้วเอา Design Token ที่เป็น Global Component ที่ทีม Designer ทำมาให้ เอามา Generate โดยใช้ Pre-defined formatter/transformer สิ่งที่ได้คือแบบนี้
ไม่เวิร์กอย่างแรง มี Static Variable จำนวนหลายร้อยบรรทัดแบบนี้ แถมยังมีค่า px ติดมาด้วย แบบนี้คงไม่มีใครอยากใช้เพราะมันทำร้ายสายตามาก
แต่เพิ่งนึกได้ว่า Token นี้มันถูกทีม Designer สร้างมาให้ทีม Front end เค้าใช้นี่นา เราไปแอบเอาของเค้ามาใช้ก็ต้องออกแรงกันหน่อย 😁
อย่างเช่น นี่คือ JSON บางส่วน…
และนี่คือสิ่งที่ได้รับ
ขยี้ตาสามที แบบนี้มันไม่เวิร์กแล้วครับ เพราะเราต้องการ Gradient แต่สิ่งที่ได้กลับเป็น Color แถมยังเป็นสีดำอีกต่างหาก
อีกอย่างต่อให้มันจะสร้าง Type ออกมาได้ถูกต้องไม่มี Error เลยแม้แต่นิดเดียว แต่เวลาเรียกใช้ต้องมาตาลายกับ Static Variable ที่ไหลเป็นพรืดตอนที่เราเรียก Auto Complete ขึ้นมานี่ดูแล้วท่าทางจะไม่สนุกละครับ
เขียน Formatter เองซะเลย
โชคดีที่ StyleDictionary เค้าเตรียมคำสั่งไว้ให้เราสามารถจัดการ Format ของไฟล์ที่เราต้องการจะสร้างได้เองด้วยคำสั่งราว ๆ นี้
ถ้าเราดูที่ตัวแปร dictionary.tokens.color มันก็จะได้ JavaScript Object ที่มีโครงสร้างเหมือน JSON ที่เราอ่านมาเป๊ะ ๆ เลย
เอาละสิ เราจะเห็นว่าความลึกของ Design Token มันไม่เท่ากัน วนลูปสร้างไม่ได้แน่ ๆ แล้วทีนี้ในฟังก์ชัน generateData เราจะทำยังไงล่ะ
คำตอบมันอยู่ในวิชาที่เราเกลียดกันตอนเรียนครับ ถ้าเรามองดี ๆ ไฟล์ JSON มันก็เป็นแค่ Tree เท่านั้นเอง ดังนั้นถ้าเราจะสร้างโค้ดใหม่ขึ้นมา เราก็ต้องขุดลงไปให้ลึกที่สุดก่อนแล้วค่อยๆ คืนค่าที่ได้ออกมาจนถึงชั้นบนสุด คุ้น ๆ มั้ยครับ มันคือ Depth First Search นั่นเอง
ว่าแล้วก็ลงมือทำครับ
ทีนี้ลอง Generate ไฟล์ดูอีกที
แบบนี้ค่อยน่าชมขึ้นหน่อย เพราะแทนที่เราจะต้องมาเรียกแบบที่มันออกมาเป็นคำสั่งที่ไม่มีโครงสร้าง BitkubDesignToken.colorBannerDarkgrayscale เราก็เปลี่ยนมาเรียกสวย ๆ ได้เป็น BitkubColor.shared.banner.darkgrayscale ซึ่งดูแล้วมี Readablity มากกว่ากันเยอะ
ขอพักเหนื่อยไว้เท่านี้ก่อน
เดี๋ยวตอนที่ 2 จะมาทำเรื่องที่มันยากกว่าเดิมขึ้นไปอีกสักนิด นั่นก็คือเรื่องของ Gradient และ Shadow ว่าเราจะเอา Design Token มาทำได้ยังไง เพราะค่าที่ส่งมามันเป็นค่าของ CSS
ยกตัวอย่างเช่น iOS เวลาเราทำ Gradient เราจะรับค่าพารามิเตอร์เป็น CGPoint ที่เป็น จุด start และ end เป็น Gradient Space ในระนาบ 2 มิติ แต่ Desige Token ที่ส่งมาให้เรากลับส่งมาเป็นมุมองศา หรือเงาที่ใน iOS เราไม่มี spread ให้ แต่มันกลับถูกกำหนดมาให้ใน Design Token ซึ่งต้องเอามาใช้ในการปรับความกว้างของเงา อีกทั้งการทำ Gradient หรือ Shadow มันต้องไปทำบน CALayer ที่เรานั้นไม่สามารถกำหนดค่าเข้าไปในตัว Component ได้แบบตรงๆ อีกด้วย แล้วแบบนี้เราจะเอา Desige Token มาใช้ได้ยังไง?
ติดตามได้ใน เอา Design Token มาใช้กับ Native iOS กันเถอะ: ตอนที่ 2