{"_id":"@bw-ui/datepicker-data","name":"@bw-ui/datepicker-data","dist-tags":{"latest":"1.1.0"},"versions":{"1.1.0":{"name":"@bw-ui/datepicker-data","version":"1.1.0","description":"Data plugin for @bw-ui/datepicker - API integration for prices, availability, events","main":"dist/bw-data.min.js","module":"dist/bw-data.esm.min.js","exports":{".":{"import":"./dist/bw-data.esm.min.js","require":"./dist/bw-data.min.js"},"./css":"./dist/bw-data.min.css"},"types":"src/index.d.ts","scripts":{"build":"node build.js"},"keywords":["datepicker","data","api","prices","availability","calendar","bw-ui"],"author":{"name":"BW UI"},"license":"MIT","peerDependencies":{"@bw-ui/datepicker":"^1.0.0"},"devDependencies":{"esbuild":"^0.20.0"},"repository":{"type":"git","url":"git+https://github.com/bw-ui/bw-datepicker.git"},"bugs":{"url":"https://github.com/bw-ui/bw-datepicker/issues"},"homepage":"https://github.com/bw-ui/bw-datepicker","type":"module","_id":"@bw-ui/datepicker-data@1.1.0","gitHead":"30d8915a21fd5e442ea3830e44532446a20dfa3c","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-uRYchF8QPMzntUOiKIA/3JAa2kaFWBoiZakuhzOuCd62YMR/TtT+edHua1cc8Ea9bTHddYMkv9CcODA2x9i7hA==","shasum":"30c13a697e4670515a86e04faedb2bcb20239c07","tarball":"https://registry.npmjs.org/@bw-ui/datepicker-data/-/datepicker-data-1.1.0.tgz","fileCount":6,"unpackedSize":41067,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCsKh3PJmwdC1SiSIrN8AexgxTWJFybwcMurE7274Yq4wIgJU3ZNl44EsSqRQMNFwqcU1o3Pp0OkKwiRUIHMc5r/Dc="}]},"_npmUser":{"name":"rchoudhary.dev","email":"rchoudhary.dev@gmail.com"},"directories":{},"maintainers":[{"name":"rchoudhary.dev","email":"rchoudhary.dev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/datepicker-data_1.1.0_1764510949788_0.6034050180355239"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-30T13:55:49.605Z","1.1.0":"2025-11-30T13:55:49.991Z","modified":"2025-11-30T13:55:50.360Z"},"maintainers":[{"name":"rchoudhary.dev","email":"rchoudhary.dev@gmail.com"}],"description":"Data plugin for @bw-ui/datepicker - API integration for prices, availability, events","homepage":"https://github.com/bw-ui/bw-datepicker","keywords":["datepicker","data","api","prices","availability","calendar","bw-ui"],"repository":{"type":"git","url":"git+https://github.com/bw-ui/bw-datepicker.git"},"author":{"name":"BW UI"},"bugs":{"url":"https://github.com/bw-ui/bw-datepicker/issues"},"license":"MIT","readme":"# @bw-ui/datepicker-data\r\n\r\nData plugin for BW DatePicker - API integration for prices, availability, and events.\r\n\r\n![Version](https://img.shields.io/npm/v/@bw-ui/datepicker-data)\r\n![License](https://img.shields.io/npm/l/@bw-ui/datepicker-data)\r\n![Size](https://img.shields.io/bundlephobia/minzip/@bw-ui/datepicker-data)\r\n\r\n[Live Demo](https://bw-ui.github.io/bw-datepicker) • [Documentation](https://www.npmjs.com/package/@bw-ui/datepicker-data) • [Core Package](https://www.npmjs.com/package/@bw-ui/datepicker)\r\n\r\n## ✨ Features\r\n\r\n- 💰 **Price Display** - Show prices in day cells\r\n- 🏨 **Availability Status** - Available, limited, sold-out states\r\n- 🔄 **API Integration** - Fetch data from any endpoint\r\n- 📦 **Static Data** - Use pre-defined data objects\r\n- ⏳ **Multiple Loader Types** - Overlay, calendar, skeleton, or spinner\r\n- 🗄️ **Caching** - Cache fetched months to avoid re-fetching\r\n- 🔁 **Auto Retry** - Retry failed requests automatically\r\n- 📐 **Expanded Mode** - Larger cells for better readability\r\n- 📅 **View Mode Support** - Works with calendar and week views\r\n- 📆 **DualCalendar Support** - Automatically fetches data for all visible months\r\n\r\n## 📦 Installation\r\n\r\n```bash\r\nnpm install @bw-ui/datepicker @bw-ui/datepicker-data\r\n```\r\n\r\n> ⚠️ **Peer Dependency:** Requires `@bw-ui/datepicker` core package\r\n\r\n## 🚀 Quick Start\r\n\r\n### ES Modules\r\n\r\n```javascript\r\nimport { BWDatePicker } from '@bw-ui/datepicker';\r\nimport { DataPlugin } from '@bw-ui/datepicker-data';\r\nimport '@bw-ui/datepicker/css';\r\nimport '@bw-ui/datepicker-data/css';\r\n\r\nconst picker = new BWDatePicker('#date-input').use(DataPlugin, {\r\n  data: {\r\n    '2025-12-01': { price: 99, status: 'available' },\r\n    '2025-12-02': { price: 150, status: 'limited' },\r\n    '2025-12-03': { price: 200, status: 'sold-out' },\r\n  },\r\n  renderDay: (dateKey, data) => {\r\n    if (!data) return '';\r\n    return `<span class=\"price\">₹${data.price}</span>`;\r\n  },\r\n  dayClass: (dateKey, data) => data?.status || '',\r\n});\r\n```\r\n\r\n### CDN\r\n\r\n```html\r\n<link\r\n  rel=\"stylesheet\"\r\n  href=\"https://unpkg.com/@bw-ui/datepicker/dist/bw-datepicker.min.css\"\r\n/>\r\n<link\r\n  rel=\"stylesheet\"\r\n  href=\"https://unpkg.com/@bw-ui/datepicker-data/dist/bw-data.min.css\"\r\n/>\r\n\r\n<script src=\"https://unpkg.com/@bw-ui/datepicker/dist/bw-datepicker.min.js\"></script>\r\n<script src=\"https://unpkg.com/@bw-ui/datepicker-data/dist/bw-data.min.js\"></script>\r\n\r\n<script>\r\n  const picker = new BWDatePicker('#date-input').use(BWData.DataPlugin, {\r\n    data: {\r\n      '2025-12-01': { price: 99, status: 'available' },\r\n    },\r\n    renderDay: (dateKey, data) =>\r\n      data ? `<span class=\"price\">₹${data.price}</span>` : '',\r\n    dayClass: (dateKey, data) => data?.status || '',\r\n  });\r\n</script>\r\n```\r\n\r\n## ⚙️ Options\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  // Data Sources\r\n  data: {},                     // Static data object\r\n  fetch: async () => {},        // Fetch function\r\n  fetchPriority: 'replace',     // 'replace' | 'merge' | 'fallback'\r\n\r\n  // Rendering\r\n  renderDay: (dateKey, data) => '',   // Custom day content\r\n  dayClass: (dateKey, data) => '',    // Custom day class\r\n\r\n  // Display\r\n  expanded: false,              // Larger day cells\r\n\r\n  // Loading Options\r\n  showLoading: true,            // Show loader while fetching\r\n  loaderType: 'overlay',        // 'overlay' | 'calendar' | 'skeleton' | 'spinner'\r\n\r\n  // Fetch Options\r\n  cache: true,                  // Cache fetched months\r\n  retries: 2,                   // Retry failed requests\r\n  timeout: 10000,               // Request timeout (ms)\r\n})\r\n```\r\n\r\n### Options Reference\r\n\r\n| Option          | Type       | Default     | Description                            |\r\n| --------------- | ---------- | ----------- | -------------------------------------- |\r\n| `data`          | `object`   | `null`      | Static data object with date keys      |\r\n| `fetch`         | `function` | `null`      | Async function to fetch data           |\r\n| `fetchPriority` | `string`   | `'replace'` | How fetch interacts with static data   |\r\n| `renderDay`     | `function` | `null`      | Custom render function for day content |\r\n| `dayClass`      | `function` | `null`      | Custom class function for day cells    |\r\n| `expanded`      | `boolean`  | `false`     | Enable larger day cells                |\r\n| `showLoading`   | `boolean`  | `true`      | Show loading indicator                 |\r\n| `loaderType`    | `string`   | `'overlay'` | Type of loading indicator              |\r\n| `cache`         | `boolean`  | `true`      | Cache fetched months                   |\r\n| `retries`       | `number`   | `2`         | Number of retry attempts               |\r\n| `timeout`       | `number`   | `10000`     | Request timeout in ms                  |\r\n\r\n## ⏳ Loader Types\r\n\r\n| Type         | Description                                | Blocks Clicks |\r\n| ------------ | ------------------------------------------ | ------------- |\r\n| `'overlay'`  | Full picker overlay with spinner (default) | ✅ Yes        |\r\n| `'calendar'` | Only calendar area has spinner             | ❌ No         |\r\n| `'skeleton'` | Skeleton loaders on each day cell          | ❌ No         |\r\n| `'spinner'`  | Small spinner in corner                    | ❌ No         |\r\n\r\n### Overlay Loader (Default)\r\n\r\nBlocks all interaction while loading - prevents accidental navigation.\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  fetch: fetchPrices,\r\n  loaderType: 'overlay',\r\n})\r\n```\r\n\r\n### Calendar Loader\r\n\r\nOnly calendar area shows loader - user can still use header navigation.\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  fetch: fetchPrices,\r\n  loaderType: 'calendar',\r\n})\r\n```\r\n\r\n### Skeleton Loader\r\n\r\nShows skeleton animation on each day cell.\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  fetch: fetchPrices,\r\n  loaderType: 'skeleton',\r\n})\r\n```\r\n\r\n### Spinner Loader\r\n\r\nNon-intrusive small spinner in corner.\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  fetch: fetchPrices,\r\n  loaderType: 'spinner',\r\n})\r\n```\r\n\r\n### Disable Loading Indicator\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  fetch: fetchPrices,\r\n  showLoading: false,\r\n})\r\n```\r\n\r\n## 📊 Data Format\r\n\r\n```javascript\r\n{\r\n  \"2025-12-01\": { price: 99, status: \"available\", rooms: 5 },\r\n  \"2025-12-02\": { price: 150, status: \"limited\", rooms: 2 },\r\n  \"2025-12-03\": { price: 200, status: \"sold-out\", rooms: 0 },\r\n}\r\n```\r\n\r\n### Built-in Status Classes\r\n\r\n| Status      | CSS Class    | Effect                   |\r\n| ----------- | ------------ | ------------------------ |\r\n| `available` | `.available` | Green background         |\r\n| `limited`   | `.limited`   | Yellow background        |\r\n| `sold-out`  | `.sold-out`  | Red background, disabled |\r\n\r\n## 📖 Examples\r\n\r\n### Static Data\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  data: {\r\n    '2025-12-01': { price: 99, status: 'available' },\r\n    '2025-12-02': { price: 150, status: 'limited' },\r\n  },\r\n  renderDay: (dateKey, data) => data ? `<span class=\"price\">₹${data.price}</span>` : '',\r\n  dayClass: (dateKey, data) => data?.status || '',\r\n})\r\n```\r\n\r\n### API Fetch\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  fetch: async ({ month, year, signal }) => {\r\n    const res = await fetch(`/api/prices?month=${month}&year=${year}`, { signal });\r\n    return res.json();\r\n  },\r\n  renderDay: (dateKey, data) => data ? `<span class=\"price\">₹${data.price}</span>` : '',\r\n  dayClass: (dateKey, data) => data?.status || '',\r\n})\r\n```\r\n\r\n### Fake Data for Testing\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  fetch: async ({ month, year }) => {\r\n    await new Promise(r => setTimeout(r, 1000)); // 1 sec delay\r\n\r\n    const daysInMonth = new Date(year, month + 1, 0).getDate();\r\n    const data = {};\r\n\r\n    for (let day = 1; day <= daysInMonth; day++) {\r\n      const dateKey = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;\r\n      const rooms = Math.floor(Math.random() * 10);\r\n      data[dateKey] = {\r\n        price: Math.floor(Math.random() * 300) + 50,\r\n        rooms: rooms,\r\n        status: rooms === 0 ? 'sold-out' : rooms < 3 ? 'limited' : 'available'\r\n      };\r\n    }\r\n    return data;\r\n  },\r\n  loaderType: 'skeleton',\r\n  renderDay: (dateKey, data) => {\r\n    if (!data) return '';\r\n    return `<span class=\"price\">₹${data.price}</span>`;\r\n  },\r\n  dayClass: (dateKey, data) => data?.status || '',\r\n})\r\n```\r\n\r\n### Expanded Mode (Larger Cells)\r\n\r\n```javascript\r\n.use(DataPlugin, {\r\n  expanded: true,\r\n  data: { ... },\r\n  renderDay: (dateKey, data) => {\r\n    if (!data) return '';\r\n    const statusColor = {\r\n      'available': '#16a34a',\r\n      'limited': '#ca8a04',\r\n      'sold-out': '#dc2626'\r\n    }[data.status] || '#666';\r\n\r\n    return `\r\n      <div style=\"display: flex; flex-direction: column; align-items: center; gap: 1px; margin-top: 2px;\">\r\n        <span style=\"font-size: 11px; font-weight: 700; color: ${statusColor};\">₹${data.price}</span>\r\n        <span style=\"font-size: 8px; color: #999;\">${data.rooms} left</span>\r\n      </div>\r\n    `;\r\n  },\r\n  dayClass: (dateKey, data) => data?.status || '',\r\n})\r\n```\r\n\r\n## 🔄 Fetch Priority\r\n\r\n| Priority     | Behavior                                      |\r\n| ------------ | --------------------------------------------- |\r\n| `'replace'`  | Fetch overwrites static data (default)        |\r\n| `'merge'`    | Fetch + static combined, fetch wins conflicts |\r\n| `'fallback'` | Only fetch if no static data exists for month |\r\n\r\n```javascript\r\n// Static as placeholder, API updates\r\n.use(DataPlugin, {\r\n  data: { ... },              // Shows immediately\r\n  fetch: async () => { ... }, // Replaces when loaded\r\n  fetchPriority: 'replace',\r\n})\r\n\r\n// Merge static defaults with API data\r\n.use(DataPlugin, {\r\n  data: { ... },\r\n  fetch: async () => { ... },\r\n  fetchPriority: 'merge',\r\n})\r\n\r\n// Use static, only fetch if missing\r\n.use(DataPlugin, {\r\n  data: { ... },\r\n  fetch: async () => { ... },\r\n  fetchPriority: 'fallback',\r\n})\r\n```\r\n\r\n## 🎨 Custom Rendering\r\n\r\n### Price with Status Badge\r\n\r\n```javascript\r\nrenderDay: (dateKey, data) => {\r\n  if (!data) return '';\r\n\r\n  const statusBg = {\r\n    'available': '#dcfce7',\r\n    'limited': '#fef9c3',\r\n    'sold-out': '#fee2e2'\r\n  }[data.status] || '#f3f4f6';\r\n\r\n  const statusText = {\r\n    'available': '#16a34a',\r\n    'limited': '#ca8a04',\r\n    'sold-out': '#dc2626'\r\n  }[data.status] || '#666';\r\n\r\n  return `\r\n    <div style=\"display: flex; flex-direction: column; align-items: center; gap: 3px; margin-top: 4px;\">\r\n      <span style=\"font-size: 11px; font-weight: 700; color: ${statusText};\">₹${data.price}</span>\r\n      <span style=\"font-size: 7px; background: ${statusBg}; color: ${statusText}; padding: 1px 4px; border-radius: 4px;\">${data.rooms} left</span>\r\n    </div>\r\n  `;\r\n},\r\n```\r\n\r\n## 🔌 API Methods\r\n\r\nAccess via `picker.getPlugin('data')`:\r\n\r\n```javascript\r\nconst dataPlugin = picker.getPlugin('data');\r\n\r\n// Get data for specific date\r\ndataPlugin.get('2025-12-01');\r\n\r\n// Set data for specific date\r\ndataPlugin.set('2025-12-01', { price: 99, status: 'available' });\r\n\r\n// Set data for entire month\r\ndataPlugin.setMonth(11, 2025, { ... });\r\n\r\n// Get data for date range\r\ndataPlugin.getRange(new Date('2025-12-01'), new Date('2025-12-07'));\r\n\r\n// Sum property across range (e.g., total price)\r\ndataPlugin.sumRange(new Date('2025-12-01'), new Date('2025-12-07'), 'price');\r\n\r\n// Refresh data (clear cache + re-fetch)\r\ndataPlugin.refresh();\r\n\r\n// Clear all data\r\ndataPlugin.clear();\r\n\r\n// Check if loading\r\ndataPlugin.isLoading();\r\n```\r\n\r\n## 📡 Events\r\n\r\n```javascript\r\nconst picker = new BWDatePicker('#date-input')\r\n  .use(DataPlugin, { ... });\r\n\r\npicker.on('data:loaded', ({ month, year, data }) => {\r\n  console.log('Data loaded:', data);\r\n});\r\n\r\npicker.on('data:error', ({ month, year, error }) => {\r\n  console.error('Fetch failed:', error);\r\n});\r\n```\r\n\r\n## 📅 View Mode Support\r\n\r\nThe Data Plugin automatically handles different view modes:\r\n\r\n| View Mode  | Data Display              |\r\n| ---------- | ------------------------- |\r\n| `calendar` | ✅ Shows data on days     |\r\n| `week`     | ✅ Shows data on days     |\r\n| `month`    | ❌ No data (month picker) |\r\n| `year`     | ❌ No data (year picker)  |\r\n\r\nData is automatically fetched when:\r\n\r\n- Picker opens\r\n- Month/year navigation\r\n- Week navigation (in week view)\r\n- Switching back to calendar/week view\r\n\r\n## 🔌 Combining with Other Plugins\r\n\r\n```javascript\r\nimport { BWDatePicker } from '@bw-ui/datepicker';\r\nimport { ThemingPlugin } from '@bw-ui/datepicker-theming';\r\nimport { DataPlugin } from '@bw-ui/datepicker-data';\r\n\r\nconst picker = new BWDatePicker('#date-input')\r\n  .use(ThemingPlugin, { theme: 'dark' })\r\n  .use(DataPlugin, {\r\n    expanded: true,\r\n    loaderType: 'overlay',\r\n    data: { ... },\r\n    renderDay: (dateKey, data) => { ... },\r\n  });\r\n```\r\n\r\n## 📁 What's Included\r\n\r\n```\r\ndist/\r\n├── bw-data.min.js       # IIFE build (for <script>)\r\n├── bw-data.esm.min.js   # ESM build (for import)\r\n└── bw-data.min.css      # Styles\r\n```\r\n\r\n## 🔗 Related Packages\r\n\r\n| Package                                                                                          | Description          |\r\n| ------------------------------------------------------------------------------------------------ | -------------------- |\r\n| [@bw-ui/datepicker](https://www.npmjs.com/package/@bw-ui/datepicker)                             | Core (required)      |\r\n| [@bw-ui/datepicker-theming](https://www.npmjs.com/package/@bw-ui/datepicker-theming)             | Dark mode            |\r\n| [@bw-ui/datepicker-range](https://www.npmjs.com/package/@bw-ui/datepicker-range)                 | Date range selection |\r\n| [@bw-ui/datepicker-positioning](https://www.npmjs.com/package/@bw-ui/datepicker-positioning)     | Auto positioning     |\r\n| [@bw-ui/datepicker-accessibility](https://www.npmjs.com/package/@bw-ui/datepicker-accessibility) | Keyboard nav         |\r\n| [@bw-ui/datepicker-mobile](https://www.npmjs.com/package/@bw-ui/datepicker-mobile)               | Touch support        |\r\n\r\n## 📄 License\r\n\r\nMIT © [BW UI](https://github.com/bw-ui)\r\n\r\n## 🐛 Issues\r\n\r\nFound a bug? [Report it here](https://github.com/bw-ui/bw-datepicker/issues)\r\n","readmeFilename":"README.md","_rev":"1-1877870b44023abc9418389950f2aeb3"}