Now.js Framework Documentation

Now.js Framework Documentation

ThemeManager

TH 28 Dec 2025 09:45

ThemeManager

ภาพรวม

ThemeManager คือระบบจัดการ theme ใน Now.js Framework รองรับ:

  • Light/Dark mode switching
  • Auto-enhanced toggle buttons (data-component="theme")
  • Backend API integration (โหลด CSS Variables จาก server)
  • Smooth transitions (Anti-FOUC)
  • System preference detection

การใช้งานพื้นฐาน

Initialization

await Now.init({
  theme: {
    enabled: true,
    defaultTheme: 'light',
    storageKey: 'app_theme',
    systemPreference: true
  }
});

Toggle Theme

ThemeManager.toggle();               // สลับ light ↔ dark
await ThemeManager.setTheme('dark'); // ตั้งค่าเฉพาะเจาะจง
const theme = ThemeManager.getCurrentTheme();

Toggle Button

HTML

<!-- Auto-enhanced - ไม่ต้องเขียน JS -->
<button data-component="theme">🌓</button>

ThemeManager จะ enhance ปุ่มอัตโนมัติ:

  • ✅ เพิ่ม click handler
  • ✅ Sync data-theme-state attribute
  • ✅ ทุกปุ่มจะ sync เมื่อ theme เปลี่ยน

CSS สำหรับ Toggle Button

/* Icon font setup */
[data-component="theme"]:before {
  font-family: 'icomoon' !important;
}

/* แสดง icon ตาม theme */
[data-component="theme"][data-theme-state="light"]:before {
  content: "\e929";  /* icon-night */
}

[data-component="theme"][data-theme-state="dark"]:before {
  content: "\e9d4";  /* icon-day */
}

หรือใช้ CSS classes:

[data-theme-state="light"] .icon-light { display: none; }
[data-theme-state="dark"] .icon-dark { display: none; }

การตั้งค่าเต็มรูปแบบ

await Now.init({
  theme: {
    enabled: true,
    defaultTheme: 'light',
    storageKey: 'app_theme',
    systemPreference: true,

    // Smooth Transitions
    transition: {
      enabled: true,
      duration: 300,
      hideOnSwitch: true,
      readyClass: 'theme-ready',
      transitionClass: 'theme-transitioning'
    },

    // Backend API
    api: {
      enabled: false,
      configUrl: '/api/theme/config',
      timeout: 5000,
      cacheResponse: true
    }
  }
});

Backend API Integration

โหลด Config จาก API

await ThemeManager.loadFromAPI('/api/theme/config');

API Response Format

{
  "variables": {
    "--color-primary": "#6366f1",
    "--color-background": "#0f172a",
    "--hero-bg": "images/hero.jpg"
  }
}

หมายเหตุ: API ไม่ควบคุม light/dark mode - ผู้ใช้ควบคุมเอง

CSS Variables

Apply Variables

ThemeManager.applyVariables({
  '--color-primary': '#6366f1',
  '--color-background': '#0f172a',
  '--hero-bg': '/images/hero.jpg'  // Auto-wrap เป็น url()
});

Security

  • อนุญาตเฉพาะ CSS Custom Properties (--*)
  • ลบ patterns อันตราย (javascript:, expression(), <script>)
  • URLs: รองรับ local paths หรือ absolute URLs จากโดเมนเดียวกัน
  • โดเมนภายนอกถูกบล็อกโดย default
  • Extensions ต้องเป็นรูปภาพ (ไม่มี SVG)

Smooth Transitions

CSS ที่ต้องใช้

body {
  opacity: 0;
  transition: opacity 0.3s ease;
}

body.theme-ready {
  opacity: 1;
}

body.theme-transitioning {
  opacity: 0;
}

วิธีทำงาน

  1. body เริ่มต้นที่ opacity: 0
  2. ThemeManager โหลด theme
  3. เพิ่ม class theme-ready → fade in
  4. เมื่อ switch → fade out → apply → fade in

API Reference

Method คำอธิบาย
toggle() สลับ theme
setTheme(theme) ตั้งค่า theme
getCurrentTheme() รับ theme ปัจจุบัน
applyVariables(vars) Apply CSS Variables
clearVariables() ล้าง CSS Variables
getAppliedVariables() ดึง variables ที่ใช้
loadFromAPI(url?) โหลดจาก API
refreshFromAPI() โหลดใหม่ (ล้าง cache)
destroy() Cleanup ทั้งหมด
reset() Reset state

Events

Event เมื่อเกิด
theme:initialized Init เสร็จ
theme:changed Theme เปลี่ยน
theme:ready พร้อมแสดงผล
theme:variables-applied Apply variables เสร็จ
theme:variables-cleared ล้าง variables เสร็จ
theme:api-loaded โหลดจาก API สำเร็จ
theme:api-error API error
theme:destroyed Cleanup เสร็จ
theme:reset Reset เสร็จ
EventManager.on('theme:changed', ({ theme }) => {
  console.log('เปลี่ยนเป็น:', theme);
});

Cleanup

// Cleanup สมบูรณ์ (unmount app)
ThemeManager.destroy();

// Reset เบาๆ (re-init)
ThemeManager.reset();
await ThemeManager.init({ ... });

ข้อควรระวัง

⚠️ 1. Enable ก่อนใช้

// ❌ ยังไม่ enable
ThemeManager.toggle();

// ✅ Enable ก่อน
await Now.init({ theme: { enabled: true } });
ThemeManager.toggle();

⚠️ 2. ใช้ CSS Variables

/* ❌ ใช้ค่าคงที่ */
body { background: white; }

/* ✅ ใช้ variables */
body { background: var(--color-background); }

⚠️ 3. เปิดผ่าน HTTP

// ❌ file:// protocol ใช้ API ไม่ได้
// ✅ http://localhost/...

เอกสารที่เกี่ยวข้อง