2 คะแนน โดย GN⁺ 14 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Jelly UI v1.1 เป็นไลบรารีเว็บคอมโพเนนต์แบบไม่พึ่งพาไลบรารีอื่น ที่ผสานคอนโทรลฟอร์มจริงเข้ากับเอฟเฟ็กต์ฟิสิกส์ซอฟต์บอดีนุ่มเด้ง และมีคัสตอมเอลิเมนต์ให้ 40 รายการ
  • ติดตั้งด้วยโมดูลสคริปต์เพียงตัวเดียว และรองรับ โหมดมืด, การติดตามธีมของระบบปฏิบัติการอัตโนมัติ, การเปลี่ยนสีเน้น, และเลย์เอาต์ RTL แบบขวาไปซ้าย
  • ปุ่มใช้ <button> แบบเนทีฟ ส่วนสไลเดอร์ใช้ range input ที่ซ่อนไว้ เพื่อคง โครงสร้างความหมายแบบเนทีฟ สำหรับการควบคุมด้วยคีย์บอร์ด, โปรแกรมอ่านหน้าจอ, และการทำงานร่วมกับฟอร์ม
  • มีการใส่ แอนิเมชันเชิงสัมผัส เช่น การยุบตัว การยืดตัว ระลอกคลื่น และการเด้ง ให้กับองค์ประกอบหลากหลายตั้งแต่ช่องทำเครื่องหมายและช่องกรอกข้อมูล ไปจนถึง toast, tabs และ dialog
  • ฝังโทเค็นสีตาม WCAG AA และแพตเทิร์น ARIA มาในตัว จึงสามารถสร้าง อินเทอร์เฟซผลิตภัณฑ์ที่เข้าถึงได้ โดยยังคงเอฟเฟ็กต์ภาพที่นุ่มลื่นไว้ได้

การติดตั้งและธีม

  • Jelly UI ใช้งานได้ โดยไม่ต้องพึ่งพาไลบรารีอื่น, ด้วยคัสตอมเอลิเมนต์ 40 รายการและแท็ก <script type="module"> เพียงตัวเดียว
    <script type="module" src="https://jelly-ui.com/package.js"></script>;
    
    <jelly-theme mode="auto">
      <jelly-button variant="mint">Publish</jelly-button>
    </jelly-theme>
    
  • <jelly-theme> เป็นตัวให้ธีมที่จำกัดการใช้ดีไซน์โทเค็นไว้กับ subtree ด้านล่าง
    • mode รองรับ auto, light, dark เพื่อให้ตามค่าระบบปฏิบัติการหรือบังคับธีมที่ต้องการได้
    • สามารถกำหนด สีเน้น ใหม่ได้ด้วย accent
  • ชุดสีที่ใช้ร่วมกันได้แก่ azure, rose, amber, mint, graphite, platinum, white และขนาดหลัก ๆ คือ small, medium, large

ปุ่มและองค์ประกอบการกระทำ

  • <jelly-button> เป็น ปุ่มทรงแคปซูล ที่มี <button> แบบเนทีฟจริงอยู่ภายใน จึงรองรับคีย์บอร์ดและโปรแกรมอ่านหน้าจอ
    • ตั้งค่าสี ขนาด รูปแบบ pill และ square รวมถึงสถานะปิดใช้งานและการจัดวางแบบบล็อกได้
  • <jelly-icon-button> เป็นปุ่มทรงสี่เหลี่ยมหรือวงกลมที่ออกแบบมาสำหรับไอคอนเดี่ยว
    • ใช้แอตทริบิวต์ label เพื่อกำหนดชื่อที่โปรแกรมอ่านหน้าจอจะรับรู้

คอนโทรลสำหรับป้อนข้อมูลในฟอร์ม

  • <jelly-checkbox> ทำงานร่วมกับฟอร์มได้ รองรับ checked และ สถานะไม่กำหนดแน่ชัด (indeterminate) และเมื่อสถานะเปลี่ยน สี่เหลี่ยมเจลลีจะเด้งขึ้น
  • <jelly-input> เป็นช่องกรอกข้อมูลบรรทัดเดียวสำหรับ text, email, password
    • เมื่อได้รับโฟกัส พื้นผิวจะยกตัวขึ้นและมีเส้นขอบปรากฏ และทุกครั้งที่พิมพ์จะเกิดระลอกคลื่นจากตำแหน่งเคอร์เซอร์
    • รองรับ disabled และ readonly
  • <jelly-label> เชื่อมกับคอนโทรลผ่าน for
    • เมื่อคลิกจะโฟกัสไปยังเป้าหมาย และข้อความของ label จะกลายเป็น ชื่อที่เข้าถึงได้ พร้อมกำหนดความเป็นฟิลด์บังคับและขนาดได้
  • <jelly-otp> เป็น ช่องกรอกรหัสใช้ครั้งเดียว ที่มีหนึ่งช่องต่อหนึ่งตัวเลข
    • รองรับการพิมพ์, backspace, ปุ่มลูกศร, การวาง และตั้งค่าความยาว สี ขนาด และการปิดใช้งานได้
  • <jelly-radio> จะสร้างกลุ่มกับรายการที่ใช้ name เดียวกันภายใต้ root เดียวกัน
    • รองรับ การนำทางด้วยปุ่มลูกศร โดยคำนึงถึง tabindex แบบเคลื่อนย้ายและทิศทางเอกสาร
  • <jelly-radio-group> เป็นคอนเทนเนอร์ radiogroup แบบมี label สำหรับ jelly-radio
    • มี legend, การจัดเรียงแนวนอน·แนวตั้ง และการส่งต่อขนาดไปยังองค์ประกอบลูก
  • <jelly-range> เป็น สไลเดอร์แบบสอง handle สำหรับเลือกช่วงค่าต่ำสุดถึงสูงสุด
    • ใส่ role="slider", โฟกัส และ ARIA ให้กับ handle ทั้งสอง และเมื่อ drag ตัว handle แบบเจลลีจะยุบตัว
  • <jelly-segmented> เป็นแทร็กทรงแคปซูลที่เก็บตัวเลือกแบบเลือกได้เพียงหนึ่งเดียว
    • ตัวแสดงการเลือกจะทำงานเป็นเม็ดยาเจลลีที่เอียงและยืดขณะเลื่อนไประหว่างช่วงต่าง ๆ
  • <jelly-select> เป็นดรอปดาวน์ที่เชื่อมกับฟอร์มโดยใช้แพตเทิร์น ARIA combobox·listbox
    • ทั้ง trigger และแผงตัวเลือกสร้างด้วยพื้นผิวซอฟต์บอดี
    • แผงจะกางออกจากฟิลด์ และหากพื้นที่ด้านล่างไม่พอจะ สลับขึ้นด้านบน
  • <jelly-slider> เป็นสไลเดอร์สำหรับเลือกค่าเดียว
    • range input แบบเนทีฟที่ซ่อนไว้จะดูแลโครงสร้างความหมายและการทำงานร่วมกับฟอร์ม ส่วนบนหน้าจอจะแสดง handle เจลลีที่กดยุบได้
  • <jelly-switch> เป็นสวิตช์ที่ลากได้ โดยตัว handle จะยืดเหมือนหยดของเหลว และสีสถานะปิด·เปิดจะสลับเปลี่ยนกัน
  • <jelly-textarea> จะขยายความสูงอัตโนมัติระหว่างค่าต่ำสุด·สูงสุดตามจำนวนบรรทัดของข้อความ
    • พื้นผิวก็ยืดตามความสูงด้วย และเมื่อพิมพ์จะเกิดระลอกคลื่นจากตำแหน่งเคอร์เซอร์ พร้อมรองรับ disabled และ readonly

สถานะและฟีดแบ็ก

  • <jelly-alert> เป็นแบนเนอร์ที่มี 4 โทนคือ info, success, warning, danger พร้อม ปุ่มปิด แบบเลือกใช้ได้
  • <jelly-badge> เป็นองค์ประกอบขนาดเล็กสำหรับ badge, tag และการแสดงสถานะ โดยจะเด้งขึ้นเมื่อข้อความเปลี่ยน
    • ตั้งค่ารูปแบบแบบเติมสี·เส้นขอบ รูปทรงเม็ดยา·สี่เหลี่ยม และพฤติกรรม live, instant ได้
  • <jelly-progress> เป็นแถบความคืบหน้าที่ส่วนหน้าของแถบเติมจะสั่นไหวตามความคืบหน้า
    • ใน โหมดไม่กำหนดแน่ชัด ก้อนเจลลีจะเด้งไปมาระหว่างผนังทั้งสองด้าน
  • <jelly-skeleton> เป็น placeholder ระหว่างโหลดที่ไหวเบา ๆ เหมือนกำลังหายใจ แทนเอฟเฟ็กต์แวววาว
    • รองรับรูปแบบ line, rect, circle
  • <jelly-spinner> มีทั้งตัวบ่งชี้แบบ dots ที่เป็นก้อนเมือกเคลื่อนระหว่างจุดสามจุด และแบบ blob ที่หมุนพร้อมเปลี่ยนรูปทรง
  • <jelly-toaster> ใช้จัดการการแจ้งเตือนแบบ toast ที่ปรากฏแล้วหายไปจากทิศทางปลายบรรทัด
    • โดยทั่วไปเรียกผ่านเฮลเปอร์ jellyToast('Saved!', { tone: 'success' })
    • หากกำหนด position="bottom" ให้กับองค์ประกอบที่วางไว้ สแต็กการแจ้งเตือนจะขยายขึ้นด้านบน

พื้นผิวคอนเทนต์

  • <jelly-accordion> ใช้รวมหลายรายการของ <jelly-collapsible>
    • ในโหมด single เมื่อรายการหนึ่งเปิด รายการอื่นจะปิดแบบเด้งกลับ
  • <jelly-card> เป็นคอนเทนเนอร์พื้นผิวเจลลีที่วางอยู่ใต้คอนเทนต์
    • หากเพิ่ม squish จะทำหน้าที่เป็น ปุ่ม พร้อมความรู้สึกยุบตัวเหมือนเบาะนุ่ม
  • <jelly-chip> ใช้เป็น label แบบคงที่, filter ที่สลับสถานะได้ หรือ tag ที่ลบได้
    • ตั้งค่าได้ว่าเลือกได้ อยู่ในสถานะเลือกแล้ว ลบได้ หรือปิดใช้งาน
  • <jelly-collapsible> เป็นพื้นที่พับ·ขยายที่เปิดปิดแผงด้วยปุ่มส่วนหัวแบบเด้งนุ่ม
    • ออกแบบให้ พื้นผิวเคลื่อนไหว ไม่ใช่ตัวข้อความ
  • <jelly-divider> เป็นเส้นคั่นบาง ๆ แบบแนวนอน·แนวตั้ง หรือมี label
  • <jelly-kbd> เป็นคีย์แคปเจลลีที่กดโต้ตอบได้
    • หากเชื่อมกับปุ่มจริงผ่าน key เมื่อกดปุ่มนั้นที่ใดก็ได้บนหน้า คีย์แคปก็จะยุบลงตามระหว่างที่กด

การนำทางและเลย์เอาต์

  • <jelly-resizable> เป็น กริดแผง ที่ปรับขนาดได้ด้วยการลากเส้นคั่นแบบเจลลีหรือใช้คีย์บอร์ด
    • รองรับทิศทาง row, vertical, both
  • <jelly-tabs> เป็นมุมมองแท็บที่ใช้โครงสร้างความหมาย tablist จริง
    • ตัวแสดงการเลือกแบบเม็ดยาเจลลีจะเลื่อนไปมา และแผงแท็บจะปรากฏแบบเด้งนุ่ม

โอเวอร์เลย์

  • <jelly-dialog> เป็นกล่องโต้ตอบแบบโมดัลที่เด้งขึ้นมาเหมือนเจลลี
    • จะล็อกหน้าไว้ และหลังปิดจะ คืนโฟกัส กลับไปยังตำแหน่งก่อนหน้า
    • ปิดได้ด้วยปุ่ม Escape, ปุ่มปิด หรือการคลิกพื้นหลัง
  • <jelly-drawer> เป็นแผงลอยที่แสดงด้วยเอฟเฟ็กต์สปริงเลยออกไปเล็กน้อยแล้วเด้งกลับ
    • เปิดได้จากด้านต้นบรรทัด·ปลายบรรทัด หรือด้านล่าง
  • <jelly-popover> เป็นแผงแบบไม่ใช่โมดัลที่เปิดด้วยการคลิก
    • ยึดกับ trigger และปิดได้ด้วยปุ่ม Escape หรือการคลิกภายนอก
    • รองรับการจัดวาง top, bottom, start, end
  • <jelly-tooltip> จะแสดงบอลลูนคำอธิบายแบบใช้ธีมไว้เหนือ trigger เมื่อเอาเมาส์ไปวางหรือได้รับโฟกัสจากคีย์บอร์ด
    • รองรับการจัดวาง 4 ทิศทางและ 3 ขนาด

1 ความคิดเห็น

 
ความคิดเห็นจาก Hacker News
  • หน้าต่างกระตุกพอสมควรเลยลองขุดหาสาเหตุ แล้วพบว่าไลบรารีนี้รัน ลูปแอนิเมชัน requestAnimationFrame (RAF) ทุก 8ms ครอบคลุมทุกคอมโพเนนต์ในหน้า และสั่งวาดเอกสารทั้งหน้าใหม่
    คอมเมนต์ข้างบนที่ว่า “ประมวลผลคอมโพเนนต์ที่แอ็กทีฟร่วมกันในหนึ่งเฟรม และหยุดเมื่อว่าง” ก็ดูเหมือน AI สร้างขึ้นมาเหมือนกัน JellyEngine ไม่ได้คำนวณแอนิเมชันเจลลีเฉพาะตอนเกิด pointer event แต่คำนวณคอมโพเนนต์ที่แอ็กทีฟทั้งหมดในหน้าซ้ำทุกเฟรม เป็นการอิมพลีเมนต์ที่คนทั่วไปเห็นแล้วน่าจะคิดว่า “ทำแบบนี้ไม่ได้ มันหนักเกินไป”

    • พอลองทำ performance profiling ใน Chrome ก็ไม่พบสิ่งที่ยืนยันคำอธิบายนี้ ลูปดูเหมือนจะจัดการคอมโพเนนต์ที่ต้องอัปเดตด้วย Set() ของตัวที่แอ็กทีฟ และเอาออกเมื่อการเคลื่อนไหวหยุด
      เห็นด้วยว่าคอมเมนต์ดูเหมือน AI เขียนแบบขอไปทีอยู่บ้าง แต่ก็ไม่เจอปัญหาชัดเจนในแนวทางนี้ และตอนที่ไม่มีอะไรเกิดขึ้น ลูปหลักก็จบภายในไม่กี่ไมโครวินาที
    • มันไม่ใช่วิธีที่หนักเกินไป 99.99% ของวิดีโอเกม ก็ทำงานแบบนี้ตรง ๆ คือวาดทั้งหน้าจอใหม่ต่อเนื่องเท่าที่อัตรารีเฟรชแบบ vertical sync หรือประสิทธิภาพฮาร์ดแวร์จะเอื้อ
  • ชอบนะ แต่ดูเหมือนจะไม่ตรงกับ แนวปฏิบัติ UX มาตรฐาน
    ถ้ากดเมาส์ค้างไว้แล้วลากออกนอกองค์ประกอบ ก็ควรจะไม่ถูกนับเป็นการคลิก ตอนนี้ปุ่มยังนับว่าเป็นการคลิก แต่ checkbox ไม่เป็น แบบนี้ไม่สอดคล้องกัน

    • เป็นปัญหาที่เจอตลอดเวลาทำงานกับนักพัฒนา Flash สมัยก่อน หลักการที่ได้ยินบ่อยคือ “ถ้ายังทำฟังก์ชันของ แถบเลื่อน ได้ไม่ครบ ก็อย่าเขียนแถบเลื่อนขึ้นมาใหม่” แต่สุดท้ายก็มักต้องเสียเวลาหลายวันแก้กันเกินห้ารอบ
    • เจอประเด็นดีมาก เลยแก้ ลอจิกของปุ่ม แล้ว ตอนนี้ถ้าเคอร์เซอร์อยู่นอกขอบเขตปุ่มก็จะไม่เกิดการคลิก
  • น่ารักจริง ๆ และชอบที่ลดฟังก์ชันลงอย่างเป็นธรรมชาติเมื่อเจอ @media (prefers-reduced-motion: reduce)
    แต่อยากให้ในเดโมไซต์ ผู้ใช้สามารถ override ได้โดยไม่ต้องไปเปลี่ยนค่าระบบ หรืออย่างน้อยก็มี ข้อความแจ้งว่าแอนิเมชันจะไม่แสดง

    • ผมพลาดไปว่าเป็นเพราะตั้งใจลด motion เลยคิดว่ามันเสีย แถมยังลืมไปแล้วด้วยว่าเคยเปิดการตั้งค่านี้ไว้
    • ที่เมนู Apple > การตั้งค่าระบบ > การช่วยการเข้าถึง > การเคลื่อนไหว สามารถตั้งค่า ลดการเคลื่อนไหว ได้
      ทุกครั้งที่มีเดโมเจ๋ง ๆ แบบนี้โผล่มา ผมต้องใช้เวลานิดหน่อยกว่าจะนึกถึงการตั้งค่านี้ ระหว่างนั้นก็ได้แต่คลิกแบบผิดหวังว่า “มันพิเศษตรงไหนนะ?”
    • ตอนนี้มีการแสดงการแจ้งเตือนแล้ว และยังสามารถกด ไอคอนกระต่ายน่ารัก เพื่อ override การตั้งค่าระบบได้ด้วย
  • ถ้าเป็นตอนวัยหนุ่มคงชอบมาก แต่เดี๋ยวนี้กลับใช้เวลากับการเอาเอฟเฟกต์แบบนี้ออกด้วย local stylesheet หรือเปิดใช้ โหมดมืดกับโหมดอ่าน มากกว่า เวลาผ่านไปเยอะจริง ๆ

    • ชอบตรงที่แอนิเมชันเป็นฟีดแบ็กที่ช่วยเน้นว่าสิ่งใดกำลังเกิดขึ้นหรือเปลี่ยนแปลงอยู่ คอมโพเนนต์เนทีฟไม่ได้สื่อสิ่งนี้ได้ดีเสมอไป และถ้าใช้แอนิเมชันอย่างถูกต้อง มันไม่ใช่แค่ของตกแต่ง แต่มี คุณค่าด้าน UX จริง ๆ
    • ปีละครั้งผมจะรู้สึกว่าอยากให้ซอฟต์แวร์มีความสนุกมากขึ้น แต่สุดท้ายก็กลับไปหวังแค่ว่า อย่ามารบกวนกันก็พอ
  • อยากให้มีเอฟเฟกต์เบา ๆ ตอนเอาเมาส์ไปชี้ด้วย ดูเหมือนคอนโทรลบางตัวอย่างแถบความคืบหน้าและ toast จะไม่มีเอฟเฟกต์เจลลี
    อีกอย่างคือ ประสิทธิภาพของหน้าเดโมก็ไม่ค่อยดีและให้ความรู้สึกเหมือนแย่งการเลื่อน แต่โดยรวมก็น่ารักและน่าจะเข้ากับ UI ของเกมได้ดี

  • องค์ประกอบ Chip ควรเปลี่ยนสถานะโดยอยู่กับที่ แต่พอคลิกแล้วมัน หลุดออกนอกขอบเขต ซึ่งไม่ค่อยถูกใจ

  • น่ารัก แต่ ความไวในการตอบสนอง ของคอนโทรลบางตัวแย่มาก ลากสไลเดอร์ไปมาจะตามเคอร์เซอร์ช้ามาก ทั้งที่มันควรจะติดตามเคอร์เซอร์เหมือนถูกกาวแปะไว้
    ในทางกลับกัน คอนโทรลอื่นอย่าง jelly-resizable กลับเกาะเคอร์เซอร์ได้ดี ส่วนคอนโทรล "Placeholder" ดูเหมือนคลิกแล้ว placeholder ก็ไม่หายไป

  • สงสัยว่ามีใครจำ เอฟเฟกต์เจลลี คล้าย ๆ กันที่เคยอยู่ตามขอบหน้าของเว็บไซต์ บล็อก และหน้าโชว์เคสของ Paul Neave ราวปี 2007~2010 ได้ไหม ตอนนั้นทำด้วย Flash
    ช่วงนั้น Paul Neave เป็นฮีโร่ส่วนตัวของผมเลย ถ้าเจ้าตัวมาอ่านอยู่ก็ขอให้สบายดี

  • ในระบบออกแบบ UI นี้ แทบหาอะไรที่เรียกว่า เอฟเฟกต์ทางฟิสิกส์ ไม่เจอเลย

    • ไลบรารีนี้เคารพการตั้งค่า ลดการเคลื่อนไหว ของไคลเอนต์ โดยปิดเอฟเฟกต์แอนิเมชันทั้งหมด
  • อาจเป็นเพราะ ภาวะการมองเห็นสีผิดปกติ ของผมหรือการตั้งค่าจอ แต่สีแดงกับสีอำพันคล้ายกันเกินไป จนแยกไม่ออกด้วยซ้ำว่ากดปุ่มไปแล้วหรือยัง