resources-247d05d5.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.82
  5. */
  6. 'use strict';
  7. const index = require('./index-5c65e149.js');
  8. const locale = require('./locale-f2ebe4fa.js');
  9. /**
  10. * Get supported locale code from raw user input
  11. * Exported for testing purposes.
  12. * @private
  13. */
  14. function getSupportedLocale(lang = "") {
  15. if (locale.locales.indexOf(lang) > -1) {
  16. return lang;
  17. }
  18. lang = lang.toLowerCase();
  19. if (lang.includes("-")) {
  20. lang = lang.replace(/(\w+)-(\w+)/, (_match, language, region) => `${language}-${region.toUpperCase()}`);
  21. if (!locale.locales.includes(lang)) {
  22. lang = lang.split("-")[0];
  23. }
  24. }
  25. return locale.locales.includes(lang) ? lang : "en";
  26. }
  27. /**
  28. * CLDR cache.
  29. * Exported for testing purposes.
  30. * @private
  31. */
  32. const translationCache = {};
  33. /**
  34. * CLDR request cache.
  35. * Exported for testing purposes.
  36. * @private
  37. */
  38. const requestCache = {};
  39. /**
  40. * Fetch calendar data for a given locale from list of supported languages
  41. * @public
  42. */
  43. async function getLocaleData(lang) {
  44. const locale = getSupportedLocale(lang);
  45. if (translationCache[locale]) {
  46. return translationCache[locale];
  47. }
  48. if (!requestCache[locale]) {
  49. requestCache[locale] = fetch(index.getAssetPath(`./assets/date-picker/nls/${locale}.json`))
  50. .then((resp) => resp.json())
  51. .catch(() => {
  52. console.error(`Translations for "${locale}" not found or invalid, falling back to english`);
  53. return getLocaleData("en");
  54. });
  55. }
  56. const data = await requestCache[locale];
  57. translationCache[locale] = data;
  58. return data;
  59. }
  60. /**
  61. * Check if date is within a min and max
  62. */
  63. function inRange(date, min, max) {
  64. const time = date.getTime();
  65. const afterMin = !(min instanceof Date) || time >= min.getTime();
  66. const beforeMax = !(max instanceof Date) || time <= max.getTime();
  67. return afterMin && beforeMax;
  68. }
  69. /**
  70. * Ensures date is within range,
  71. * returns min or max if out of bounds
  72. */
  73. function dateFromRange(date, min, max) {
  74. if (!(date instanceof Date)) {
  75. return null;
  76. }
  77. const time = date.getTime();
  78. const beforeMin = min instanceof Date && time < min.getTime();
  79. const afterMax = max instanceof Date && time > max.getTime();
  80. if (beforeMin) {
  81. return min;
  82. }
  83. if (afterMax) {
  84. return max;
  85. }
  86. return date;
  87. }
  88. /**
  89. * Parse an iso8601 string (YYYY-mm-dd) into a valid date.
  90. * TODO: handle time when time of day UI is added
  91. */
  92. function dateFromISO(iso8601) {
  93. if (iso8601 instanceof Date) {
  94. return iso8601;
  95. }
  96. if (!iso8601 || typeof iso8601 !== "string") {
  97. return null;
  98. }
  99. const d = iso8601.split(/[: T-]/).map(parseFloat);
  100. const date = new Date(d[0], (d[1] || 1) - 1, d[2] || 1);
  101. date.setFullYear(d[0]);
  102. if (isNaN(date.getTime())) {
  103. throw new Error(`Invalid ISO 8601 date: "${iso8601}"`);
  104. }
  105. return date;
  106. }
  107. /**
  108. * Return first portion of ISO string (YYYY-mm-dd)
  109. */
  110. function dateToISO(date) {
  111. if (typeof date === "string") {
  112. return date;
  113. }
  114. if (date instanceof Date) {
  115. return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().split("T")[0];
  116. }
  117. return "";
  118. }
  119. /**
  120. * Check if two dates are the same day, month, year
  121. */
  122. function sameDate(d1, d2) {
  123. return (d1 instanceof Date &&
  124. d2 instanceof Date &&
  125. d1.getDate() === d2.getDate() &&
  126. d1.getMonth() === d2.getMonth() &&
  127. d1.getFullYear() === d2.getFullYear());
  128. }
  129. /**
  130. * Get a date one month in the past
  131. */
  132. function prevMonth(date) {
  133. const month = date.getMonth();
  134. const nextDate = new Date(date);
  135. nextDate.setMonth(month - 1);
  136. // date doesn't exist in new month, use last day
  137. if (month === nextDate.getMonth()) {
  138. return new Date(date.getFullYear(), month, 0);
  139. }
  140. return nextDate;
  141. }
  142. /**
  143. * Get a date one month in the future
  144. */
  145. function nextMonth(date) {
  146. const month = date.getMonth();
  147. const nextDate = new Date(date);
  148. nextDate.setMonth(month + 1);
  149. // date doesn't exist in new month, use last day
  150. if ((month + 2) % 7 === nextDate.getMonth() % 7) {
  151. return new Date(date.getFullYear(), month + 2, 0);
  152. }
  153. return nextDate;
  154. }
  155. /**
  156. * Translate a number into a given locals numeral system
  157. */
  158. function localizeNumber(num, localeData) {
  159. return String(num)
  160. .split("")
  161. .map((i) => localeData.numerals[i])
  162. .join("");
  163. }
  164. /**
  165. * Calculate actual number from localized string
  166. */
  167. function parseNumber(str, localeData) {
  168. const numerals = "0123456789";
  169. return parseInt(str
  170. .split("")
  171. .map((i) => numerals[localeData.numerals.indexOf(i)])
  172. .filter((num) => num)
  173. .join(""));
  174. }
  175. /**
  176. * Parse numeric units for day, month, and year from a localized string
  177. * month starts at 0 (can pass to date constructor)
  178. */
  179. function parseDateString(str, localeData) {
  180. const { separator, unitOrder } = localeData;
  181. const order = getOrder(unitOrder);
  182. const values = replaceArabicNumerals(str).split(separator);
  183. return {
  184. day: parseInt(values[order.indexOf("d")]),
  185. month: parseInt(values[order.indexOf("m")]) - 1,
  186. year: parseInt(values[order.indexOf("y")])
  187. };
  188. }
  189. /**
  190. * Convert eastern arbic numerals
  191. */
  192. function replaceArabicNumerals(str = "") {
  193. return str
  194. .replace(/[\u0660-\u0669]/g, (c) => (c.charCodeAt(0) - 0x0660))
  195. .replace(/[\u06f0-\u06f9]/g, (c) => (c.charCodeAt(0) - 0x06f0));
  196. }
  197. /**
  198. * Based on the unitOrder string, find order of month, day, and year for locale
  199. */
  200. function getOrder(unitOrder) {
  201. const signifiers = ["d", "m", "y"];
  202. const order = unitOrder.toLowerCase();
  203. return signifiers.sort((a, b) => order.indexOf(a) - order.indexOf(b));
  204. }
  205. /**
  206. * Get number of days between two dates
  207. */
  208. function getDaysDiff(date1, date2) {
  209. const ts1 = date1.getTime();
  210. const ts2 = date2.getTime();
  211. return (ts1 - ts2) / (1000 * 3600 * 24);
  212. }
  213. const HEADING_LEVEL = 2;
  214. const TEXT = {
  215. nextMonth: "Next month",
  216. prevMonth: "Previous month",
  217. year: "Year"
  218. };
  219. exports.HEADING_LEVEL = HEADING_LEVEL;
  220. exports.TEXT = TEXT;
  221. exports.dateFromISO = dateFromISO;
  222. exports.dateFromRange = dateFromRange;
  223. exports.dateToISO = dateToISO;
  224. exports.getDaysDiff = getDaysDiff;
  225. exports.getLocaleData = getLocaleData;
  226. exports.getOrder = getOrder;
  227. exports.inRange = inRange;
  228. exports.localizeNumber = localizeNumber;
  229. exports.nextMonth = nextMonth;
  230. exports.parseDateString = parseDateString;
  231. exports.parseNumber = parseNumber;
  232. exports.prevMonth = prevMonth;
  233. exports.sameDate = sameDate;