diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e4f41429..b69db32f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# [10.4.0](https://github.com/dhis2/ui/compare/v10.3.1...v10.4.0) (2025-03-12)
+
+
+### Features
+
+* add year month selector to calendar component ([#1663](https://github.com/dhis2/ui/issues/1663)) ([b643b16](https://github.com/dhis2/ui/commit/b643b16cf927bca885d67eb5113639abf71c1ebe))
+
## [10.3.1](https://github.com/dhis2/ui/compare/v10.3.0...v10.3.1) (2025-03-06)
diff --git a/collections/forms/package.json b/collections/forms/package.json
index c128feae8..2226f3957 100644
--- a/collections/forms/package.json
+++ b/collections/forms/package.json
@@ -1,6 +1,6 @@
{
"name": "@dhis2/ui-forms",
- "version": "10.3.1",
+ "version": "10.4.0",
"main": "./build/cjs/index.js",
"module": "./build/es/index.js",
"sideEffects": [
@@ -35,15 +35,15 @@
},
"dependencies": {
"@dhis2/prop-types": "^3.1.2",
- "@dhis2-ui/button": "10.3.1",
- "@dhis2-ui/checkbox": "10.3.1",
- "@dhis2-ui/field": "10.3.1",
- "@dhis2-ui/file-input": "10.3.1",
- "@dhis2-ui/input": "10.3.1",
- "@dhis2-ui/radio": "10.3.1",
- "@dhis2-ui/select": "10.3.1",
- "@dhis2-ui/switch": "10.3.1",
- "@dhis2-ui/text-area": "10.3.1",
+ "@dhis2-ui/button": "10.4.0",
+ "@dhis2-ui/checkbox": "10.4.0",
+ "@dhis2-ui/field": "10.4.0",
+ "@dhis2-ui/file-input": "10.4.0",
+ "@dhis2-ui/input": "10.4.0",
+ "@dhis2-ui/radio": "10.4.0",
+ "@dhis2-ui/select": "10.4.0",
+ "@dhis2-ui/switch": "10.4.0",
+ "@dhis2-ui/text-area": "10.4.0",
"classnames": "^2.3.1",
"final-form": "^4.20.2",
"prop-types": "^15.7.2",
diff --git a/collections/ui/API.md b/collections/ui/API.md
index aef0aca27..6e0d5996b 100644
--- a/collections/ui/API.md
+++ b/collections/ui/API.md
@@ -227,6 +227,7 @@ import { Calendar } from '@dhis2/ui'
|dir|'ltr' │ 'rtl'|||the direction of the library - internally the library will use rtl for rtl-languages but this can be overridden here for more control|
|locale|string|||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)|
|numberingSystem|string|||numbering system to use - full list here https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/numberingSystems.ts|
+|pastOnly|boolean|||When true, only shows years in the past (current year and earlier)|
|timeZone|string|||the timeZone to use|
|weekDayFormat|'narrow' │ 'short' │ 'long'|``'narrow'``||the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow)|
|width|string|``'240px'``||the width of the calendar component|
@@ -260,6 +261,7 @@ import { CalendarInput } from '@dhis2/ui'
|maxDate|string|||The maximum selectable date|
|minDate|string|||The minimum selectable date|
|numberingSystem|string|||numbering system to use - full list here https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/numberingSystems.ts|
+|pastOnly|boolean|||When true, only shows years in the past (current year and earlier)|
|strictValidation|boolean|||Whether to use strict validation by showing errors for out-of-range dates when enabled (default), and warnings when disabled|
|weekDayFormat|'narrow' │ 'short' │ 'long'|||the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow)|
|width|string|||the width of the calendar component|
diff --git a/collections/ui/package.json b/collections/ui/package.json
index ffeede00a..aebd45df1 100644
--- a/collections/ui/package.json
+++ b/collections/ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@dhis2/ui",
- "version": "10.3.1",
+ "version": "10.4.0",
"main": "./build/cjs/index.js",
"module": "./build/es/index.js",
"exports": {
@@ -21,54 +21,54 @@
"build": "d2-app-scripts build"
},
"dependencies": {
- "@dhis2-ui/alert": "10.3.1",
- "@dhis2-ui/box": "10.3.1",
- "@dhis2-ui/button": "10.3.1",
- "@dhis2-ui/calendar": "10.3.1",
- "@dhis2-ui/card": "10.3.1",
- "@dhis2-ui/center": "10.3.1",
- "@dhis2-ui/checkbox": "10.3.1",
- "@dhis2-ui/chip": "10.3.1",
- "@dhis2-ui/cover": "10.3.1",
- "@dhis2-ui/css": "10.3.1",
- "@dhis2-ui/divider": "10.3.1",
- "@dhis2-ui/field": "10.3.1",
- "@dhis2-ui/file-input": "10.3.1",
- "@dhis2-ui/header-bar": "10.3.1",
- "@dhis2-ui/help": "10.3.1",
- "@dhis2-ui/input": "10.3.1",
- "@dhis2-ui/intersection-detector": "10.3.1",
- "@dhis2-ui/label": "10.3.1",
- "@dhis2-ui/layer": "10.3.1",
- "@dhis2-ui/legend": "10.3.1",
- "@dhis2-ui/loader": "10.3.1",
- "@dhis2-ui/logo": "10.3.1",
- "@dhis2-ui/menu": "10.3.1",
- "@dhis2-ui/modal": "10.3.1",
- "@dhis2-ui/node": "10.3.1",
- "@dhis2-ui/notice-box": "10.3.1",
- "@dhis2-ui/organisation-unit-tree": "10.3.1",
- "@dhis2-ui/pagination": "10.3.1",
- "@dhis2-ui/popover": "10.3.1",
- "@dhis2-ui/popper": "10.3.1",
- "@dhis2-ui/portal": "10.3.1",
- "@dhis2-ui/radio": "10.3.1",
- "@dhis2-ui/required": "10.3.1",
- "@dhis2-ui/segmented-control": "10.3.1",
- "@dhis2-ui/select": "10.3.1",
- "@dhis2-ui/selector-bar": "10.3.1",
- "@dhis2-ui/sharing-dialog": "10.3.1",
- "@dhis2-ui/switch": "10.3.1",
- "@dhis2-ui/tab": "10.3.1",
- "@dhis2-ui/table": "10.3.1",
- "@dhis2-ui/tag": "10.3.1",
- "@dhis2-ui/text-area": "10.3.1",
- "@dhis2-ui/tooltip": "10.3.1",
- "@dhis2-ui/transfer": "10.3.1",
- "@dhis2-ui/user-avatar": "10.3.1",
- "@dhis2/ui-constants": "10.3.1",
- "@dhis2/ui-forms": "10.3.1",
- "@dhis2/ui-icons": "10.3.1",
+ "@dhis2-ui/alert": "10.4.0",
+ "@dhis2-ui/box": "10.4.0",
+ "@dhis2-ui/button": "10.4.0",
+ "@dhis2-ui/calendar": "10.4.0",
+ "@dhis2-ui/card": "10.4.0",
+ "@dhis2-ui/center": "10.4.0",
+ "@dhis2-ui/checkbox": "10.4.0",
+ "@dhis2-ui/chip": "10.4.0",
+ "@dhis2-ui/cover": "10.4.0",
+ "@dhis2-ui/css": "10.4.0",
+ "@dhis2-ui/divider": "10.4.0",
+ "@dhis2-ui/field": "10.4.0",
+ "@dhis2-ui/file-input": "10.4.0",
+ "@dhis2-ui/header-bar": "10.4.0",
+ "@dhis2-ui/help": "10.4.0",
+ "@dhis2-ui/input": "10.4.0",
+ "@dhis2-ui/intersection-detector": "10.4.0",
+ "@dhis2-ui/label": "10.4.0",
+ "@dhis2-ui/layer": "10.4.0",
+ "@dhis2-ui/legend": "10.4.0",
+ "@dhis2-ui/loader": "10.4.0",
+ "@dhis2-ui/logo": "10.4.0",
+ "@dhis2-ui/menu": "10.4.0",
+ "@dhis2-ui/modal": "10.4.0",
+ "@dhis2-ui/node": "10.4.0",
+ "@dhis2-ui/notice-box": "10.4.0",
+ "@dhis2-ui/organisation-unit-tree": "10.4.0",
+ "@dhis2-ui/pagination": "10.4.0",
+ "@dhis2-ui/popover": "10.4.0",
+ "@dhis2-ui/popper": "10.4.0",
+ "@dhis2-ui/portal": "10.4.0",
+ "@dhis2-ui/radio": "10.4.0",
+ "@dhis2-ui/required": "10.4.0",
+ "@dhis2-ui/segmented-control": "10.4.0",
+ "@dhis2-ui/select": "10.4.0",
+ "@dhis2-ui/selector-bar": "10.4.0",
+ "@dhis2-ui/sharing-dialog": "10.4.0",
+ "@dhis2-ui/switch": "10.4.0",
+ "@dhis2-ui/tab": "10.4.0",
+ "@dhis2-ui/table": "10.4.0",
+ "@dhis2-ui/tag": "10.4.0",
+ "@dhis2-ui/text-area": "10.4.0",
+ "@dhis2-ui/tooltip": "10.4.0",
+ "@dhis2-ui/transfer": "10.4.0",
+ "@dhis2-ui/user-avatar": "10.4.0",
+ "@dhis2/ui-constants": "10.4.0",
+ "@dhis2/ui-forms": "10.4.0",
+ "@dhis2/ui-icons": "10.4.0",
"prop-types": "^15.7.2"
},
"peerDependencies": {
diff --git a/components/alert/package.json b/components/alert/package.json
index f058180b6..befdf6374 100644
--- a/components/alert/package.json
+++ b/components/alert/package.json
@@ -1,6 +1,6 @@
{
"name": "@dhis2-ui/alert",
- "version": "10.3.1",
+ "version": "10.4.0",
"description": "UI Alert",
"repository": {
"type": "git",
@@ -33,9 +33,9 @@
},
"dependencies": {
"@dhis2/prop-types": "^3.1.2",
- "@dhis2-ui/portal": "10.3.1",
- "@dhis2/ui-constants": "10.3.1",
- "@dhis2/ui-icons": "10.3.1",
+ "@dhis2-ui/portal": "10.4.0",
+ "@dhis2/ui-constants": "10.4.0",
+ "@dhis2/ui-icons": "10.4.0",
"classnames": "^2.3.1",
"prop-types": "^15.7.2"
},
diff --git a/components/box/package.json b/components/box/package.json
index fb08e8dd6..18d5c27b3 100644
--- a/components/box/package.json
+++ b/components/box/package.json
@@ -1,6 +1,6 @@
{
"name": "@dhis2-ui/box",
- "version": "10.3.1",
+ "version": "10.4.0",
"description": "UI Box",
"repository": {
"type": "git",
@@ -33,7 +33,7 @@
},
"dependencies": {
"@dhis2/prop-types": "^3.1.2",
- "@dhis2/ui-constants": "10.3.1",
+ "@dhis2/ui-constants": "10.4.0",
"classnames": "^2.3.1",
"prop-types": "^15.7.2"
},
diff --git a/components/button/package.json b/components/button/package.json
index d224f3a65..88b2cdcab 100644
--- a/components/button/package.json
+++ b/components/button/package.json
@@ -1,6 +1,6 @@
{
"name": "@dhis2-ui/button",
- "version": "10.3.1",
+ "version": "10.4.0",
"description": "UI Button",
"repository": {
"type": "git",
@@ -33,11 +33,11 @@
},
"dependencies": {
"@dhis2/prop-types": "^3.1.2",
- "@dhis2-ui/layer": "10.3.1",
- "@dhis2-ui/loader": "10.3.1",
- "@dhis2-ui/popper": "10.3.1",
- "@dhis2/ui-constants": "10.3.1",
- "@dhis2/ui-icons": "10.3.1",
+ "@dhis2-ui/layer": "10.4.0",
+ "@dhis2-ui/loader": "10.4.0",
+ "@dhis2-ui/popper": "10.4.0",
+ "@dhis2/ui-constants": "10.4.0",
+ "@dhis2/ui-icons": "10.4.0",
"classnames": "^2.3.1",
"prop-types": "^15.7.2"
},
diff --git a/components/calendar/API.md b/components/calendar/API.md
index 01eed66f8..26076fc96 100644
--- a/components/calendar/API.md
+++ b/components/calendar/API.md
@@ -21,6 +21,7 @@ import { Calendar } from '@dhis2/ui'
|dir|'ltr' │ 'rtl'|||the direction of the library - internally the library will use rtl for rtl-languages but this can be overridden here for more control|
|locale|string|||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)|
|numberingSystem|string|||numbering system to use - full list here https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/numberingSystems.ts|
+|pastOnly|boolean|||When true, only shows years in the past (current year and earlier)|
|timeZone|string|||the timeZone to use|
|weekDayFormat|'narrow' │ 'short' │ 'long'|``'narrow'``||the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow)|
|width|string|``'240px'``||the width of the calendar component|
@@ -54,6 +55,7 @@ import { CalendarInput } from '@dhis2/ui'
|maxDate|string|||The maximum selectable date|
|minDate|string|||The minimum selectable date|
|numberingSystem|string|||numbering system to use - full list here https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/numberingSystems.ts|
+|pastOnly|boolean|||When true, only shows years in the past (current year and earlier)|
|strictValidation|boolean|||Whether to use strict validation by showing errors for out-of-range dates when enabled (default), and warnings when disabled|
|weekDayFormat|'narrow' │ 'short' │ 'long'|||the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow)|
|width|string|||the width of the calendar component|
diff --git a/components/calendar/package.json b/components/calendar/package.json
index 5d3dfc33b..d05d1b551 100644
--- a/components/calendar/package.json
+++ b/components/calendar/package.json
@@ -1,6 +1,6 @@
{
"name": "@dhis2-ui/calendar",
- "version": "10.3.1",
+ "version": "10.4.0",
"description": "UI Calendar",
"repository": {
"type": "git",
@@ -33,15 +33,15 @@
"styled-jsx": "^4"
},
"dependencies": {
- "@dhis2-ui/button": "10.3.1",
- "@dhis2-ui/card": "10.3.1",
- "@dhis2-ui/input": "10.3.1",
- "@dhis2-ui/layer": "10.3.1",
- "@dhis2-ui/popper": "10.3.1",
- "@dhis2/multi-calendar-dates": "2.0.0",
+ "@dhis2-ui/button": "10.4.0",
+ "@dhis2-ui/card": "10.4.0",
+ "@dhis2-ui/input": "10.4.0",
+ "@dhis2-ui/layer": "10.4.0",
+ "@dhis2-ui/popper": "10.4.0",
+ "@dhis2/multi-calendar-dates": "2.1.0",
"@dhis2/prop-types": "^3.1.2",
- "@dhis2/ui-constants": "10.3.1",
- "@dhis2/ui-icons": "10.3.1",
+ "@dhis2/ui-constants": "10.4.0",
+ "@dhis2/ui-icons": "10.4.0",
"classnames": "^2.3.1",
"prop-types": "^15.7.2"
},
diff --git a/components/calendar/src/calendar-input/__tests__/calendar-input.test.js b/components/calendar/src/calendar-input/__tests__/calendar-input.test.js
index 3d91dbb67..7e08bbf0b 100644
--- a/components/calendar/src/calendar-input/__tests__/calendar-input.test.js
+++ b/components/calendar/src/calendar-input/__tests__/calendar-input.test.js
@@ -112,95 +112,104 @@ describe('Calendar Input', () => {
)
)
})
- it('should validate date in ethiopic calendar', async () => {
- const onDateSelectMock = jest.fn()
- const { getByTestId, findByText, queryByText } = render(
-
- )
+ it(
+ 'should validate date in ethiopic calendar',
+ async () => {
+ const onDateSelectMock = jest.fn()
+ const { getByTestId, findByText, queryByText } = render(
+
+ )
- let dateInputString = '2018-13-02'
- const dateInput = within(
- getByTestId('dhis2-uicore-input')
- ).getByRole('textbox')
+ let dateInputString = '2018-13-02'
+ const dateInput = within(
+ getByTestId('dhis2-uicore-input')
+ ).getByRole('textbox')
- await userEvent.clear(dateInput)
- await userEvent.type(dateInput, dateInputString)
- await userEvent.tab()
+ await userEvent.clear(dateInput)
+ await userEvent.type(dateInput, dateInputString)
+ await userEvent.tab()
- expect(
await findByText(
'Date 2018-13-02 is less than the minimum allowed date 2018-13-04.'
)
- )
- dateInputString = '2018-13-05'
- await userEvent.clear(dateInput)
- await userEvent.type(dateInput, dateInputString)
- await userEvent.tab()
-
- expect(
- queryByText(
- 'Date 2018-13-04 is less than the minimum allowed date 2018-13-05.'
+ dateInputString = '2018-13-05'
+ await userEvent.clear(dateInput)
+ await userEvent.click(dateInput)
+ await userEvent.type(dateInput, dateInputString)
+
+ await userEvent.tab()
+
+ expect(
+ queryByText(
+ 'Date 2018-13-04 is less than the minimum allowed date 2018-13-05.'
+ )
+ ).not.toBeInTheDocument()
+
+ dateInputString = '2018-13-07'
+ await userEvent.clear(dateInput)
+ await userEvent.type(dateInput, dateInputString)
+ await userEvent.tab()
+
+ expect(
+ await findByText('Invalid date in specified calendar')
+ ).toBeInTheDocument()
+ },
+ 20 * 1000
+ )
+ // ToDo: these scenarios seem to work but they timeout on CI sporadically - ticket: https://dhis2.atlassian.net/browse/LIBS-763
+ it.skip(
+ 'should validate date in nepali calendar',
+ async () => {
+ const onDateSelectMock = jest.fn()
+ const { getByTestId, findByText, queryByText } = render(
+
)
- ).not.toBeInTheDocument()
-
- dateInputString = '2018-13-07'
- await userEvent.clear(dateInput)
- await userEvent.type(dateInput, dateInputString)
- await userEvent.tab()
-
- expect(
- await findByText('Invalid date in specified calendar')
- ).toBeInTheDocument()
- })
- it('should validate date in nepali calendar', async () => {
- const onDateSelectMock = jest.fn()
- const { getByTestId, findByText, queryByText } = render(
-
- )
- let dateInputString = '2080-06-01'
- const dateInput = within(
- getByTestId('dhis2-uicore-input')
- ).getByRole('textbox')
+ let dateInputString = '2080-06-01'
+ const dateInput = within(
+ getByTestId('dhis2-uicore-input')
+ ).getByRole('textbox')
- await userEvent.clear(dateInput)
- await userEvent.type(dateInput, dateInputString)
- await userEvent.tab()
+ await userEvent.clear(dateInput)
+ await userEvent.type(dateInput, dateInputString)
+ await userEvent.tab()
- expect(
- await findByText(
- 'Date 2080-06-01 is greater than the maximum allowed date 2080-05-30.'
+ expect(
+ await findByText(
+ 'Date 2080-06-01 is greater than the maximum allowed date 2080-05-30.'
+ )
)
- )
- dateInputString = '2080-04-32'
- await userEvent.clear(dateInput)
- await userEvent.type(dateInput, dateInputString)
- await userEvent.tab()
-
- expect(
- queryByText(/greater than the maximum allowed date/)
- ).not.toBeInTheDocument()
-
- dateInputString = '2080-01-32'
- await userEvent.clear(dateInput)
- await userEvent.type(dateInput, dateInputString)
- await userEvent.tab()
-
- expect(
- await findByText('Invalid date in specified calendar')
- ).toBeInTheDocument()
- })
- it('should validate from date picker', async () => {
+ dateInputString = '2080-04-32'
+ await userEvent.clear(dateInput)
+ await userEvent.type(dateInput, dateInputString)
+ await userEvent.tab()
+
+ expect(
+ queryByText(/greater than the maximum allowed date/)
+ ).not.toBeInTheDocument()
+
+ dateInputString = '2080-01-32'
+ await userEvent.clear(dateInput)
+ await userEvent.type(dateInput, dateInputString)
+ await userEvent.tab()
+
+ expect(
+ await findByText('Invalid date in specified calendar')
+ ).toBeInTheDocument()
+ },
+ 20 * 1000
+ )
+ it.skip('should validate from date picker', async () => {
jest.useFakeTimers('modern')
jest.setSystemTime(new Date('2024-10-22T09:05:00.000Z'))
diff --git a/components/calendar/src/calendar-input/calendar-input.js b/components/calendar/src/calendar-input/calendar-input.js
index ee127951e..ee9303eb0 100644
--- a/components/calendar/src/calendar-input/calendar-input.js
+++ b/components/calendar/src/calendar-input/calendar-input.js
@@ -38,6 +38,7 @@ export const CalendarInput = ({
strictValidation,
inputWidth,
dataTest = 'dhis2-uiwidgets-calendar-inputfield',
+ pastOnly,
...rest
} = {}) => {
const ref = useRef()
@@ -53,8 +54,9 @@ export const CalendarInput = ({
locale,
numberingSystem,
weekDayFormat,
+ pastOnly,
}),
- [calendar, locale, numberingSystem, weekDayFormat]
+ [calendar, locale, numberingSystem, weekDayFormat, pastOnly]
)
const onChooseDate = (date, validationOptions) => {
@@ -129,6 +131,10 @@ export const CalendarInput = ({
nextYear: pickerResults.nextYear,
prevMonth: pickerResults.prevMonth,
prevYear: pickerResults.prevYear,
+ navigateToYear: pickerResults.navigateToYear,
+ navigateToMonth: pickerResults.navigateToMonth,
+ months: pickerResults.months,
+ years: pickerResults.years,
languageDirection,
}),
[cellSize, date, pickerResults, width, languageDirection]
@@ -240,6 +246,8 @@ CalendarInput.propTypes = {
minDate: PropTypes.string,
/** numbering system to use - full list here https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/numberingSystems.ts */
numberingSystem: PropTypes.string,
+ /** When true, only shows years in the past (current year and earlier) */
+ pastOnly: PropTypes.bool,
/** Whether to use strict validation by showing errors for out-of-range dates when enabled (default), and warnings when disabled */
strictValidation: PropTypes.bool,
/** the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow) */
diff --git a/components/calendar/src/calendar/calendar-container.js b/components/calendar/src/calendar/calendar-container.js
index 6ef4fd35e..4053d574b 100644
--- a/components/calendar/src/calendar/calendar-container.js
+++ b/components/calendar/src/calendar/calendar-container.js
@@ -22,6 +22,10 @@ export const CalendarContainer = React.memo(function CalendarContainer({
nextYear,
prevMonth,
prevYear,
+ navigateToYear,
+ navigateToMonth,
+ months,
+ years,
languageDirection,
calendarRef,
}) {
@@ -34,6 +38,10 @@ export const CalendarContainer = React.memo(function CalendarContainer({
prevMonth,
prevYear,
languageDirection,
+ navigateToYear,
+ navigateToMonth,
+ months,
+ years,
}
}, [
currMonth,
@@ -43,6 +51,10 @@ export const CalendarContainer = React.memo(function CalendarContainer({
nextYear,
prevMonth,
prevYear,
+ navigateToYear,
+ navigateToMonth,
+ months,
+ years,
])
return (
diff --git a/components/calendar/src/calendar/calendar-table.js b/components/calendar/src/calendar/calendar-table.js
index 08d084a23..c7c51e7ec 100644
--- a/components/calendar/src/calendar/calendar-table.js
+++ b/components/calendar/src/calendar/calendar-table.js
@@ -35,7 +35,7 @@ export const CalendarTable = ({
border: none;
border-collapse: collapse;
width: 100%;
- margin-block: ${spacers.dp4};
+ margin-block: 0 ${spacers.dp4};
}
.calendar-table tr,
.calendar-table td {
diff --git a/components/calendar/src/calendar/calendar.js b/components/calendar/src/calendar/calendar.js
index bde6d6a0c..68d8196c7 100644
--- a/components/calendar/src/calendar/calendar.js
+++ b/components/calendar/src/calendar/calendar.js
@@ -17,6 +17,7 @@ export const Calendar = ({
timeZone,
width = '240px',
cellSize = '32px',
+ pastOnly,
}) => {
const [selectedDateString, setSelectedDateString] = useState(date)
const languageDirection = useResolvedDirection(dir, locale)
@@ -27,6 +28,7 @@ export const Calendar = ({
timeZone,
numberingSystem,
weekDayFormat,
+ pastOnly,
}
const pickerResults = useDatePicker({
@@ -59,6 +61,10 @@ export const Calendar = ({
nextYear: pickerResults.nextYear,
prevMonth: pickerResults.prevMonth,
prevYear: pickerResults.prevYear,
+ navigateToYear: pickerResults.navigateToYear,
+ navigateToMonth: pickerResults.navigateToMonth,
+ months: pickerResults.months,
+ years: pickerResults.years,
languageDirection,
}
}, [cellSize, date, dir, locale, pickerResults, width, languageDirection])
@@ -85,6 +91,8 @@ export const CalendarProps = {
locale: PropTypes.string,
/** numbering system to use - full list here https://github.com/dhis2/multi-calendar-dates/blob/main/src/constants/numberingSystems.ts */
numberingSystem: PropTypes.string,
+ /** When true, only shows years in the past (current year and earlier) */
+ pastOnly: PropTypes.bool,
/** the timeZone to use */
timeZone: PropTypes.string,
/** the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow) */
diff --git a/components/calendar/src/calendar/navigation-container.js b/components/calendar/src/calendar/navigation-container.js
index 72480e2b1..2c9251e5e 100644
--- a/components/calendar/src/calendar/navigation-container.js
+++ b/components/calendar/src/calendar/navigation-container.js
@@ -5,7 +5,7 @@ import React from 'react'
import i18n from '../locales/index.js'
const wrapperBorderColor = colors.grey300
-const headerBackground = colors.grey050
+const headerBackground = colors.grey100
export const NavigationContainer = ({
languageDirection,
@@ -15,15 +15,30 @@ export const NavigationContainer = ({
nextYear,
prevMonth,
prevYear,
+ navigateToYear,
+ navigateToMonth,
+ months,
+ years,
}) => {
const PreviousIcon =
languageDirection === 'ltr' ? IconChevronLeft16 : IconChevronRight16
const NextIcon =
languageDirection === 'ltr' ? IconChevronRight16 : IconChevronLeft16
- // Ethiopic years - when localised to English - add the era (i.e. 2015 ERA1), which is redundant in practice (like writing AD for gregorian years)
- // there is an ongoing discussion in JS-Temporal polyfill whether the era should be included or not, but for our case, it's safer to remove it
- const currentYearLabel = currYear.label?.toString().replace(/ERA1/, '')
+ const handleYearChange = (e) => {
+ const targetYear = parseInt(e.target.value)
+ navigateToYear(targetYear)
+ }
+
+ const handleMonthChange = (e) => {
+ const selectedMonth = months.find(
+ (month) => month.label === e.target.value
+ )
+
+ if (selectedMonth) {
+ navigateToMonth(selectedMonth.value)
+ }
+ }
return (
<>
@@ -40,8 +55,31 @@ export const NavigationContainer = ({
-
-
{currMonth.label}
+
+
+
-
-
+
+
+
+