คอมโพเนนต์ทุกตัวมีบุคลิกที่คุณเปลี่ยนได้ ทั้งสปริงที่ใช้เคลื่อนไหว ปฏิกิริยาของปุ่มเมื่อถูกนิ้วกด วิธีที่ไดอะล็อกและเมนูปรากฏขึ้น รูปทรงและขนาดของมุม และพื้นที่ที่ใช้ แต่ละอย่างกำหนดได้ด้วย attribute เดียวสำหรับทุกอย่างภายในเอลิเมนต์ หรือ input เดียวสำหรับคอมโพเนนต์ตัวเดียว
Attribute เดียว ครอบคลุมทั้ง subtree
ใส่ attribute data-nui-* ไว้ที่ <body> เพื่อใช้กับทั้งแอป หรือที่เอลิเมนต์ใดก็ได้เพื่อใช้เฉพาะส่วนนั้น ตัวที่อยู่ใกล้ที่สุดจะมีผล จึงซ้อนกันได้ Attribute เหล่านี้แค่กำหนดตัวแปร CSS จึงทำงานเหมือนกันไม่ว่าจะใช้เฟรมเวิร์กใด หรือไม่ใช้เฟรมเวิร์กเลยก็ตาม
<body data-nui-motion="bouncy" data-nui-corners="squircle">
<!-- Everything here bounces and has squircle corners… -->
<main data-nui-press="squish" data-nui-density="compact">
<!-- …buttons in here squish, and controls are compact… -->
</main>
<aside data-nui-motion="none" data-nui-radius="none">
<!-- …and nothing in here moves or has rounded corners. -->
</aside>
</body>คอมโพเนนต์เดียว
ใน Angular นั้น nuiButton nuiDialog และ nuiMenu รับค่าเดียวกันนี้ผ่าน input ส่วน input ที่ไม่ได้กำหนดจะใช้ค่าตาม attribute ที่ครอบอยู่
<button nuiButton press="rubber" motion="elastic">Boing</button>
<dialog nuiDialog [(open)]="editing" enter="flip" corners="squircle">…</dialog>
<button nuiButton [nuiMenuTrigger]="actions">Actions</button>
<div nuiMenu #actions="ngMenu" enter="unfold" motion="mechanical">…</div>สปริงที่คอมไพล์เป็น CSS
การเคลื่อนไหวใช้ฟิสิกส์ของสปริง คือความแข็งเกร็ง การหน่วง และมวล แทนระยะเวลาและเส้นโค้ง คอมไพเลอร์ token จะแก้สมการของสปริงแต่ละตัว แล้วเขียนลง CSS เป็นเวลาที่ใช้จนหยุดนิ่งกับ easing แบบ linear() จึงทำงานบน compositor ได้โดยไม่ต้องใช้ JavaScript มีสปริงหกแบบมาในรูป token ตั้งแต่ --nui-spring-snappy ถึง --nui-spring-mechanical และ --nui-motion เก็บสปริงที่ใช้อยู่
สปริงแบบอื่นใช้ได้ด้วย input เพียงตัวเดียว Angular จะคอมไพล์ขณะรันไทม์ด้วยตัวแก้สมการเดียวกัน และ springTransition() ให้ CSS สำหรับเอลิเมนต์ของคุณเอง
import { springTransition } from '@needless-ui/angular';
// In a template, any spring is an input:
// <button nuiButton [spring]="{ stiffness: 900, damping: 12 }">Save</button>
// Anywhere else, compile it yourself:
const wobbly = springTransition({ stiffness: 120, damping: 4, mass: 1.2 });
// '4152ms linear(0, 0.014 0.41%, …, 1)'
const card = document.querySelector<HTMLElement>('.card')!;
card.style.transition = `transform ${wobbly}`;ทุกค่าที่อยู่ระหว่างนั้น
พรีเซ็ตเป็นเพียงทางลัด สำหรับค่าอื่น ๆ ให้กำหนดตัวแปร CSS เอง: transform ใดก็ได้สำหรับ --nui-press และ --nui-enter และตัวเลขใดก็ได้สำหรับ --nui-radius-scale และ --nui-density
.checkout {
--nui-motion: var(--nui-spring-jelly);
--nui-press: scale(0.92) rotate(-2deg);
--nui-enter: translateY(100%);
--nui-radius-scale: 1.5;
--nui-density: 1.1;
}การเข้าถึง
เมื่อระบบขอให้ลดการเคลื่อนไหว สปริงจะจบลงทันที ส่วนการกดและการปรากฏจะไม่ขยับ ความหนาแน่นจะไม่ทำให้ตัวควบคุมเล็กกว่าขนาดพื้นที่กด 24px ตาม WCAG 2.2 และไม่มีพรีเซ็ตใดแตะต้องสี การตรวจคอนทราสต์ทุกรายการจึงยังใช้ได้ เบราว์เซอร์ที่ไม่รองรับ corner-shape จะวาดทุกมุมเป็นมุมโค้ง