@dhis2-ui/calendar 10.16.2 → 10.16.3-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -9
- package/src/__e2e__/calendar-input.e2e.stories.js +22 -0
- package/src/calendar/calendar-container.js +99 -0
- package/src/calendar/calendar-table-cell.js +97 -0
- package/src/calendar/calendar-table-days-header.js +40 -0
- package/src/calendar/calendar-table.js +74 -0
- package/src/calendar/calendar.js +104 -0
- package/src/calendar/navigation-container.js +295 -0
- package/src/calendar-input/__tests__/calendar-input.test.js +344 -0
- package/src/calendar-input/calendar-input.js +262 -0
- package/src/features/supports_calendar_clear_button/supports_calendar_clear_button.js +64 -0
- package/src/features/supports_calendar_clear_button.feature +23 -0
- package/src/features/supports_ethiopic_calendar/supports_ethiopic_calendar.js +61 -0
- package/src/features/supports_ethiopic_calendar.feature +20 -0
- package/src/features/supports_gregorian_calendar/supports_gregorian_calendar.js +62 -0
- package/src/features/supports_gregorian_calendar.feature +19 -0
- package/src/features/supports_islamic_calendar/supports_islamic_calendar.js +17 -0
- package/src/features/supports_islamic_calendar.feature +5 -0
- package/src/features/supports_nepali_calendar/supports_nepali_calendar.js +60 -0
- package/src/features/supports_nepali_calendar.feature +19 -0
- package/src/index.js +2 -0
- package/src/locales/en/translations.json +6 -0
- package/src/locales/index.js +16 -0
- package/src/stories/calendar-input.prod.stories.js +255 -0
- package/src/stories/calendar-story-wrapper.js +161 -0
- package/src/stories/calendar.prod.stories.js +91 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useDatePicker,
|
|
3
|
+
useResolvedDirection,
|
|
4
|
+
validateDateString,
|
|
5
|
+
} from '@dhis2/multi-calendar-dates'
|
|
6
|
+
import { Button } from '@dhis2-ui/button'
|
|
7
|
+
import { InputField } from '@dhis2-ui/input'
|
|
8
|
+
import { Layer } from '@dhis2-ui/layer'
|
|
9
|
+
import { Popper } from '@dhis2-ui/popper'
|
|
10
|
+
import cx from 'classnames'
|
|
11
|
+
import PropTypes from 'prop-types'
|
|
12
|
+
import React, { useRef, useState, useMemo, useEffect } from 'react'
|
|
13
|
+
import { CalendarContainer } from '../calendar/calendar-container.js'
|
|
14
|
+
import i18n from '../locales/index.js'
|
|
15
|
+
|
|
16
|
+
const offsetModifier = {
|
|
17
|
+
name: 'offset',
|
|
18
|
+
options: {
|
|
19
|
+
offset: [0, 2],
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const CalendarInput = ({
|
|
24
|
+
onDateSelect: parentOnDateSelect,
|
|
25
|
+
calendar,
|
|
26
|
+
date,
|
|
27
|
+
dir,
|
|
28
|
+
locale,
|
|
29
|
+
numberingSystem,
|
|
30
|
+
weekDayFormat = 'narrow',
|
|
31
|
+
width = '300px',
|
|
32
|
+
cellSize = '32px',
|
|
33
|
+
clearable,
|
|
34
|
+
minDate,
|
|
35
|
+
maxDate,
|
|
36
|
+
format,
|
|
37
|
+
strictValidation,
|
|
38
|
+
inputWidth,
|
|
39
|
+
dataTest = 'dhis2-uiwidgets-calendar-inputfield',
|
|
40
|
+
pastOnly,
|
|
41
|
+
...rest
|
|
42
|
+
} = {}) => {
|
|
43
|
+
const ref = useRef()
|
|
44
|
+
const calendarRef = useRef()
|
|
45
|
+
const popperRef = useRef()
|
|
46
|
+
const [open, setOpen] = useState(false)
|
|
47
|
+
const [partialDate, setPartialDate] = useState(date)
|
|
48
|
+
|
|
49
|
+
useEffect(() => setPartialDate(date), [date])
|
|
50
|
+
|
|
51
|
+
const useDatePickerOptions = useMemo(
|
|
52
|
+
() => ({
|
|
53
|
+
calendar,
|
|
54
|
+
locale,
|
|
55
|
+
numberingSystem,
|
|
56
|
+
weekDayFormat,
|
|
57
|
+
pastOnly,
|
|
58
|
+
}),
|
|
59
|
+
[calendar, locale, numberingSystem, weekDayFormat, pastOnly]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const onChooseDate = (date, validationOptions) => {
|
|
63
|
+
if (!date) {
|
|
64
|
+
parentOnDateSelect?.({
|
|
65
|
+
calendarDateString: null,
|
|
66
|
+
validation: { valid: true },
|
|
67
|
+
})
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const validation = validateDateString(date, validationOptions)
|
|
72
|
+
parentOnDateSelect?.({
|
|
73
|
+
calendarDateString: date,
|
|
74
|
+
validation,
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const validationOptions = useMemo(
|
|
79
|
+
() => ({
|
|
80
|
+
calendar,
|
|
81
|
+
format,
|
|
82
|
+
minDateString: minDate,
|
|
83
|
+
maxDateString: maxDate,
|
|
84
|
+
strictValidation,
|
|
85
|
+
}),
|
|
86
|
+
[calendar, format, maxDate, minDate, strictValidation]
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
const pickerResults = useDatePicker({
|
|
90
|
+
onDateSelect: (result) => {
|
|
91
|
+
onChooseDate(result.calendarDateString, validationOptions)
|
|
92
|
+
setOpen(false)
|
|
93
|
+
},
|
|
94
|
+
date,
|
|
95
|
+
...validationOptions,
|
|
96
|
+
options: useDatePickerOptions,
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const handleChange = (e) => {
|
|
100
|
+
setOpen(false)
|
|
101
|
+
setPartialDate(e.value)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const handleBlur = (_, e) => {
|
|
105
|
+
if (
|
|
106
|
+
e.relatedTarget &&
|
|
107
|
+
(calendarRef.current?.contains(e.relatedTarget) ||
|
|
108
|
+
popperRef.current === e.relatedTarget)
|
|
109
|
+
) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
onChooseDate(partialDate, validationOptions)
|
|
114
|
+
setOpen(false)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const onFocus = () => {
|
|
118
|
+
setOpen(true)
|
|
119
|
+
rest?.onFocus?.()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const languageDirection = useResolvedDirection(dir, locale)
|
|
123
|
+
|
|
124
|
+
const calendarProps = useMemo(
|
|
125
|
+
() => ({
|
|
126
|
+
date,
|
|
127
|
+
width,
|
|
128
|
+
cellSize,
|
|
129
|
+
isValid: pickerResults.isValid,
|
|
130
|
+
calendarWeekDays: pickerResults.calendarWeekDays,
|
|
131
|
+
weekDayLabels: pickerResults.weekDayLabels,
|
|
132
|
+
currMonth: pickerResults.currMonth,
|
|
133
|
+
currYear: pickerResults.currYear,
|
|
134
|
+
nextMonth: pickerResults.nextMonth,
|
|
135
|
+
nextYear: pickerResults.nextYear,
|
|
136
|
+
prevMonth: pickerResults.prevMonth,
|
|
137
|
+
prevYear: pickerResults.prevYear,
|
|
138
|
+
navigateToYear: pickerResults.navigateToYear,
|
|
139
|
+
navigateToMonth: pickerResults.navigateToMonth,
|
|
140
|
+
months: pickerResults.months,
|
|
141
|
+
years: pickerResults.years,
|
|
142
|
+
languageDirection,
|
|
143
|
+
}),
|
|
144
|
+
[cellSize, date, pickerResults, width, languageDirection]
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<>
|
|
149
|
+
<div className="calendar-input-wrapper" ref={ref}>
|
|
150
|
+
<InputField
|
|
151
|
+
label={i18n.t('Pick a date')}
|
|
152
|
+
{...rest}
|
|
153
|
+
dataTest={dataTest}
|
|
154
|
+
type="text"
|
|
155
|
+
onFocus={onFocus}
|
|
156
|
+
value={partialDate}
|
|
157
|
+
onChange={handleChange}
|
|
158
|
+
onBlur={handleBlur}
|
|
159
|
+
inputWidth={inputWidth}
|
|
160
|
+
/>
|
|
161
|
+
{clearable && (
|
|
162
|
+
<div
|
|
163
|
+
className={cx('calendar-clear-button', {
|
|
164
|
+
'with-icon':
|
|
165
|
+
rest.valid ||
|
|
166
|
+
rest.error ||
|
|
167
|
+
rest.warning ||
|
|
168
|
+
rest.loading,
|
|
169
|
+
'with-dense-wrapper': rest.dense,
|
|
170
|
+
})}
|
|
171
|
+
>
|
|
172
|
+
<Button
|
|
173
|
+
dataTest="calendar-clear-button"
|
|
174
|
+
secondary
|
|
175
|
+
small
|
|
176
|
+
onClick={() => onChooseDate(null)}
|
|
177
|
+
type="button"
|
|
178
|
+
>
|
|
179
|
+
{i18n.t('Clear')}
|
|
180
|
+
</Button>
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
</div>
|
|
184
|
+
{open && (
|
|
185
|
+
<Layer onBackdropClick={() => setOpen(false)}>
|
|
186
|
+
<Popper
|
|
187
|
+
reference={ref}
|
|
188
|
+
placement="bottom-start"
|
|
189
|
+
modifiers={[offsetModifier]}
|
|
190
|
+
onFirstUpdate={(component) => {
|
|
191
|
+
popperRef.current = component?.elements?.popper
|
|
192
|
+
}}
|
|
193
|
+
>
|
|
194
|
+
<CalendarContainer
|
|
195
|
+
{...calendarProps}
|
|
196
|
+
calendarRef={calendarRef}
|
|
197
|
+
/>
|
|
198
|
+
</Popper>
|
|
199
|
+
</Layer>
|
|
200
|
+
)}
|
|
201
|
+
|
|
202
|
+
<style jsx>
|
|
203
|
+
{`
|
|
204
|
+
.calendar-input-wrapper {
|
|
205
|
+
position: relative;
|
|
206
|
+
width: ${inputWidth};
|
|
207
|
+
}
|
|
208
|
+
.calendar-clear-button {
|
|
209
|
+
position: absolute;
|
|
210
|
+
inset-inline-end: ${rest.error || rest.warning
|
|
211
|
+
? '36px'
|
|
212
|
+
: '6px'};
|
|
213
|
+
inset-block-start: 27px;
|
|
214
|
+
}
|
|
215
|
+
.calendar-clear-button.with-icon {
|
|
216
|
+
inset-inline-end: 36px;
|
|
217
|
+
}
|
|
218
|
+
.calendar-clear-button.with-dense-wrapper {
|
|
219
|
+
inset-block-start: 23px;
|
|
220
|
+
}
|
|
221
|
+
`}
|
|
222
|
+
</style>
|
|
223
|
+
</>
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
CalendarInput.propTypes = {
|
|
228
|
+
/** the calendar to use such gregory, ethiopic, nepali - full supported list here: https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/calendars.ts */
|
|
229
|
+
calendar: PropTypes.any.isRequired,
|
|
230
|
+
/** Called with signature `(null)` \|\| `({ dateCalendarString: string, validation: { error: boolean, warning: boolean, validationText: string} })` with `dateCalendarString` being the stringified date in the specified calendar in the format `yyyy-MM-dd` */
|
|
231
|
+
onDateSelect: PropTypes.func.isRequired,
|
|
232
|
+
/** the size of a single cell in the table forming the calendar */
|
|
233
|
+
cellSize: PropTypes.string,
|
|
234
|
+
/** Whether the clear button is displayed */
|
|
235
|
+
clearable: PropTypes.bool,
|
|
236
|
+
/** 'data-test' attribute of `InputField` component */
|
|
237
|
+
dataTest: PropTypes.string,
|
|
238
|
+
/** the currently selected date using an iso-like format YYYY-MM-DD, in the calendar system provided (not iso8601) */
|
|
239
|
+
date: PropTypes.string,
|
|
240
|
+
/** the direction of the library - internally the library will use rtl for rtl-languages but this can be overridden here for more control */
|
|
241
|
+
dir: PropTypes.oneOf(['ltr', 'rtl']),
|
|
242
|
+
/** The date format to use either `YYYY-MM-DD` or `DD-MM-YYYY` */
|
|
243
|
+
format: PropTypes.oneOf(['YYYY-MM-DD', 'DD-MM-YYYY']),
|
|
244
|
+
/** the width of input field */
|
|
245
|
+
inputWidth: PropTypes.string,
|
|
246
|
+
/** any valid locale - if none provided, the internal library will fallback to the user locale (more info here: https://github.com/dhis2/multi-calendar-dates/blob/main/src/hooks/internal/useResolvedLocaleOptions.ts#L15) */
|
|
247
|
+
locale: PropTypes.string,
|
|
248
|
+
/** The maximum selectable date */
|
|
249
|
+
maxDate: PropTypes.string,
|
|
250
|
+
/** The minimum selectable date */
|
|
251
|
+
minDate: PropTypes.string,
|
|
252
|
+
/** numbering system to use - full list here https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/numberingSystems.ts */
|
|
253
|
+
numberingSystem: PropTypes.string,
|
|
254
|
+
/** When true, only shows years in the past (current year and earlier) */
|
|
255
|
+
pastOnly: PropTypes.bool,
|
|
256
|
+
/** Whether to use strict validation by showing errors for out-of-range dates when enabled (default), and warnings when disabled */
|
|
257
|
+
strictValidation: PropTypes.bool,
|
|
258
|
+
/** the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow) */
|
|
259
|
+
weekDayFormat: PropTypes.oneOf(['narrow', 'short', 'long']),
|
|
260
|
+
/** the width of the calendar component */
|
|
261
|
+
width: PropTypes.string,
|
|
262
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given(
|
|
4
|
+
'a "{word}" calendar is rendered with a selected date "{word}"',
|
|
5
|
+
(calendar, initialDate) => {
|
|
6
|
+
cy.visitStory(
|
|
7
|
+
'CalendarInputTesting',
|
|
8
|
+
'Test Calendar With Clear Button',
|
|
9
|
+
{
|
|
10
|
+
qs: {
|
|
11
|
+
initialDate,
|
|
12
|
+
calendar,
|
|
13
|
+
},
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
cy.get('[data-test="storybook-calendar-date-value"]').should(
|
|
18
|
+
'have.text',
|
|
19
|
+
initialDate
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
Then('we should be able to clear it', () => {
|
|
25
|
+
cy.get(`[data-test="calendar-clear-button"]`).click()
|
|
26
|
+
cy.get('[data-test="storybook-calendar-date-value"]').should(
|
|
27
|
+
'have.text',
|
|
28
|
+
'undefined'
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
Then('show the current month afterwards', () => {
|
|
33
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"]').click()
|
|
34
|
+
cy.get('.isToday').should('be.visible')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
Then("allow selecting today's date", () => {
|
|
38
|
+
cy.get('.isToday')
|
|
39
|
+
.parent()
|
|
40
|
+
.invoke('attr', 'data-test')
|
|
41
|
+
.then((todayDate) => {
|
|
42
|
+
cy.get('.isToday').click()
|
|
43
|
+
cy.get('[data-test="storybook-calendar-date-value"]').should(
|
|
44
|
+
'have.text',
|
|
45
|
+
todayDate
|
|
46
|
+
)
|
|
47
|
+
cy.get(
|
|
48
|
+
'[data-test="dhis2-uiwidgets-calendar-inputfield"] input'
|
|
49
|
+
).should('have.value', todayDate)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
Then('highlight today as the selected date', () => {
|
|
54
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"]').click()
|
|
55
|
+
cy.get('.isToday')
|
|
56
|
+
.parent()
|
|
57
|
+
.invoke('attr', 'data-test')
|
|
58
|
+
.then((todayDate) => {
|
|
59
|
+
cy.get('.isSelected').should(
|
|
60
|
+
'have.text',
|
|
61
|
+
Number(todayDate.split('-')[2]).toString()
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Feature: The Calendar allows clearing the selection
|
|
2
|
+
|
|
3
|
+
Scenario: Clear the selection in the Gregorian calendar
|
|
4
|
+
Given a "gregory" calendar is rendered with a selected date "2021-10-13"
|
|
5
|
+
Then we should be able to clear it
|
|
6
|
+
And show the current month afterwards
|
|
7
|
+
And allow selecting today's date
|
|
8
|
+
And highlight today as the selected date
|
|
9
|
+
|
|
10
|
+
Scenario: Clear the selection in the Ethiopic calendar
|
|
11
|
+
Given a "ethiopic" calendar is rendered with a selected date "2014-02-03"
|
|
12
|
+
Then we should be able to clear it
|
|
13
|
+
And show the current month afterwards
|
|
14
|
+
And allow selecting today's date
|
|
15
|
+
And highlight today as the selected date
|
|
16
|
+
|
|
17
|
+
Scenario: Clear the selection in the Nepali calendar
|
|
18
|
+
Given a "nepali" calendar is rendered with a selected date "2078-06-27"
|
|
19
|
+
Then we should be able to clear it
|
|
20
|
+
And show the current month afterwards
|
|
21
|
+
And allow selecting today's date
|
|
22
|
+
And highlight today as the selected date
|
|
23
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('an Ethiopic calendar is rendered in {word}', (language) => {
|
|
4
|
+
cy.visitStory('CalendarInputTesting', `Ethiopic With ${language}`)
|
|
5
|
+
|
|
6
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"]').click()
|
|
7
|
+
cy.get('[data-test=calendar]').should('be.visible')
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
Then('days should be rendered in "{word}"', (language) => {
|
|
11
|
+
const days =
|
|
12
|
+
language === 'amharic'
|
|
13
|
+
? ['ሰኞ', 'ማክሰ', 'ረቡዕ', 'ሐሙስ', 'ዓርብ', 'ቅዳሜ', 'እሑድ']
|
|
14
|
+
: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
|
15
|
+
|
|
16
|
+
days.forEach((day) => {
|
|
17
|
+
cy.contains(day).should('be.visible')
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
Then('months should be rendered in "{word}" with navigation', (language) => {
|
|
22
|
+
const months =
|
|
23
|
+
language === 'amharic'
|
|
24
|
+
? { current: 'ጥቅምት', previous: 'መስከረም', next: 'ኅዳር' }
|
|
25
|
+
: { current: 'Tekemt', previous: 'Meskerem', next: 'Hedar' }
|
|
26
|
+
|
|
27
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
28
|
+
'have.text',
|
|
29
|
+
months.current
|
|
30
|
+
)
|
|
31
|
+
cy.get('[data-test="calendar-next-month"]').click()
|
|
32
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
33
|
+
'have.text',
|
|
34
|
+
months.next
|
|
35
|
+
)
|
|
36
|
+
cy.get('[data-test="calendar-previous-month"]').click()
|
|
37
|
+
cy.get('[data-test="calendar-previous-month"]').click()
|
|
38
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
39
|
+
'have.text',
|
|
40
|
+
months.previous
|
|
41
|
+
)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
Then('the era should not be displayed in the year', () => {
|
|
45
|
+
cy.get('[data-test="calendar-year-select"] option:selected').should(
|
|
46
|
+
'not.contain.text',
|
|
47
|
+
'ERA'
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
Then('we should be able to select a day', () => {
|
|
52
|
+
const date = '2014-02-03'
|
|
53
|
+
cy.get(`[data-test="${date}"]`).click()
|
|
54
|
+
|
|
55
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"] input').should(
|
|
56
|
+
'have.value',
|
|
57
|
+
date
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
cy.get('[data-test="storybook-calendar-result"]').should('have.text', date)
|
|
61
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Feature: The Calendar renders in the Ethiopic calendar system
|
|
2
|
+
|
|
3
|
+
Scenario: Display an Ethiopic calendar in Amharic
|
|
4
|
+
Given an Ethiopic calendar is rendered in "amharic"
|
|
5
|
+
Then days should be rendered in "amharic"
|
|
6
|
+
And months should be rendered in "amharic" with navigation
|
|
7
|
+
|
|
8
|
+
Scenario: Select a day in the Ethiopic calendar in Amharic
|
|
9
|
+
Given an Ethiopic calendar is rendered in "amharic"
|
|
10
|
+
Then we should be able to select a day
|
|
11
|
+
|
|
12
|
+
Scenario: Display an Ethiopic calendar in English
|
|
13
|
+
Given an Ethiopic calendar is rendered in "english"
|
|
14
|
+
Then days should be rendered in "english"
|
|
15
|
+
And months should be rendered in "english" with navigation
|
|
16
|
+
And the era should not be displayed in the year
|
|
17
|
+
|
|
18
|
+
Scenario: Select a day in the Ethiopic calendar in English
|
|
19
|
+
Given an Ethiopic calendar is rendered in English
|
|
20
|
+
Then we should be able to select a day
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('a Gregorian calendar is rendered in {word}', (language) => {
|
|
4
|
+
cy.visitStory('CalendarInputTesting', `Gregorian With ${language}`)
|
|
5
|
+
|
|
6
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"]').click()
|
|
7
|
+
cy.get('[data-test=calendar]').should('be.visible')
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
Then('days should be rendered in "{word}"', (language) => {
|
|
11
|
+
const days =
|
|
12
|
+
language === 'arabic'
|
|
13
|
+
? [
|
|
14
|
+
'الاثنين',
|
|
15
|
+
'الثلاثاء',
|
|
16
|
+
'الأربعاء',
|
|
17
|
+
'الخميس',
|
|
18
|
+
'الجمعة',
|
|
19
|
+
'السبت',
|
|
20
|
+
'الأحد',
|
|
21
|
+
]
|
|
22
|
+
: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
|
23
|
+
|
|
24
|
+
days.forEach((day) => {
|
|
25
|
+
cy.contains(day).should('be.visible')
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
Then('months should be rendered in "{word}" with navigation', (language) => {
|
|
30
|
+
const months =
|
|
31
|
+
language === 'english'
|
|
32
|
+
? { current: 'October', previous: 'September', next: 'November' }
|
|
33
|
+
: { current: 'أكتوبر', previous: 'سبتمبر', next: 'نوفمبر' }
|
|
34
|
+
|
|
35
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
36
|
+
'have.text',
|
|
37
|
+
months.current
|
|
38
|
+
)
|
|
39
|
+
cy.get('[data-test="calendar-next-month"]').click()
|
|
40
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
41
|
+
'have.text',
|
|
42
|
+
months.next
|
|
43
|
+
)
|
|
44
|
+
cy.get('[data-test="calendar-previous-month"]').click()
|
|
45
|
+
cy.get('[data-test="calendar-previous-month"]').click()
|
|
46
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
47
|
+
'have.text',
|
|
48
|
+
months.previous
|
|
49
|
+
)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
Then('we should be able to select a day', () => {
|
|
53
|
+
const date = '2021-10-13'
|
|
54
|
+
cy.get(`[data-test="${date}"]`).click()
|
|
55
|
+
|
|
56
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"] input').should(
|
|
57
|
+
'have.value',
|
|
58
|
+
date
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
cy.get('[data-test="storybook-calendar-result"]').should('have.text', date)
|
|
62
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Feature: The Calendar renders in the Gregorian calendar system
|
|
2
|
+
|
|
3
|
+
Scenario: Display a Gregorian calendar in arabic
|
|
4
|
+
Given a Gregorian calendar is rendered in "arabic"
|
|
5
|
+
Then days should be rendered in "arabic"
|
|
6
|
+
And months should be rendered in "arabic" with navigation
|
|
7
|
+
|
|
8
|
+
Scenario: Select a day in the Gregorian calendar in arabic
|
|
9
|
+
Given a Gregorian calendar is rendered in "arabic"
|
|
10
|
+
Then we should be able to select a day
|
|
11
|
+
|
|
12
|
+
Scenario: Display a Gregorian calendar in English
|
|
13
|
+
Given a Gregorian calendar is rendered in "english"
|
|
14
|
+
Then days should be rendered in "english"
|
|
15
|
+
And months should be rendered in "english" with navigation
|
|
16
|
+
|
|
17
|
+
Scenario: Select a day in the Gregorian calendar in English
|
|
18
|
+
Given a Gregorian calendar is rendered in English
|
|
19
|
+
Then we should be able to select a day
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('an Islamic calendar is rendered with Arabic locale', () => {
|
|
4
|
+
cy.visitStory('CalendarInputTesting', `Islamic With Arabic`)
|
|
5
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"]').click()
|
|
6
|
+
cy.get('[data-test=calendar]').should('be.visible')
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
Then('days should be rendered in Arabic', () => {
|
|
10
|
+
cy.contains('الأحد').should('be.visible')
|
|
11
|
+
cy.contains('السبت').should('be.visible')
|
|
12
|
+
cy.contains('الجمعة').should('be.visible')
|
|
13
|
+
cy.contains('الخميس').should('be.visible')
|
|
14
|
+
cy.contains('الأربعاء').should('be.visible')
|
|
15
|
+
cy.contains('الثلاثاء').should('be.visible')
|
|
16
|
+
cy.contains('الاثنين').should('be.visible')
|
|
17
|
+
})
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('a nepali calendar in "{word}" is rendered', (language) => {
|
|
4
|
+
cy.visitStory('CalendarInputTesting', `Nepali With ${language}`)
|
|
5
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"]', {
|
|
6
|
+
timeout: 10000,
|
|
7
|
+
}).click()
|
|
8
|
+
cy.get('[data-test=calendar]').should('be.visible')
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
Then('nepali days should be rendered in "{word}"', (language) => {
|
|
12
|
+
const days =
|
|
13
|
+
language === 'nepali'
|
|
14
|
+
? ['आइत', 'सोम', 'सोम', 'बुध', 'बिही', 'शुक्र', 'शनि']
|
|
15
|
+
: ['Som', 'Mangl', 'Budha', 'Bihi', 'Shukra', 'Shani', 'Aaita']
|
|
16
|
+
|
|
17
|
+
days.forEach((day) => {
|
|
18
|
+
cy.contains(day).should('be.visible')
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
Then('months should be rendered in "{word}" with navigation', (language) => {
|
|
23
|
+
//
|
|
24
|
+
|
|
25
|
+
const months =
|
|
26
|
+
language === 'nepali'
|
|
27
|
+
? { current: 'असोज', previous: 'भदौ', next: 'कार्तिक' }
|
|
28
|
+
: { current: 'Ashwin', previous: 'Bhadra', next: 'Kartik' }
|
|
29
|
+
|
|
30
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
31
|
+
'have.text',
|
|
32
|
+
months.current
|
|
33
|
+
)
|
|
34
|
+
cy.get('[data-test="calendar-next-month"]').click()
|
|
35
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
36
|
+
'have.text',
|
|
37
|
+
months.next
|
|
38
|
+
)
|
|
39
|
+
cy.get('[data-test="calendar-previous-month"]').click()
|
|
40
|
+
cy.get('[data-test="calendar-previous-month"]').click()
|
|
41
|
+
cy.get('[data-test="calendar-month-select"] option:selected').should(
|
|
42
|
+
'have.text',
|
|
43
|
+
months.previous
|
|
44
|
+
)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
Then('we should be able to select a day', () => {
|
|
48
|
+
const nepaliDate = '2078-06-27'
|
|
49
|
+
cy.get(`[data-test="${nepaliDate}"]`).click()
|
|
50
|
+
|
|
51
|
+
cy.get('[data-test="dhis2-uiwidgets-calendar-inputfield"] input').should(
|
|
52
|
+
'have.value',
|
|
53
|
+
nepaliDate
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
cy.get('[data-test="storybook-calendar-result"]').should(
|
|
57
|
+
'have.text',
|
|
58
|
+
nepaliDate
|
|
59
|
+
)
|
|
60
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Feature: The Calendar renders in Nepali calendar system
|
|
2
|
+
|
|
3
|
+
Scenario: Display a Nepali calendar in Nepali
|
|
4
|
+
Given a nepali calendar in "nepali" is rendered
|
|
5
|
+
Then nepali days should be rendered in "nepali"
|
|
6
|
+
And months should be rendered in "nepali" with navigation
|
|
7
|
+
|
|
8
|
+
Scenario: Select a day in the Nepali calendar in Nepali
|
|
9
|
+
Given a nepali calendar in "nepali" is rendered
|
|
10
|
+
Then we should be able to select a day
|
|
11
|
+
|
|
12
|
+
Scenario: Display a Nepali calendar in English
|
|
13
|
+
Given a nepali calendar in "english" is rendered
|
|
14
|
+
Then nepali days should be rendered in "english"
|
|
15
|
+
And months should be rendered in "english" with navigation
|
|
16
|
+
|
|
17
|
+
Scenario: Select a day in the Nepali calendar in English
|
|
18
|
+
Given a nepali calendar in "english" is rendered
|
|
19
|
+
Then we should be able to select a day
|
package/src/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//------------------------------------------------------------------------------
|
|
2
|
+
// <auto-generated>
|
|
3
|
+
// This code was generated by d2-i18n-generate.
|
|
4
|
+
//
|
|
5
|
+
// Changes to this file may cause incorrect behavior and will be lost if
|
|
6
|
+
// the code is regenerated.
|
|
7
|
+
// </auto-generated>
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
import i18n from '@dhis2/d2-i18n'
|
|
10
|
+
|
|
11
|
+
import enTranslations from './en/translations.json'
|
|
12
|
+
|
|
13
|
+
const namespace = 'default'
|
|
14
|
+
i18n.addResources('en', namespace, enTranslations)
|
|
15
|
+
|
|
16
|
+
export default i18n
|