@oruga-ui/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
157 lines (141 loc) • 5.03 kB
text/typescript
type MonthType =
| "numeric"
| "2-digit"
| "long"
| "short"
| "narrow"
| undefined;
/**
* Return month names according to a specified locale
* @param {String} locale A bcp47 localerouter. undefined will use the user browser locale
* @param {String} format long (ex. March), short (ex. Mar) or narrow (M)
* @return {Array<String>} An array of month names
*/
export function getMonthNames(
locale?: string,
format: MonthType = "long",
): string[] {
const dates: Date[] = [];
for (let i = 0; i < 12; i++) {
dates.push(new Date(2000, i, 15));
}
const dtf = new Intl.DateTimeFormat(locale, {
month: format,
});
return dates.map((d) => dtf.format(d));
}
type WeekdayType = "long" | "short" | "narrow" | undefined;
/**
* Return weekday names according to a specified locale
* @param {String} locale A bcp47 localerouter. undefined will use the user browser locale
* @param {Number} first day of week index
* @param {String} format long (ex. Thursday), short (ex. Thu) or narrow (T)
* @return {Array<String>} An array of weekday names
*/
export function getWeekdayNames(
locale?: string,
firstDayOfWeek: number = 0,
format: WeekdayType = "narrow",
): string[] {
const dates: Date[] = [];
for (let i = 1, j = 0; j < 7; i++) {
const d = new Date(2000, 0, i);
const day = d.getDay();
if (day === firstDayOfWeek || j > 0) {
dates.push(d);
j++;
}
}
const dtf = new Intl.DateTimeFormat(locale, {
weekday: format,
});
return dates.map((d) => dtf.format(d));
}
/**
* Accept a regex with group names and return an object
* ex. matchWithGroups(/((?!=<year>)\d+)\/((?!=<month>)\d+)\/((?!=<day>)\d+)/, '2000/12/25')
* will return { year: 2000, month: 12, day: 25 }
* @param {String} includes injections of (?!={groupname}) for each group
* @param {String} the string to run regex
* @return {Object} an object with a property for each group having the group's match as the value
*/
export function matchWithGroups(pattern: string, str: string): any {
const matches = str.match(pattern);
return (
// get the pattern as a string
pattern
.toString()
// suss out the groups
.match(/<(.+?)>/g)
// remove the braces
?.map((group) => {
const groupMatches = group.match(/<(.+)>/);
if (!groupMatches || groupMatches.length <= 0) {
return null;
}
const match = group.match(/<(.+)>/);
return match && match?.length > 1 ? match[1] : null;
})
// create an object with a property for each group having the group's match as the value
.reduce((acc, curr, index) => {
if (curr === null) return acc;
if (matches && matches.length > index) {
acc[curr] = matches[index + 1];
} else {
acc[curr] = null;
}
return acc;
}, {} as any)
);
}
/** Return array of all days in the week that the startingDate is within */
export function weekBuilder(
startingDate: number,
month: number,
year: number,
firstDayOfWeek: number,
): Date[] {
const thisMonth = new Date(year, month);
const thisWeek: Date[] = [];
const dayOfWeek = new Date(year, month, startingDate).getDay();
const end =
dayOfWeek >= firstDayOfWeek
? dayOfWeek - firstDayOfWeek
: 7 - firstDayOfWeek + dayOfWeek;
let daysAgo = 1;
for (let i = 0; i < end; i++) {
thisWeek.unshift(
new Date(
thisMonth.getFullYear(),
thisMonth.getMonth(),
startingDate - daysAgo,
),
);
daysAgo++;
}
thisWeek.push(new Date(year, month, startingDate));
let daysForward = 1;
while (thisWeek.length < 7) {
thisWeek.push(new Date(year, month, startingDate + daysForward));
daysForward++;
}
return thisWeek;
}
export function firstWeekOffset(year, dow, doy): number {
// first-week day -- which january is always in the first week (4 for iso, 1 for other)
const fwd = 7 + dow - doy;
// first-week day local weekday -- which local weekday is fwd
const firstJanuary = new Date(year, 0, fwd);
const fwdlw = (7 + firstJanuary.getDay() - dow) % 7;
return -fwdlw + fwd - 1;
}
/** Return the number of days in a specific year */
export function daysInYear(year): number {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 ? 366 : 365;
}
/** Return the number of weeks in a specific year */
export function weeksInYear(year, dow, doy): number {
const weekOffset = firstWeekOffset(year, dow, doy);
const weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
}