Skip to content

Commit

Permalink
STCOM-849 wrong day of week (#1583)
Browse files Browse the repository at this point in the history
* add static default region list, apply day offset to calendar

* remove locale from datepicker story, lint

* Update CHANGELOG.md
  • Loading branch information
JohnC-80 authored Jul 8, 2021
1 parent 8ba01d2 commit 54ccca4
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 14 deletions.
7 changes: 6 additions & 1 deletion .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import frTranslations from '../translations/stripes-components/fr.json';
import huTranslations from '../translations/stripes-components/hu.json';
import itTranslations from '../translations/stripes-components/it_IT.json';
import ptTranslations from '../translations/stripes-components/pt_BR.json';
import ruTranslations from '../translations/stripes-components/ru.json';
import svTranslations from '../translations/stripes-components/sv.json';


// mimics the StripesTranslationPlugin in @folio/stripes-core
function prefixKeys(obj) {
Expand All @@ -44,11 +47,13 @@ const messages = {
hu: prefixKeys(huTranslations),
it: prefixKeys(itTranslations),
pt: prefixKeys(ptTranslations),
ru: prefixKeys(ruTranslations),
sv: prefixKeys(svTranslations),
};

// Set intl configuration
setIntlConfig({
locales: ['ar', 'ca', 'da', 'de', 'en', 'es', 'fr', 'hu', 'it', 'pt'],
locales: ['ar', 'ca', 'da', 'de', 'en', 'es', 'fr', 'hu', 'it', 'pt', 'ru', 'sv'],
defaultLocale: 'en',
getMessages: (locale) => messages[locale]
});
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Add link icon. Refs STCOM-852.
* `<MultiColumnList>` add ability to focus component if content data is empty. Refs STCOM-851.
* Expose getLocaleDateFormat Datepicker util. Refs STCOM-854.
* Fix issue with misaligned dates/weekdays in Datepicker Calendar. Refs STCOM-849

## [9.2.0](https://github.com/folio-org/stripes-components/tree/v9.2.0) (2021-06-08)
[Full Changelog](https://github.com/folio-org/stripes-components/compare/v9.1.0...v9.2.0)
Expand Down
55 changes: 42 additions & 13 deletions lib/Datepicker/Calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import MonthSelect from './MonthSelect';
import css from './Calendar.css';

import staticFirstWeekday from './staticFirstWeekDay';
import staticRegions from './staticLangCountryCodes';

const moment = extendMoment(Moment);

function getCalendar(year, month) {
function getCalendar(year, month, offset) {
const startDate = moment([year, month]);
const firstDay = moment(startDate).startOf('month');
const endDay = moment(startDate).endOf('month');
Expand All @@ -36,8 +37,8 @@ function getCalendar(year, month) {
if (weeks.indexOf(ref) < 0) {
weeks.push(mo.week());
const endClone = moment(mo);
rowStartArray.push(mo.weekday(0));
rowEndArray.push(endClone.weekday(6));
rowStartArray.push(mo.weekday(offset + 0));
rowEndArray.push(endClone.weekday(offset + 6));
}
});

Expand Down Expand Up @@ -119,7 +120,7 @@ class Calendar extends React.Component {
constructor(props) {
super(props);

moment.locale(this.props.locale);
moment.locale(this.props.intl.locale || this.props.locale);

const { selectedDate, dateFormat } = this.props;

Expand All @@ -135,6 +136,27 @@ class Calendar extends React.Component {
cursorDate = new moment(); // eslint-disable-line new-cap
}

// if the stripes locale has no region (only 2 letters), it needs to be normalized to a
// common form of {language}-{region} ex: "en-SE" (english spoken in Sweden)
// We adjust it by mapping from a set of common default regions (staticRegions);
// the first weekday in calendar rendering is derived from region.
// Hopefully it will be implemented in browser Intl API soon..
// but until then...

let dayOffset = 0;
let adjustedLocale = props.intl.locale || props.locale;
if (adjustedLocale.length === 2) {
const regionDefault = staticRegions[adjustedLocale];
adjustedLocale = `${adjustedLocale}-${regionDefault}`;
}

// if moment doesn't have the requested locale from above (intl/stripes), it falls back to 'en'. If this
// is the case, we need to set an offset value for correct calendar day rendering -
// otherwise, the calendar columns will be off, resulting misaligned weekdays/calendar days.
if (moment.locale() === 'en') {
dayOffset = getFirstWeekday(adjustedLocale);
}

const base = new moment(cursorDate); // eslint-disable-line new-cap
const month = base.month();
const year = base.year();
Expand All @@ -147,17 +169,22 @@ class Calendar extends React.Component {
date: this.selectedMoment,
month,
year,
calendar: getCalendar(year, month)
calendar: getCalendar(year, month),
dayOffset,
};

this.weekDays = getWeekDays(props.intl);
this.months = getMonths(props.intl);
this.firstWeekDay = getFirstWeekday(props.intl.locale);
this.firstWeekDay = getFirstWeekday(adjustedLocale);
this.firstField = props.firstFieldRef;
this.calendarGrid = React.createRef();
}

static getDerivedStateFromProps(nextProps, prevState) {
const {
dayOffset
} = prevState;

// When the selected date has changed, update the state with it
let stateUpdate;
if (nextProps.selectedDate !== prevState.selectedDate) {
Expand All @@ -172,7 +199,7 @@ class Calendar extends React.Component {
date: moDate,
month,
year,
calendar: getCalendar(year, month),
calendar: getCalendar(year, month, dayOffset),
selectedDate: nextProps.selectedDate,
dateFormat: nextProps.dateFormat,
};
Expand All @@ -185,7 +212,7 @@ class Calendar extends React.Component {
date: fallbackDate,
month,
year,
calendar: getCalendar(year, month),
calendar: getCalendar(year, month, dayOffset),
selectedDate: nextProps.selectedDate,
dateFormat: nextProps.dateFormat,
};
Expand All @@ -195,7 +222,7 @@ class Calendar extends React.Component {
if (stateUpdate) {
const newState = prevState;
Object.assign(newState, stateUpdate);
newState.calendar = getCalendar(newState.year, newState.month);
newState.calendar = getCalendar(newState.year, newState.month, dayOffset);
return newState;
} else {
return null;
Expand Down Expand Up @@ -271,7 +298,7 @@ class Calendar extends React.Component {
newState.month = newState.cursorDate.month();
newState.year = newState.cursorDate.year();
if (newState.year !== oldState.year || newState.month !== oldState.month) {
newState.calendar = getCalendar(newState.year, newState.month);
newState.calendar = getCalendar(newState.year, newState.month, oldState.dayOffset);
}
return newState;
}, () => {
Expand Down Expand Up @@ -325,6 +352,7 @@ class Calendar extends React.Component {
const month = parseInt(e.target.value, 10);

this.setState(curState => {
const { dayOffset } = curState;
let cursorDate = '';
if (month === this.selectedMoment?.month()) {
cursorDate = this.selectedMoment;
Expand All @@ -333,7 +361,7 @@ class Calendar extends React.Component {
}
return {
month,
calendar: getCalendar(curState.year, month),
calendar: getCalendar(curState.year, month, dayOffset),
cursorDate,
};
});
Expand All @@ -345,7 +373,7 @@ class Calendar extends React.Component {
if (new moment(year, 'YYYY', true).isValid()) { // eslint-disable-line new-cap
this.setState(curState => ({
year,
calendar: getCalendar(year, curState.month),
calendar: getCalendar(year, curState.month, curState.dayOffset),
}));
}
}
Expand All @@ -359,14 +387,15 @@ class Calendar extends React.Component {

moveDate = (op, unit) => {
this.setState(curState => {
const { dayOffset } = curState;
const newDate = curState.date[op](1, unit);
const month = newDate.month();
const year = newDate.year();
return {
date: newDate,
month,
year,
calendar: getCalendar(year, month)
calendar: getCalendar(year, month, dayOffset)
};
});
}
Expand Down
151 changes: 151 additions & 0 deletions lib/Datepicker/staticLangCountryCodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// Export a 'default' mapping using ISO-396-1 culture codes.
// This is used to convert 2-letter locales (language-only) to 4-letter locales.
// containing region information (used to derive first-day-of-week)

export default {
af: 'ZA',
sq: 'AL',
gsw: 'FR',
am: 'ET',
ar: 'SA',
hy: 'AM',
as: 'IN',
az: 'AZ',
bn: 'IN',
ba: 'RU',
eu: 'ES',
be: 'BY',
bs: 'BA',
br: 'FR',
bg: 'BG',
my: 'MM',
ca: 'ES',
ku: 'IQ',
chr: 'US',
zh: 'CN',
co: 'FR',
hr: 'HR',
cs: 'CZ',
da: 'DK',
prs: 'AF',
dv: 'MV',
nl: 'NL',
dz: 'BT',
bin: 'NG',
en: 'US',
et: 'EE',
fo: 'FO',
fil: 'PH',
fi: 'FI',
fr: 'FR',
fy: 'NL',
ff: 'NG',
gl: 'ES',
ka: 'GE',
de: 'DE',
el: 'GR',
kl: 'GL',
gn: 'PY',
gu: 'IN',
ha: 'NG',
haw: 'US',
he: 'IL',
hi: 'IN',
hu: 'HU',
ibb: 'NG',
is: 'IS',
ig: 'NG',
id: 'ID',
iu: 'CA',
ga: 'IE',
xh: 'ZA',
zu: 'ZA',
it: 'IT',
ja: 'JP',
kn: 'IN',
kr: 'NG',
ks: 'IN',
kk: 'KZ',
km: 'KH',
quc: 'GT',
rw: 'RW',
sw: 'KE',
kok: 'IN',
ko: 'KR',
ky: 'KG',
lo: 'LA',
la: '001',
lv: 'LV',
lt: 'LT',
dsb: 'DE',
lb: 'LU',
mk: 'MK',
ms: 'MY',
ml: 'IN',
mt: 'MT',
mni: 'IN',
mi: 'NZ',
arn: 'CL',
mr: 'IN',
moh: 'CA',
mn: 'MN',
ne: 'NP',
nb: 'NO',
nn: 'NO',
oc: 'FR',
or: 'IN',
om: 'ET',
pap: '029',
ps: 'AF',
fa: 'IR',
pl: 'PL',
pt: 'PT',
pa: 'IN',
quz: 'BO',
ro: 'RO',
rm: 'CH',
ru: 'RU',
sah: 'RU',
smn: 'FI',
smj: 'SE',
se: 'NO',
sms: 'FI',
sma: 'SE',
sa: 'IN',
gd: 'GB',
sr: 'RS',
nso: 'ZA',
tn: 'ZA',
sd: 'PK',
si: 'LK',
sk: 'SK',
sl: 'SI',
so: 'SO',
st: 'ZA',
es: 'ES',
sv: 'SE',
syr: 'SY',
tg: 'TJ',
tzm: 'DZ',
ta: 'IN',
tt: 'RU',
te: 'IN',
th: 'TH',
bo: 'CN',
ti: 'ER',
ts: 'ZA',
tr: 'TR',
tk: 'TM',
uk: 'UA',
hsb: 'DE',
ur: 'PK',
ug: 'CN',
uz: 'UZ',
ve: 'ZA',
vi: 'VN',
cy: 'GB',
wo: 'SN',
ii: 'CN',
yi: '001',
yo: 'NG'
};

0 comments on commit 54ccca4

Please sign in to comment.