npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jungtz/calendar-scheduler

v0.4.2

Published

Hotel room reservation calendar scheduler - vanilla JS library

Readme

Calendar Scheduler v2 📅

License: MIT Vite Language Style Morphing

這是一款專為**飯店客房預訂(Hotel Reservation)物業管理系統(PMS)**量身打造的輕量化、高效能日曆排程表(Calendar Scheduler)套件。

本套件完全基於 純 JavaScript (Vanilla JS)Sass/SCSS 自研構建,零外部 UI 框架依賴,並採用現代的 Class-based 邏輯與 ESM 格式輸出,具備極高的相容性與極輕的代碼體積。


🌟 核心特色 (Core Features)

  • 零框架依賴:擺脫 Vue、React 或 Bootstrap-Vue 等沉重框架束縛,大小極度輕量,能無縫整合至任何前端專案中。
  • 漸進式無痕更新 (Idiomorph DOM Morphing)
    • 引進先進的 Idiomorph 進行虛擬 DOM 比對與局部節點更新。
    • 徹底告別傳統 innerHTML 暴力重繪所造成的 UI 閃爍、捲軸移位與輸入焦點遺失,帶來絲滑順暢的更新體驗。
  • 純資料驅動的跨行 (Rowspan) 計算
    • 重構了 rowspan 的佈局引擎。不再低效地在渲染後去查詢 DOM 節點數量。
    • 在渲染前,直接由 dataResult 資料結構預先計算每個資源在特定時間區間內的最大排程長度,提供極致穩定的佈局與渲染效能。
  • HTML5 原生拖曳 (Drag & Drop) 引擎
    • 精確限定拖曳目標容器([data-type="content"], [data-type="wait"]),大幅提升互動精準度。
    • 智慧衝突過濾:自動識別並保留原先已存在的衝突(Orig Conflicts),只對「拖放所產生的新衝突」進行干預與警報。
    • 零變更優化:當原地拖放(無實質資料變更)時,自動跳過重新渲染與事件觸發,大幅降低 CPU 負載。
  • 流暢的雙向滾動同步 (Scroll Sync)
    • 完美同步左側資源菜單與右側排程表,不發生位置偏差。
    • 水平滾動時會自動快取滾動位置(儲存至 sessionStorage),確保頁面重整後視圖不跳動。
    • 垂直滾動時提供流暢、動態計算定位基準的 Sticky 標題浮動效果。
  • 自適應折疊動畫:改用平滑的 max-height CSS 動畫優化資源菜單的展開與折疊。
  • 健全的 Month (月) 視圖支援:除了動態天數外,亦完整支援 month 視圖,能自動計算當月的首尾日期。
  • UID 穩定機制:自動為所有預訂卡片(Items)分配並維護穩定的 _uid,以保證 DOM Morphing 時的節點穩定對齊。

📦 安裝指南 (Installation)

Peer Dependencies

本套件需要以下 peer dependencies,請確保您的專案中已安裝:

  • dayjs (>= 1.11.13) - 用於日期與時間計算
  • split.js (>= 1.6.5) - 用於左右區塊拖曳分割
npm install dayjs split.js

引入套件

您可以使用 NPM 安裝此套件(或直接引入建置後的 ESM 模組與樣式檔):

import { CalendarScheduler } from '@jungtz/calendar-scheduler';
import '@jungtz/calendar-scheduler/dist/style.css';

🚀 快速開始 (Quick Start)

在您的 HTML 中建立一個容器:

<!-- 引入 Font Awesome 6 (可選,用於圖示顯示) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" />

<div id="calendar-container"></div>

在 JavaScript 中初始化:

import { CalendarScheduler } from '@jungtz/calendar-scheduler';
import '@jungtz/calendar-scheduler/dist/style.css';

// 1. 定義資源資料 (房型與房號)
const resources = [
  {
    id: 1,
    name: '標準雙人房',
    active: true,
    children: [
      { id: 101, name: '101 室' },
      { id: 102, name: '102 室' }
    ]
  }
];

// 2. 定義預訂卡片資料 (Items)
const items = [
  {
    id: 'res-9981',
    title: '王小明 (3晚)',
    start: '2026-05-20',
    end: '2026-05-23',
    room_type: 1,
    room_number_id: 101,
    assign: true,      // 已指派房號
    checked_status: 'checked-in' // 自訂樣式狀態
  }
];

// 3. 初始化排程表
const calendar = new CalendarScheduler('#calendar-container', {
  resource: resources,
  items: items,
  locale: 'tw',         // 支援 'tw', 'en', 'ja'
  allowEdit: true,      // 允許編輯與彈窗事件
  allowContinuous: true, // 支援跨日拖曳
  allowAutoAssign: true, // 支援自動指派
  showAssignButton: true,// 顯示指派按鈕
  view: {
    count: 7            // 預設展示 7 天 (亦可設定為 'month' 展示整月)
  }
});

// 4. 監聽拖放完成事件 (Drop)
calendar.on('drop', (event) => {
  console.log('拖放成功,新預訂資訊:', event);
  // 可在此串接 API 將變更寫回資料庫
});

📖 API 參考文件 (API Reference)

初始化設定 (Initialization Options)

| 選項參數 | 類型 | 預設值 | 說明 | | :--- | :--- | :--- | :--- | | resource | Array | [] | 資源樹資料結構(包含父房型與子房號)。 | | items | Array | [] | 預訂卡片資料陣列(會自動生成或對齊 _uid)。 | | stock | Object | {} | 每日庫存量與剩餘房數資訊。 | | holidays | Array | [] | 特殊節假日資料,會在表頭顯示標記。 | | locale | String | 'tw' | 語系設定:'tw' (繁體中文)、'en' (英文)、'ja' (日文)。 | | allowEdit | Boolean | true | 是否啟用編輯與點擊卡片事件。 | | allowContinuous| Boolean | true | 是否允許跨日連續卡片顯示。 | | allowAutoAssign| Boolean | true | 是否啟用拖曳自動指派機制。 | | allowChangeDate| Boolean | true | 是否允許在拖放中改變日期。 | | allowChangeType| Boolean | true | 是否允許在拖放中改變房型/資源類別。 | | showAssignButton| Boolean | false | 是否在預訂卡片上顯示指派按鈕。 | | view.count | Number\|String| 7 | 展示天數(傳入數字)或設定為 'month'。 |

📊 資料格式說明 (Data Formats)

為了讓排程表正常運作,傳入的 resourceitems 以及 stock 必須符合特定的資料結構。以下是各資料結構的詳細說明與範例:

1. 資源資料 (resource)

資源資料通常為樹狀結構,代表「房型(父級)」與「房號(子級)」。

  • id (Number|String): 資源的唯一識別碼。
  • name (String): 資源顯示名稱。
  • active (Boolean, 選填): 是否啟用。
  • children (Array, 選填): 子級資源清單(如房號)。子級資源同樣包含 idname
const resources = [
  {
    id: 1,
    name: '標準雙人房',
    active: true,
    children: [
      { id: 101, name: '101 室' },
      { id: 102, name: '102 室' }
    ]
  }
];

2. 預訂卡片資料 (items)

代表預訂或排程卡片,顯示於時間軸上。

  • id (Number|String): 預訂的唯一識別碼。
  • title (String): 卡片上顯示的標題或客戶姓名。
  • start (String): 開始日期,格式為 YYYY-MM-DD
  • end (String): 結束日期,格式為 YYYY-MM-DD
  • room_type (Number|String): 所屬的父級資源(房型)ID。
  • room_number_id (Number|String, 選填): 所屬的子級資源(房號)ID。若為 null 或未指定且啟用自動分配,則可能被視為未排房。
  • assign (Boolean): 是否已指派房號。
  • checked_status (String, 選填): 自訂的狀態樣式名稱(例如 'checked-in', 'checked-out', 'noshow')。
const items = [
  {
    id: 'res-9981',
    title: '王小明 (3晚)',
    start: '2026-05-20',
    end: '2026-05-23',
    room_type: 1,
    room_number_id: 101,
    assign: true,
    checked_status: 'checked-in'
  }
];

3. 每日庫存資料 (stock)

用於呈現每日的房間庫存、價格及開放狀態。結構為巢狀物件:外層 Key 為資源 ID(房型 ID),內層 Key 為日期(YYYY-MM-DD。 每個日期對應的 Stock 物件必要內容如下:

  • price (Number): 每日房價。
  • stock (Number): 剩餘庫存量。
  • open (Number): 庫存開啟狀態,1 表示開啟,0 表示關閉(關閉時會顯示鎖定/無庫存狀態)。
  • full (Number): 滿房狀態,1 表示已滿,0 表示未滿(滿房時會呈現滿房樣式)。
const stock = {
  // Key '1' 代表 room_type_id 為 1 的房型
  "1": {
    "2026-05-20": {
      "price": 2800,
      "stock": 5,
      "open": 1,
      "full": 0
    },
    "2026-05-21": {
      "price": 2800,
      "stock": 0,
      "open": 1,
      "full": 1  // 滿房
    },
    "2026-05-22": {
      "price": 3200,
      "stock": 3,
      "open": 0, // 關閉房況
      "full": 0
    }
  }
};

公開方法 (Public Methods)

套件實例提供了多個 API 方法,便於您動態控制排程表:

  • setItems(items) 更新排程卡片資料。內部會自動維護 _uid 的一致性並透過 Idiomorph 進行局部 DOM 無痕刷新。

    calendar.setItems(newItemsList);
  • setResource(resource) 更新資源選單資料並重新計算排程網格。

    calendar.setResource(newResourcesList);
  • setStock(stock) 更新每日庫存與剩餘房數。

    calendar.setStock(newStockData);
  • refresh() 手動觸發視圖重新渲染。

    calendar.refresh();
  • destroy() 徹底銷毀排程表實例,清除所有全域事件監聽器(如 window 滾動監聽),並還原 DOM 容器。

    calendar.destroy();

事件監聽 (Event Listeners)

您可以使用 .on(eventName, callback) 方法監聽排程表內的交互事件:

  • click 當點擊卡片、空白網格或日期表頭時觸發。

    calendar.on('click', (data) => {
      // data 包含 type ('item'|'date'|'cell'), value 及原始事件 e
      console.log('點擊事件:', data);
    });
  • drop 當預訂卡片拖曳釋放並成功變更位置時觸發。

    calendar.on('drop', (data) => {
      // data 包含卡片的 _uid, 新日期, 房號 room, 原始數據 rawData 等
      console.log('拖曳落點更新:', data);
    });
  • change 當開關選項、視圖天數改變或刷新時觸發。

    calendar.on('change', (data) => {
      console.log('狀態變更:', data);
    });

🛠️ 開發與建置 (Development)

若您需要對套件進行二次開發或客製化,請確保已在專案目錄下執行 npm install

啟動本地開發伺服器

運行 Vite 開發伺服器,並開啟 Dev Demo 頁面進行調試:

npm run dev

建置生產環境版本

使用 Vite 將源碼與樣式打包編譯至 dist 目錄:

npm run build

建置輸出將包含:

  • dist/calendar-scheduler.es.js - 優化壓縮後的 ESM 核心邏輯
  • dist/style.css - 自研 CSS 樣式檔

監聽建置模式

npm run build:watch

📄 授權協議 (License)

本專案採用 MIT License 授權協議。您可以自由地商用、修改及分發。