From 1d7a341959a4c38455094874914d204a53438f8c Mon Sep 17 00:00:00 2001 From: Artur Yorsh <10753921+artyorsh@users.noreply.github.com> Date: Thu, 17 Oct 2019 16:49:22 +0300 Subject: [PATCH] feat(ui): calendar - start day of week --- src/date-fns/dateFnsDate.service.spec.ts | 3 +- src/date-fns/dateFnsDate.service.ts | 7 ++-- .../ui/calendar/calendar.component.tsx | 2 + .../service/nativeDate.service.spec.ts | 21 ++++++++-- .../ui/calendar/service/nativeDate.service.ts | 35 +++++++++++++---- src/framework/ui/index.ts | 10 ++++- src/playground/src/ui/screen/calendar/type.ts | 22 ++++++++++- .../calendarCustomLocale.component.tsx | 2 +- .../calendarStartDayOfWeek.component.tsx | 39 +++++++++++++++++++ .../src/ui/screen/showcases/calendar/index.ts | 1 + 10 files changed, 121 insertions(+), 21 deletions(-) create mode 100644 src/playground/src/ui/screen/showcases/calendar/calendarStartDayOfWeek.component.tsx diff --git a/src/date-fns/dateFnsDate.service.spec.ts b/src/date-fns/dateFnsDate.service.spec.ts index c3f2883de..cb059cc14 100644 --- a/src/date-fns/dateFnsDate.service.spec.ts +++ b/src/date-fns/dateFnsDate.service.spec.ts @@ -12,7 +12,7 @@ describe('@date-fns: service checks', () => { let dateService: DateService; beforeEach(() => { - dateService = new DateFnsService('en', null, null); + dateService = new DateFnsService('en', null); }); it('* should parse date according to the MM.dd.yyyy format', () => { @@ -37,7 +37,6 @@ describe('@date-fns: service checks', () => { beforeEach(() => { dateService = new DateFnsService( 'en', - null, { format: FORMAT, parseOptions: {}, diff --git a/src/date-fns/dateFnsDate.service.ts b/src/date-fns/dateFnsDate.service.ts index be3e8694c..477d76005 100644 --- a/src/date-fns/dateFnsDate.service.ts +++ b/src/date-fns/dateFnsDate.service.ts @@ -7,6 +7,7 @@ import { I18nConfig, NativeDateService, + NativeDateServiceOptions, } from 'react-native-ui-kitten'; // @ts-ignore import dateFnsParse, { default as rollupParse } from 'date-fns/parse'; @@ -16,7 +17,7 @@ import dateFnsFormat, { default as rollupFormat } from 'date-fns/format'; const parse = rollupParse || dateFnsParse; const formatDate = rollupFormat || dateFnsFormat; -export interface DateFnsOptions { +export interface DateFnsOptions extends NativeDateServiceOptions { format: string; parseOptions: {}; formatOptions: {}; @@ -28,8 +29,8 @@ export class DateFnsService extends NativeDateService { format: `DD/MM/YYYY`, }; - constructor(locale: string = 'en', i18n?: I18nConfig, options?: DateFnsOptions) { - super(locale, i18n); + constructor(locale: string = 'en', options?: DateFnsOptions) { + super(locale, options); this.options = options || this.options; } diff --git a/src/framework/ui/calendar/calendar.component.tsx b/src/framework/ui/calendar/calendar.component.tsx index 928ccf0fe..adca77752 100644 --- a/src/framework/ui/calendar/calendar.component.tsx +++ b/src/framework/ui/calendar/calendar.component.tsx @@ -62,6 +62,8 @@ export type CalendarElement = React.ReactElement>; * * @overview-example CalendarBounds * + * @overview-example CalendarStartDayOfWeek + * * @overview-example CalendarCustomLocale * * @example CalendarMoment diff --git a/src/framework/ui/calendar/service/nativeDate.service.spec.ts b/src/framework/ui/calendar/service/nativeDate.service.spec.ts index 6cd7918ce..66d6e0404 100644 --- a/src/framework/ui/calendar/service/nativeDate.service.spec.ts +++ b/src/framework/ui/calendar/service/nativeDate.service.spec.ts @@ -33,8 +33,8 @@ describe('@native-date: service checks', () => { expect((dateService).locale).toBe('en'); }); - it('* should be initialized with ru locale', () => { - dateService = new NativeDateService('zh', i18n); + it('* should be initialized with zh locale', () => { + dateService = new NativeDateService('zh', { i18n }); expect((dateService).locale).toBe('zh'); }); @@ -87,13 +87,18 @@ describe('@native-date: service checks', () => { expect(dateService.getFirstDayOfWeek()).toBe(0); }); + it('* should get custom first day of week if provided', () => { + dateService = new NativeDateService('en', { startDayOfWeek: 1 }); + expect(dateService.getFirstDayOfWeek()).toBe(1); + }); + it('* should get month name', () => { const month = new Date(2018, 5, 15); expect(dateService.getMonthName(month)).toBe('Jun'); }); it('* should get i18n month name', () => { - dateService = new NativeDateService('zh', i18n); + dateService = new NativeDateService('zh', { i18n }); const month = new Date(2018, 5, 15); expect(dateService.getMonthName(month, TranslationWidth.SHORT)).toBe('6月'); }); @@ -106,8 +111,16 @@ describe('@native-date: service checks', () => { expect(dateService.getDayOfWeekNames()).toEqual(EN.dayNames.short); }); + it('* should get day of week names', () => { + const startDayOfWeek = 1; + dateService = new NativeDateService('en', { startDayOfWeek }); + + const { [0]: startDayOfWeekName } = dateService.getDayOfWeekNames(); + expect(startDayOfWeekName).toEqual(EN.dayNames.short[startDayOfWeek]); + }); + it('* should get i18n day of week names', () => { - dateService = new NativeDateService('zh', i18n); + dateService = new NativeDateService('zh', { i18n}); expect(dateService.getDayOfWeekNames(TranslationWidth.SHORT)).toEqual(i18n.dayNames.short); }); diff --git a/src/framework/ui/calendar/service/nativeDate.service.ts b/src/framework/ui/calendar/service/nativeDate.service.ts index 98a3bbe11..41153ee4c 100644 --- a/src/framework/ui/calendar/service/nativeDate.service.ts +++ b/src/framework/ui/calendar/service/nativeDate.service.ts @@ -13,7 +13,16 @@ import { import { EN } from '../i18n/en'; export const LOCALE_DEFAULT = 'en'; -export const FIRST_DAY_OF_WEEK: number = 0; + +export interface NativeDateServiceOptions { + // 0 for Sunday, 1 for Monday, etc + startDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6; + i18n?: I18nConfig; +} + +const DEFAULT_OPTIONS: NativeDateServiceOptions = { + startDayOfWeek: 0, +}; /** * The `NativeDateService` is basic implementation of `DateService` using @@ -21,10 +30,13 @@ export const FIRST_DAY_OF_WEEK: number = 0; */ export class NativeDateService extends DateService { - constructor(locale: string = LOCALE_DEFAULT, i18n?: I18nConfig) { + protected options: NativeDateServiceOptions; + + constructor(locale: string = LOCALE_DEFAULT, options?: NativeDateServiceOptions) { super(); - super.setLocale(i18n ? locale : LOCALE_DEFAULT); - this.setFechaLocaleData(i18n || EN); + this.options = { ...DEFAULT_OPTIONS, ...options }; + super.setLocale(this.options.i18n ? locale : LOCALE_DEFAULT); + this.setFechaLocaleData(this.options.i18n || EN); } public setLocale(locale: string) { @@ -60,7 +72,7 @@ export class NativeDateService extends DateService { * and 0 if from sunday and so on. * */ public getFirstDayOfWeek(): number { - return FIRST_DAY_OF_WEEK; + return this.options.startDayOfWeek; } public getMonthName(date: Date, style: TranslationWidth = TranslationWidth.SHORT): string { @@ -74,7 +86,10 @@ export class NativeDateService extends DateService { } public getDayOfWeekNames(style: TranslationWidth = TranslationWidth.SHORT): string[] { - return this.getFechaDayNames(style); + const dayNames: string[] = this.getFechaDayNames(style); + + // avoid mutation of source array + return this.shiftDayOfWeekNames([...dayNames], this.options.startDayOfWeek); } public format(date: Date, format: string): string { @@ -172,7 +187,11 @@ export class NativeDateService extends DateService { return 'native'; } - private getFechaDayNames(style: TranslationWidth) { + protected shiftDayOfWeekNames(value: T[], offset: number): T[] { + return value.splice(offset).concat(value); + } + + private getFechaDayNames(style: TranslationWidth): string[] { switch (style) { case TranslationWidth.SHORT: return fecha.i18n.dayNamesShort; @@ -181,7 +200,7 @@ export class NativeDateService extends DateService { } } - private getFechaMonthNames(style: TranslationWidth) { + private getFechaMonthNames(style: TranslationWidth): string[] { switch (style) { case TranslationWidth.SHORT: return fecha.i18n.monthNamesShort; diff --git a/src/framework/ui/index.ts b/src/framework/ui/index.ts index 607a8db58..ae884f828 100644 --- a/src/framework/ui/index.ts +++ b/src/framework/ui/index.ts @@ -204,5 +204,11 @@ export { ViewPagerElement, } from './viewPager/viewPager.component'; export { DateService } from './calendar/service/date.service'; -export { NativeDateService } from './calendar/service/nativeDate.service'; -export { TranslationWidth, I18nConfig } from './calendar/i18n/type'; +export { + NativeDateService, + NativeDateServiceOptions, +} from './calendar/service/nativeDate.service'; +export { + TranslationWidth, + I18nConfig, +} from './calendar/i18n/type'; diff --git a/src/playground/src/ui/screen/calendar/type.ts b/src/playground/src/ui/screen/calendar/type.ts index cbbf0c4f7..70044bcb1 100644 --- a/src/playground/src/ui/screen/calendar/type.ts +++ b/src/playground/src/ui/screen/calendar/type.ts @@ -1,5 +1,8 @@ import moment from 'moment'; -import { CalendarViewModes } from 'react-native-ui-kitten'; +import { + CalendarViewModes, + NativeDateService, +} from 'react-native-ui-kitten'; import { MomentDateService } from '@ui-kitten/moment'; import { DateFnsService } from '@ui-kitten/date-fns'; import { @@ -81,6 +84,15 @@ const filterCalendar: ComponentShowcaseItem = { }, }; +const mondayCalendar: ComponentShowcaseItem = { + props: { + ...defaultCalendar.props, + dateService: new NativeDateService('en', { + startDayOfWeek: 1, + }), + }, +}; + const defaultSection: ComponentShowcaseSection = { title: 'Default', items: [ @@ -144,9 +156,17 @@ const filterSection: ComponentShowcaseSection = { ], }; +const startDayOfWeekSection: ComponentShowcaseSection = { + title: 'Start Day of Week', + items: [ + mondayCalendar, + ], +}; + export const calendarShowcase: ComponentShowcase = { sections: [ defaultSection, + // startDayOfWeekSection, // customItemSection, // momentSection, // dateFnsSection, diff --git a/src/playground/src/ui/screen/showcases/calendar/calendarCustomLocale.component.tsx b/src/playground/src/ui/screen/showcases/calendar/calendarCustomLocale.component.tsx index a23bd5312..821f169c9 100644 --- a/src/playground/src/ui/screen/showcases/calendar/calendarCustomLocale.component.tsx +++ b/src/playground/src/ui/screen/showcases/calendar/calendarCustomLocale.component.tsx @@ -23,7 +23,7 @@ export class CalendarCustomLocaleShowcase extends React.Component { date: new Date(), }; - dateService = new NativeDateService('zh', i18n); + dateService = new NativeDateService('zh', { i18n }); onSelect = (date) => { this.setState({ date }); diff --git a/src/playground/src/ui/screen/showcases/calendar/calendarStartDayOfWeek.component.tsx b/src/playground/src/ui/screen/showcases/calendar/calendarStartDayOfWeek.component.tsx new file mode 100644 index 000000000..859eefd1e --- /dev/null +++ b/src/playground/src/ui/screen/showcases/calendar/calendarStartDayOfWeek.component.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { StyleSheet } from 'react-native'; +import { + Calendar, + Layout, + NativeDateService, +} from 'react-native-ui-kitten'; + +export class CalendarStartDayOfWeekShowcase extends React.Component { + + state = { + date: new Date(), + }; + + dateService = new NativeDateService('en', { startDayOfWeek: 1 }); + + onSelect = (date) => { + this.setState({ date }); + }; + + render() { + return ( + + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + padding: 16, + minHeight: 376, + }, +}); diff --git a/src/playground/src/ui/screen/showcases/calendar/index.ts b/src/playground/src/ui/screen/showcases/calendar/index.ts index ddb4a14fb..71a5310d1 100644 --- a/src/playground/src/ui/screen/showcases/calendar/index.ts +++ b/src/playground/src/ui/screen/showcases/calendar/index.ts @@ -5,4 +5,5 @@ export { CalendarCustomLocaleShowcase } from './calendarCustomLocale.component'; export { CalendarFilterShowcase } from './calendarFilterShowcase.component'; export { CalendarMomentShowcase } from './calendarMoment.component'; export { CalendarSimpleUsageShowcase } from './calendarSimpleUsage.component'; +export { CalendarStartDayOfWeekShowcase } from './calendarStartDayOfWeek.component'; export { RangeCalendarSimpleUsageShowcase } from './rangeCalendarSimpleUsage.component';