From c17fdf0afaf595b4ab7ea86deddd5f395ff6037c Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Mon, 20 May 2024 16:22:09 +0300 Subject: [PATCH 01/11] feat: support min & max dates --- .../src/calendar-input/calendar-input.js | 65 +++++++++++++++++-- components/calendar/src/calendar/calendar.js | 6 +- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/components/calendar/src/calendar-input/calendar-input.js b/components/calendar/src/calendar-input/calendar-input.js index a2753110b2..0be3e42cdd 100644 --- a/components/calendar/src/calendar-input/calendar-input.js +++ b/components/calendar/src/calendar-input/calendar-input.js @@ -3,8 +3,9 @@ import { Card } from '@dhis2-ui/card' import { InputField, InputFieldProps } from '@dhis2-ui/input' import { Layer } from '@dhis2-ui/layer' import { Popper } from '@dhis2-ui/popper' +import { validateDateString } from '@dhis2/multi-calendar-dates' import cx from 'classnames' -import React, { useRef, useState } from 'react' +import React, { useRef, useState, useEffect } from 'react' import { Calendar, CalendarProps } from '../calendar/calendar.js' import i18n from '../locales/index.js' @@ -27,10 +28,16 @@ export const CalendarInput = ({ width, cellSize, clearable, + editable, + minDate, + maxDate, ...rest } = {}) => { const ref = useRef() + const [tempDate, setTempDate] = useState(date) const [open, setOpen] = useState(false) + const [error, setError] = useState('') + const [warning, setWarning] = useState('') const calendarProps = React.useMemo(() => { const onDateSelectWrapper = (selectedDate) => { @@ -66,6 +73,47 @@ export const CalendarInput = ({ setOpen(true) } + useEffect(() => { + setTempDate(date) + const { isValid, errorMessage, warningMessage } = validateDateString( + date, + { + minDateString: minDate, + maxDateString: maxDate, + validationType: 'throw', + } + ) + if (isValid) { + setError('') + setWarning(warningMessage || '') + } else { + setError(errorMessage) + setOpen(true) + } + }, [date, maxDate, minDate]) + + const handleChange = (e) => { + setOpen(false) + const newDate = e.value + setTempDate(newDate) + const { isValid, errorMessage, warningMessage } = validateDateString( + newDate, + { + minDateString: minDate, + maxDateString: maxDate, + validationType: 'throw', + } + ) + setOpen(true) + if (isValid) { + setError('') + setWarning(warningMessage || '') + onDateSelect({ calendarDateString: newDate }) + } else { + setError(errorMessage) + } + } + return ( <> <div className="calendar-input-wrapper" ref={ref}> @@ -74,14 +122,15 @@ export const CalendarInput = ({ {...rest} type="text" onFocus={onFocus} - value={date} + value={tempDate} + onChange={editable ? handleChange : undefined} + validationText={error || warning} + error={!!error} + warning={!!warning} /> {clearable && ( <div className={cx('calendar-clear-button', { - // ToDo: this is a workaround to show the clear button in the correct place when an icon is shown. - // Long-term, we should abstract and share the logic multi-select uses for the input-wrapper - // https://dhis2.atlassian.net/browse/DHIS2-14848 'with-icon': rest.valid || rest.error || @@ -94,7 +143,10 @@ export const CalendarInput = ({ dataTest="calendar-clear-button" secondary small - onClick={() => calendarProps.onDateSelect(null)} + onClick={() => { + setTempDate('') + onDateSelect?.(null) + }} type="button" > {i18n.t('Clear')} @@ -130,7 +182,6 @@ export const CalendarInput = ({ inset-inline-end: 6px; inset-block-start: 27px; } - .calendar-clear-button.with-icon { inset-inline-end: 36px; } diff --git a/components/calendar/src/calendar/calendar.js b/components/calendar/src/calendar/calendar.js index 51176ea25d..2cd8ecba01 100644 --- a/components/calendar/src/calendar/calendar.js +++ b/components/calendar/src/calendar/calendar.js @@ -4,7 +4,7 @@ import { } from '@dhis2/multi-calendar-dates' import { colors } from '@dhis2/ui-constants' import PropTypes from 'prop-types' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { CalendarTable } from './calendar-table.js' import { NavigationContainer } from './navigation-container.js' @@ -26,6 +26,10 @@ export const Calendar = ({ const [selectedDateString, setSelectedDateString] = useState(date) const languageDirection = useResolvedDirection(dir, locale) + useEffect(() => { + setSelectedDateString(date) + }, [date]) + const options = { locale, calendar, From 14f8bde6274efb84d5a3639a3c324d8247dc2152 Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Tue, 21 May 2024 17:47:14 +0300 Subject: [PATCH 02/11] chore: add story CalendarWithEditiableInput --- .../src/stories/calendar-input.stories.js | 50 +++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/components/calendar/src/stories/calendar-input.stories.js b/components/calendar/src/stories/calendar-input.stories.js index 13cc451670..493cb15021 100644 --- a/components/calendar/src/stories/calendar-input.stories.js +++ b/components/calendar/src/stories/calendar-input.stories.js @@ -22,20 +22,17 @@ export default { }, } -const buildCalendar = - ({ date, locale, calendar }) => - () => - ( - <CalendarStoryWrapper - component={CalendarInput} - dir="ltr" - timeZone="Africa/Khartoum" - weekDayFormat="short" - date={date} - locale={locale} - calendar={calendar} - /> - ) +const buildCalendar = ({ date, locale, calendar }) => () => ( + <CalendarStoryWrapper + component={CalendarInput} + dir="ltr" + timeZone="Africa/Khartoum" + weekDayFormat="short" + date={date} + locale={locale} + calendar={calendar} + /> +) export const EthiopicWithAmharic = buildCalendar({ calendar: 'ethiopic', @@ -114,3 +111,28 @@ export const CalendarWithClearButton = ({ </> ) } + +export function CalendarWithEditiableInput() { + const [date, setDate] = useState('2020-07-03') + return ( + <div> + <> + <CalendarInput + editable + date={date} + calendar="gregory" + onDateSelect={(selectedDate) => { + const date = selectedDate?.calendarDateString + setDate(date) + }} + label="ooo" + width={'700px'} + inputWidth="900px" + timeZone={'UTC'} + minDate={'2020-07-01'} + maxDate={'2020-07-09'} + /> + </> + </div> + ) +} From dd1c85fb3670c3539b8da7fcce669735483fc79e Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Wed, 29 May 2024 12:23:45 +0300 Subject: [PATCH 03/11] chore: refactor code --- .../src/calendar-input/calendar-input.js | 78 ++++++++----------- components/calendar/src/calendar/calendar.js | 70 +++++------------ 2 files changed, 51 insertions(+), 97 deletions(-) diff --git a/components/calendar/src/calendar-input/calendar-input.js b/components/calendar/src/calendar-input/calendar-input.js index 0be3e42cdd..871e2f34b7 100644 --- a/components/calendar/src/calendar-input/calendar-input.js +++ b/components/calendar/src/calendar-input/calendar-input.js @@ -1,9 +1,9 @@ import { Button } from '@dhis2-ui/button' import { Card } from '@dhis2-ui/card' -import { InputField, InputFieldProps } from '@dhis2-ui/input' +import { InputField } from '@dhis2-ui/input' import { Layer } from '@dhis2-ui/layer' import { Popper } from '@dhis2-ui/popper' -import { validateDateString } from '@dhis2/multi-calendar-dates' +import { useDatePicker } from '@dhis2/multi-calendar-dates' import cx from 'classnames' import React, { useRef, useState, useEffect } from 'react' import { Calendar, CalendarProps } from '../calendar/calendar.js' @@ -31,10 +31,11 @@ export const CalendarInput = ({ editable, minDate, maxDate, + format, + validation, ...rest } = {}) => { const ref = useRef() - const [tempDate, setTempDate] = useState(date) const [open, setOpen] = useState(false) const [error, setError] = useState('') const [warning, setWarning] = useState('') @@ -69,49 +70,34 @@ export const CalendarInput = ({ width, ]) - const onFocus = () => { - setOpen(true) - } + const pickerOptions = useDatePicker({ + onDateSelect: (result) => { + setOpen(false) + onDateSelect(result) + }, + date: date, + minDate: minDate, + maxDate: maxDate, + validation: validation, + format: format, + options: calendarProps, + }) useEffect(() => { - setTempDate(date) - const { isValid, errorMessage, warningMessage } = validateDateString( - date, - { - minDateString: minDate, - maxDateString: maxDate, - validationType: 'throw', - } - ) - if (isValid) { - setError('') - setWarning(warningMessage || '') - } else { - setError(errorMessage) - setOpen(true) - } - }, [date, maxDate, minDate]) + setError(pickerOptions.errorMessage || '') + setWarning(pickerOptions.warningMessage || '') + }, [ + pickerOptions.errorMessage, + pickerOptions.warningMessage, + pickerOptions.isValid, + ]) const handleChange = (e) => { - setOpen(false) - const newDate = e.value - setTempDate(newDate) - const { isValid, errorMessage, warningMessage } = validateDateString( - newDate, - { - minDateString: minDate, - maxDateString: maxDate, - validationType: 'throw', - } - ) + onDateSelect?.({ calendarDateString: e.value }) + } + + const onFocus = () => { setOpen(true) - if (isValid) { - setError('') - setWarning(warningMessage || '') - onDateSelect({ calendarDateString: newDate }) - } else { - setError(errorMessage) - } } return ( @@ -122,7 +108,7 @@ export const CalendarInput = ({ {...rest} type="text" onFocus={onFocus} - value={tempDate} + value={date} onChange={editable ? handleChange : undefined} validationText={error || warning} error={!!error} @@ -144,7 +130,6 @@ export const CalendarInput = ({ secondary small onClick={() => { - setTempDate('') onDateSelect?.(null) }} type="button" @@ -166,7 +151,11 @@ export const CalendarInput = ({ modifiers={[offsetModifier]} > <Card> - <Calendar {...calendarProps} date={date} /> + <Calendar + {...calendarProps} + {...pickerOptions} + date={date} + /> </Card> </Popper> </Layer> @@ -199,5 +188,4 @@ CalendarInput.defaultProps = { } CalendarInput.propTypes = { ...CalendarProps, - ...InputFieldProps, } diff --git a/components/calendar/src/calendar/calendar.js b/components/calendar/src/calendar/calendar.js index 2cd8ecba01..1c88a8f1fb 100644 --- a/components/calendar/src/calendar/calendar.js +++ b/components/calendar/src/calendar/calendar.js @@ -1,55 +1,27 @@ -import { - useDatePicker, - useResolvedDirection, -} from '@dhis2/multi-calendar-dates' +import { useResolvedDirection } from '@dhis2/multi-calendar-dates' import { colors } from '@dhis2/ui-constants' import PropTypes from 'prop-types' -import React, { useEffect, useState } from 'react' +import React from 'react' import { CalendarTable } from './calendar-table.js' import { NavigationContainer } from './navigation-container.js' -export const Calendar = ({ - onDateSelect, - calendar, - date, - dir, - locale, - numberingSystem, - weekDayFormat, - timeZone, - width, - cellSize, -}) => { +export const Calendar = (calendarProps) => { + const { + date, + dir, + locale, + width, + cellSize, + calendarWeekDays, + weekDayLabels, + isValid, + } = calendarProps + const wrapperBorderColor = colors.grey300 const backgroundColor = 'none' - const [selectedDateString, setSelectedDateString] = useState(date) const languageDirection = useResolvedDirection(dir, locale) - useEffect(() => { - setSelectedDateString(date) - }, [date]) - - const options = { - locale, - calendar, - timeZone, - numberingSystem, - weekDayFormat, - } - - const pickerOptions = useDatePicker({ - onDateSelect: (result) => { - const { calendarDateString } = result - setSelectedDateString(calendarDateString) - onDateSelect(result) - }, - date: selectedDateString, - options, - }) - - const { calendarWeekDays, weekDayLabels } = pickerOptions - return ( <div> <div @@ -58,11 +30,11 @@ export const Calendar = ({ data-test="calendar" > <NavigationContainer - pickerOptions={pickerOptions} + pickerOptions={calendarProps} languageDirection={languageDirection} /> <CalendarTable - selectedDate={selectedDateString} + selectedDate={isValid ? date : null} calendarWeekDays={calendarWeekDays} weekDayLabels={weekDayLabels} cellSize={cellSize} @@ -96,10 +68,6 @@ Calendar.defaultProps = { } export const CalendarProps = { - /** 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 */ - calendar: PropTypes.any.isRequired, - /** Called with signature `(null)` \|\| `({ dateCalendarString: string, dateCalendar: Temporal.ZonedDateTime })` with `dateCalendarString` being the stringified date in the specified calendar in the format `yyyy-MM-dd` */ - onDateSelect: PropTypes.func.isRequired, /** the size of a single cell in the table forming the calendar */ cellSize: PropTypes.string, /** the currently selected date using an iso-like format YYYY-MM-DD, in the calendar system provided (not iso8601) */ @@ -108,14 +76,12 @@ export const CalendarProps = { dir: PropTypes.oneOf(['ltr', 'rtl']), /** 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) */ 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, - /** the timeZone to use */ - timeZone: PropTypes.string, /** the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow) */ weekDayFormat: PropTypes.oneOf(['narrow', 'short', 'long']), /** the width of the calendar component */ width: PropTypes.string, + /** is date valid and within range */ + isValid: PropTypes.bool, } Calendar.propTypes = CalendarProps From af16a74c5339931f45e2ba539b858c54f2290d36 Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Mon, 10 Jun 2024 13:11:58 +0300 Subject: [PATCH 04/11] fix: improve calendar component for independent use --- components/calendar/package.json | 12 +++--- components/calendar/src/calendar/calendar.js | 44 +++++++++++++++++--- yarn.lock | 12 +++--- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/components/calendar/package.json b/components/calendar/package.json index 5f3ce1604c..0a8c439fb4 100644 --- a/components/calendar/package.json +++ b/components/calendar/package.json @@ -33,12 +33,12 @@ "styled-jsx": "^4" }, "dependencies": { - "@dhis2-ui/button": "9.6.0", - "@dhis2-ui/card": "9.6.0", - "@dhis2-ui/input": "9.6.0", - "@dhis2-ui/layer": "9.6.0", - "@dhis2-ui/popper": "9.6.0", - "@dhis2/multi-calendar-dates": "^1.1.1", + "@dhis2-ui/button": "9.4.6", + "@dhis2-ui/card": "9.4.6", + "@dhis2-ui/input": "9.4.6", + "@dhis2-ui/layer": "9.4.6", + "@dhis2-ui/popper": "9.4.6", + "@dhis2/multi-calendar-dates": "v1.0.0-alpha.26", "@dhis2/prop-types": "^3.1.2", "@dhis2/ui-constants": "9.6.0", "@dhis2/ui-icons": "9.6.0", diff --git a/components/calendar/src/calendar/calendar.js b/components/calendar/src/calendar/calendar.js index 1c88a8f1fb..536fb6ad05 100644 --- a/components/calendar/src/calendar/calendar.js +++ b/components/calendar/src/calendar/calendar.js @@ -1,4 +1,7 @@ -import { useResolvedDirection } from '@dhis2/multi-calendar-dates' +import { + useResolvedDirection, + useDatePicker, +} from '@dhis2/multi-calendar-dates' import { colors } from '@dhis2/ui-constants' import PropTypes from 'prop-types' import React from 'react' @@ -12,11 +15,32 @@ export const Calendar = (calendarProps) => { locale, width, cellSize, - calendarWeekDays, - weekDayLabels, isValid, + onDateSelect, + minDate, + maxDate, + validation, + format, } = calendarProps + let { calendarWeekDays, weekDayLabels } = calendarProps + const pickerOptions = useDatePicker({ + onDateSelect: (result) => { + onDateSelect(result) + }, + date: date, + minDate: minDate, + maxDate: maxDate, + validation: validation, + format: format, + options: calendarProps, + }) + if (!calendarWeekDays) { + calendarWeekDays = pickerOptions.calendarWeekDays + } + if (!weekDayLabels) { + weekDayLabels = pickerOptions.weekDayLabels + } const wrapperBorderColor = colors.grey300 const backgroundColor = 'none' @@ -30,7 +54,11 @@ export const Calendar = (calendarProps) => { data-test="calendar" > <NavigationContainer - pickerOptions={calendarProps} + pickerOptions={ + calendarProps.calendarWeekDays + ? calendarProps + : pickerOptions + } languageDirection={languageDirection} /> <CalendarTable @@ -82,6 +110,12 @@ export const CalendarProps = { width: PropTypes.string, /** is date valid and within range */ isValid: PropTypes.bool, + calendarWeekDays: PropTypes.array, + weekDayLabels: PropTypes.arrayOf(PropTypes.string), + minDate: PropTypes.string, + maxDate: PropTypes.string, + validation: PropTypes.string, + format: PropTypes.string, } -Calendar.propTypes = CalendarProps +Calendar.propTypes = { ...CalendarProps } diff --git a/yarn.lock b/yarn.lock index 15c684e11d..d2ef2cfceb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2629,12 +2629,12 @@ i18next "^10.3" moment "^2.24.0" -"@dhis2/multi-calendar-dates@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@dhis2/multi-calendar-dates/-/multi-calendar-dates-1.1.1.tgz#fb76a77114ce0b757db7dd9f588d1a47809732da" - integrity sha512-kaisVuRGfdqY/Up6sWqgc81K67ymPVoRYgYRcT29z61ol2WhiTXTSTuRX/gDO1VKjmskeB5/badRrdLMf4BBUA== +"@dhis2/multi-calendar-dates@v1.0.0-alpha.26": + version "1.0.0-alpha.26" + resolved "https://registry.yarnpkg.com/@dhis2/multi-calendar-dates/-/multi-calendar-dates-1.0.0-alpha.26.tgz#33c3384ee96219f5500005058a69bd3104d1a5b9" + integrity sha512-85oj4Ji/UOwt4nWDrzUfyl5tkcF1YrB1kBh1kCjPL0Md1+XDzM6nee9DFx4Eh9BNJN/cOgWJo9mWDsPycXO0aA== dependencies: - "@js-temporal/polyfill" "^0.4.2" + "@js-temporal/polyfill" "0.4.3" classnames "^2.3.2" "@dhis2/prop-types@^1.6.4": @@ -3812,7 +3812,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@js-temporal/polyfill@^0.4.2": +"@js-temporal/polyfill@0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@js-temporal/polyfill/-/polyfill-0.4.3.tgz#e8f8cf86745eb5050679c46a5ebedb9a9cc1f09b" integrity sha512-6Fmjo/HlkyVCmJzAPnvtEWlcbQUSRhi8qlN9EtJA/wP7FqXsevLLrlojR44kzNzrRkpf7eDJ+z7b4xQD/Ycypw== From 21d37f1753ea8b133d1a69c98f88fc2ed2e3c06a Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Mon, 10 Jun 2024 13:32:41 +0300 Subject: [PATCH 05/11] fix: lint warnings --- .../src/stories/calendar-input.stories.js | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/components/calendar/src/stories/calendar-input.stories.js b/components/calendar/src/stories/calendar-input.stories.js index 493cb15021..be4a73db98 100644 --- a/components/calendar/src/stories/calendar-input.stories.js +++ b/components/calendar/src/stories/calendar-input.stories.js @@ -22,17 +22,20 @@ export default { }, } -const buildCalendar = ({ date, locale, calendar }) => () => ( - <CalendarStoryWrapper - component={CalendarInput} - dir="ltr" - timeZone="Africa/Khartoum" - weekDayFormat="short" - date={date} - locale={locale} - calendar={calendar} - /> -) +const buildCalendar = + ({ date, locale, calendar }) => + () => + ( + <CalendarStoryWrapper + component={CalendarInput} + dir="ltr" + timeZone="Africa/Khartoum" + weekDayFormat="short" + date={date} + locale={locale} + calendar={calendar} + /> + ) export const EthiopicWithAmharic = buildCalendar({ calendar: 'ethiopic', From 00e2cb5647d85b1c02c600ed3e6d3e6f7151ea92 Mon Sep 17 00:00:00 2001 From: Mozafar Haider <mozafar@dhis2.org> Date: Thu, 25 Jul 2024 11:18:40 +0100 Subject: [PATCH 06/11] refactor: use calendar inner components directly to avoid double calls to multi-calendar library --- .../src/calendar-input/calendar-input.js | 160 ++++++++++++------ components/calendar/src/calendar/calendar.js | 90 +++++----- 2 files changed, 148 insertions(+), 102 deletions(-) diff --git a/components/calendar/src/calendar-input/calendar-input.js b/components/calendar/src/calendar-input/calendar-input.js index 871e2f34b7..29f8033b4e 100644 --- a/components/calendar/src/calendar-input/calendar-input.js +++ b/components/calendar/src/calendar-input/calendar-input.js @@ -3,10 +3,17 @@ import { Card } from '@dhis2-ui/card' import { InputField } from '@dhis2-ui/input' import { Layer } from '@dhis2-ui/layer' import { Popper } from '@dhis2-ui/popper' -import { useDatePicker } from '@dhis2/multi-calendar-dates' +import { + useDatePicker, + useResolvedDirection, +} from '@dhis2/multi-calendar-dates' +import { colors } from '@dhis2/ui-constants' import cx from 'classnames' -import React, { useRef, useState, useEffect } from 'react' -import { Calendar, CalendarProps } from '../calendar/calendar.js' +// import { debounce } from 'lodash' +import React, { useRef, useState, useMemo, useCallback } from 'react' +import { CalendarTable } from '../calendar/calendar-table.js' +import { CalendarProps } from '../calendar/calendar.js' +import { NavigationContainer } from '../calendar/navigation-container.js' import i18n from '../locales/index.js' const offsetModifier = { @@ -17,7 +24,7 @@ const offsetModifier = { } export const CalendarInput = ({ - onDateSelect, + onDateSelect: parentOnDateSelect, calendar, date, dir, @@ -31,67 +38,42 @@ export const CalendarInput = ({ editable, minDate, maxDate, - format, + format, // todo: props and types for format and validation validation, ...rest } = {}) => { const ref = useRef() const [open, setOpen] = useState(false) - const [error, setError] = useState('') - const [warning, setWarning] = useState('') - const calendarProps = React.useMemo(() => { - const onDateSelectWrapper = (selectedDate) => { - setOpen(false) - onDateSelect?.(selectedDate) - } - return { - onDateSelect: onDateSelectWrapper, + const useDatePickerOptions = useMemo( + () => ({ calendar, - date, - dir, locale, + timeZone, // todo: we probably shouldn't have had timezone here in the first place numberingSystem, weekDayFormat, - timeZone, - width, - cellSize, - } - }, [ - calendar, - cellSize, - date, - dir, - locale, - numberingSystem, - onDateSelect, - timeZone, - weekDayFormat, - width, - ]) + }), + [calendar, locale, numberingSystem, timeZone, weekDayFormat] + ) - const pickerOptions = useDatePicker({ - onDateSelect: (result) => { - setOpen(false) - onDateSelect(result) + const onDateSelect = useCallback( + (result, keepPopperOpen = false) => { + setOpen(keepPopperOpen) + parentOnDateSelect?.(result) }, - date: date, + [parentOnDateSelect] + ) + + const pickerResults = useDatePicker({ + onDateSelect, + date, minDate: minDate, maxDate: maxDate, validation: validation, format: format, - options: calendarProps, + options: useDatePickerOptions, }) - useEffect(() => { - setError(pickerOptions.errorMessage || '') - setWarning(pickerOptions.warningMessage || '') - }, [ - pickerOptions.errorMessage, - pickerOptions.warningMessage, - pickerOptions.isValid, - ]) - const handleChange = (e) => { onDateSelect?.({ calendarDateString: e.value }) } @@ -100,6 +82,41 @@ export const CalendarInput = ({ setOpen(true) } + const calendarProps = useMemo(() => { + return { + date, + dir, + locale, + width, + cellSize, + minDate, + maxDate, + validation, // todo: clarify "validation" type in the hook + format, + calendarWeekDays: pickerResults.calendarWeekDays, + weekDayLabels: pickerResults.weekDayLabels, + currMonth: pickerResults.currMonth, + currYear: pickerResults.currYear, + nextMonth: pickerResults.nextMonth, + nextYear: pickerResults.nextYear, + prevMonth: pickerResults.prevMonth, + prevYear: pickerResults.prevYear, + } + }, [ + cellSize, + date, + dir, + format, + locale, + maxDate, + minDate, + pickerResults, + validation, + width, + ]) + + const languageDirection = useResolvedDirection(dir, locale) + return ( <> <div className="calendar-input-wrapper" ref={ref}> @@ -110,9 +127,12 @@ export const CalendarInput = ({ onFocus={onFocus} value={date} onChange={editable ? handleChange : undefined} - validationText={error || warning} - error={!!error} - warning={!!warning} + validationText={ + pickerResults.errorMessage || + pickerResults.warningMessage + } + error={!!pickerResults.errorMessage} + warning={!!pickerResults.warningMessage} /> {clearable && ( <div @@ -151,11 +171,27 @@ export const CalendarInput = ({ modifiers={[offsetModifier]} > <Card> - <Calendar - {...calendarProps} - {...pickerOptions} - date={date} - /> + <div + className="calendar-wrapper" + dir={languageDirection} + data-test="calendar" + > + <NavigationContainer + pickerOptions={calendarProps} + languageDirection={languageDirection} + /> + <CalendarTable + selectedDate={ + calendarProps.isValid ? date : null + } + calendarWeekDays={ + calendarProps.calendarWeekDays + } + weekDayLabels={calendarProps.weekDayLabels} + cellSize={cellSize} + width={width} + /> + </div> </Card> </Popper> </Layer> @@ -177,6 +213,20 @@ export const CalendarInput = ({ .calendar-clear-button.with-dense-wrapper { inset-block-start: 23px; } + .calendar-wrapper { + font-family: Roboto, sans-serif; + font-weight: 400; + font-size: 14px; + background-color: none; + display: flex; + flex-direction: column; + border: 1px solid ${colors.grey300}; + border-radius: 3px; + min-width: ${width}; + width: max-content; + box-shadow: 0px 4px 6px -2px #2129340d; + box-shadow: 0px 10px 15px -3px #2129341a; + } `} </style> </> diff --git a/components/calendar/src/calendar/calendar.js b/components/calendar/src/calendar/calendar.js index 536fb6ad05..51176ea25d 100644 --- a/components/calendar/src/calendar/calendar.js +++ b/components/calendar/src/calendar/calendar.js @@ -1,50 +1,50 @@ import { - useResolvedDirection, useDatePicker, + useResolvedDirection, } from '@dhis2/multi-calendar-dates' import { colors } from '@dhis2/ui-constants' import PropTypes from 'prop-types' -import React from 'react' +import React, { useState } from 'react' import { CalendarTable } from './calendar-table.js' import { NavigationContainer } from './navigation-container.js' -export const Calendar = (calendarProps) => { - const { - date, - dir, +export const Calendar = ({ + onDateSelect, + calendar, + date, + dir, + locale, + numberingSystem, + weekDayFormat, + timeZone, + width, + cellSize, +}) => { + const wrapperBorderColor = colors.grey300 + const backgroundColor = 'none' + + const [selectedDateString, setSelectedDateString] = useState(date) + const languageDirection = useResolvedDirection(dir, locale) + + const options = { locale, - width, - cellSize, - isValid, - onDateSelect, - minDate, - maxDate, - validation, - format, - } = calendarProps - let { calendarWeekDays, weekDayLabels } = calendarProps + calendar, + timeZone, + numberingSystem, + weekDayFormat, + } + const pickerOptions = useDatePicker({ onDateSelect: (result) => { + const { calendarDateString } = result + setSelectedDateString(calendarDateString) onDateSelect(result) }, - date: date, - minDate: minDate, - maxDate: maxDate, - validation: validation, - format: format, - options: calendarProps, + date: selectedDateString, + options, }) - if (!calendarWeekDays) { - calendarWeekDays = pickerOptions.calendarWeekDays - } - if (!weekDayLabels) { - weekDayLabels = pickerOptions.weekDayLabels - } - const wrapperBorderColor = colors.grey300 - const backgroundColor = 'none' - - const languageDirection = useResolvedDirection(dir, locale) + const { calendarWeekDays, weekDayLabels } = pickerOptions return ( <div> @@ -54,15 +54,11 @@ export const Calendar = (calendarProps) => { data-test="calendar" > <NavigationContainer - pickerOptions={ - calendarProps.calendarWeekDays - ? calendarProps - : pickerOptions - } + pickerOptions={pickerOptions} languageDirection={languageDirection} /> <CalendarTable - selectedDate={isValid ? date : null} + selectedDate={selectedDateString} calendarWeekDays={calendarWeekDays} weekDayLabels={weekDayLabels} cellSize={cellSize} @@ -96,6 +92,10 @@ Calendar.defaultProps = { } export const CalendarProps = { + /** 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 */ + calendar: PropTypes.any.isRequired, + /** Called with signature `(null)` \|\| `({ dateCalendarString: string, dateCalendar: Temporal.ZonedDateTime })` with `dateCalendarString` being the stringified date in the specified calendar in the format `yyyy-MM-dd` */ + onDateSelect: PropTypes.func.isRequired, /** the size of a single cell in the table forming the calendar */ cellSize: PropTypes.string, /** the currently selected date using an iso-like format YYYY-MM-DD, in the calendar system provided (not iso8601) */ @@ -104,18 +104,14 @@ export const CalendarProps = { dir: PropTypes.oneOf(['ltr', 'rtl']), /** 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) */ 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, + /** the timeZone to use */ + timeZone: PropTypes.string, /** the format to display for the week day, i.e. Monday (long), Mon (short), M (narrow) */ weekDayFormat: PropTypes.oneOf(['narrow', 'short', 'long']), /** the width of the calendar component */ width: PropTypes.string, - /** is date valid and within range */ - isValid: PropTypes.bool, - calendarWeekDays: PropTypes.array, - weekDayLabels: PropTypes.arrayOf(PropTypes.string), - minDate: PropTypes.string, - maxDate: PropTypes.string, - validation: PropTypes.string, - format: PropTypes.string, } -Calendar.propTypes = { ...CalendarProps } +Calendar.propTypes = CalendarProps From e2b9176be156fe9093a11e0d679f691184a572eb Mon Sep 17 00:00:00 2001 From: Mozafar Haider <mozafar@dhis2.org> Date: Mon, 29 Jul 2024 09:36:17 +0100 Subject: [PATCH 07/11] fix: pass isValid to calendarProps --- components/calendar/src/calendar-input/calendar-input.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/calendar/src/calendar-input/calendar-input.js b/components/calendar/src/calendar-input/calendar-input.js index 29f8033b4e..cb52892925 100644 --- a/components/calendar/src/calendar-input/calendar-input.js +++ b/components/calendar/src/calendar-input/calendar-input.js @@ -93,6 +93,7 @@ export const CalendarInput = ({ maxDate, validation, // todo: clarify "validation" type in the hook format, + isValid: pickerResults.isValid, calendarWeekDays: pickerResults.calendarWeekDays, weekDayLabels: pickerResults.weekDayLabels, currMonth: pickerResults.currMonth, From e69edb8f054ebcdd9a7b5ee40a81c05bf2855619 Mon Sep 17 00:00:00 2001 From: Mozafar Haider <mozafar@dhis2.org> Date: Mon, 29 Jul 2024 10:45:09 +0100 Subject: [PATCH 08/11] refactor: extract calendar table into shared component --- .../src/calendar-input/calendar-input.js | 80 +++------------- .../src/calendar/calendar-container.js | 92 +++++++++++++++++++ .../calendar/src/calendar/calendar-table.js | 4 +- components/calendar/src/calendar/calendar.js | 69 ++++++-------- .../src/calendar/navigation-container.js | 61 ++++++------ 5 files changed, 166 insertions(+), 140 deletions(-) create mode 100644 components/calendar/src/calendar/calendar-container.js diff --git a/components/calendar/src/calendar-input/calendar-input.js b/components/calendar/src/calendar-input/calendar-input.js index cb52892925..34be79361c 100644 --- a/components/calendar/src/calendar-input/calendar-input.js +++ b/components/calendar/src/calendar-input/calendar-input.js @@ -7,13 +7,10 @@ import { useDatePicker, useResolvedDirection, } from '@dhis2/multi-calendar-dates' -import { colors } from '@dhis2/ui-constants' import cx from 'classnames' -// import { debounce } from 'lodash' import React, { useRef, useState, useMemo, useCallback } from 'react' -import { CalendarTable } from '../calendar/calendar-table.js' +import { CalendarContainer } from '../calendar/calendar-container.js' import { CalendarProps } from '../calendar/calendar.js' -import { NavigationContainer } from '../calendar/navigation-container.js' import i18n from '../locales/index.js' const offsetModifier = { @@ -56,16 +53,11 @@ export const CalendarInput = ({ [calendar, locale, numberingSystem, timeZone, weekDayFormat] ) - const onDateSelect = useCallback( - (result, keepPopperOpen = false) => { - setOpen(keepPopperOpen) + const pickerResults = useDatePicker({ + onDateSelect: (result) => { + setOpen(false) parentOnDateSelect?.(result) }, - [parentOnDateSelect] - ) - - const pickerResults = useDatePicker({ - onDateSelect, date, minDate: minDate, maxDate: maxDate, @@ -75,24 +67,20 @@ export const CalendarInput = ({ }) const handleChange = (e) => { - onDateSelect?.({ calendarDateString: e.value }) + parentOnDateSelect?.({ calendarDateString: e.value }) } const onFocus = () => { setOpen(true) } + const languageDirection = useResolvedDirection(dir, locale) + const calendarProps = useMemo(() => { return { date, - dir, - locale, width, cellSize, - minDate, - maxDate, - validation, // todo: clarify "validation" type in the hook - format, isValid: pickerResults.isValid, calendarWeekDays: pickerResults.calendarWeekDays, weekDayLabels: pickerResults.weekDayLabels, @@ -102,21 +90,9 @@ export const CalendarInput = ({ nextYear: pickerResults.nextYear, prevMonth: pickerResults.prevMonth, prevYear: pickerResults.prevYear, + languageDirection, } - }, [ - cellSize, - date, - dir, - format, - locale, - maxDate, - minDate, - pickerResults, - validation, - width, - ]) - - const languageDirection = useResolvedDirection(dir, locale) + }, [cellSize, date, pickerResults, width, languageDirection]) return ( <> @@ -151,7 +127,7 @@ export const CalendarInput = ({ secondary small onClick={() => { - onDateSelect?.(null) + parentOnDateSelect?.(null) }} type="button" > @@ -172,27 +148,7 @@ export const CalendarInput = ({ modifiers={[offsetModifier]} > <Card> - <div - className="calendar-wrapper" - dir={languageDirection} - data-test="calendar" - > - <NavigationContainer - pickerOptions={calendarProps} - languageDirection={languageDirection} - /> - <CalendarTable - selectedDate={ - calendarProps.isValid ? date : null - } - calendarWeekDays={ - calendarProps.calendarWeekDays - } - weekDayLabels={calendarProps.weekDayLabels} - cellSize={cellSize} - width={width} - /> - </div> + <CalendarContainer {...calendarProps} /> </Card> </Popper> </Layer> @@ -214,20 +170,6 @@ export const CalendarInput = ({ .calendar-clear-button.with-dense-wrapper { inset-block-start: 23px; } - .calendar-wrapper { - font-family: Roboto, sans-serif; - font-weight: 400; - font-size: 14px; - background-color: none; - display: flex; - flex-direction: column; - border: 1px solid ${colors.grey300}; - border-radius: 3px; - min-width: ${width}; - width: max-content; - box-shadow: 0px 4px 6px -2px #2129340d; - box-shadow: 0px 10px 15px -3px #2129341a; - } `} </style> </> diff --git a/components/calendar/src/calendar/calendar-container.js b/components/calendar/src/calendar/calendar-container.js new file mode 100644 index 0000000000..4d8fb004b2 --- /dev/null +++ b/components/calendar/src/calendar/calendar-container.js @@ -0,0 +1,92 @@ +import { colors } from '@dhis2/ui-constants' +import PropTypes from 'prop-types' +import React, { useMemo } from 'react' +import { CalendarTable, CalendarTableProps } from './calendar-table.js' +import { + NavigationContainer, + NavigationContainerProps, +} from './navigation-container.js' + +const wrapperBorderColor = colors.grey300 +const backgroundColor = 'none' + +export const CalendarContainer = ({ + date, + width, + cellSize, + calendarWeekDays, + weekDayLabels, + currMonth, + currYear, + nextMonth, + nextYear, + prevMonth, + prevYear, + languageDirection, +}) => { + const navigationProps = useMemo(() => { + return { + currMonth, + currYear, + nextMonth, + nextYear, + prevMonth, + prevYear, + languageDirection, + } + }, [ + currMonth, + currYear, + languageDirection, + nextMonth, + nextYear, + prevMonth, + prevYear, + ]) + return ( + <div> + <div + className="calendar-wrapper" + dir={languageDirection} + data-test="calendar" + > + <NavigationContainer {...navigationProps} /> + <CalendarTable + selectedDate={date} + calendarWeekDays={calendarWeekDays} + weekDayLabels={weekDayLabels} + cellSize={cellSize} + width={width} + /> + </div> + <style jsx>{` + .calendar-wrapper { + font-family: Roboto, sans-serif; + font-weight: 400; + font-size: 14px; + background-color: ${backgroundColor}; + display: flex; + flex-direction: column; + border: 1px solid ${wrapperBorderColor}; + border-radius: 3px; + min-width: ${width}; + width: max-content; + box-shadow: 0px 4px 6px -2px #2129340d; + box-shadow: 0px 10px 15px -3px #2129341a; + } + `}</style> + </div> + ) +} + +CalendarContainer.defaultProps = { + cellSize: '32px', + width: '240px', +} + +CalendarContainer.propTypes = { + /** the currently selected date using an iso-like format YYYY-MM-DD, in the calendar system provided (not iso8601) */ + date: PropTypes.string, + ...CalendarTableProps, + ...NavigationContainerProps, +} diff --git a/components/calendar/src/calendar/calendar-table.js b/components/calendar/src/calendar/calendar-table.js index b4d0ea1940..a9ea2ac5cf 100644 --- a/components/calendar/src/calendar/calendar-table.js +++ b/components/calendar/src/calendar/calendar-table.js @@ -48,7 +48,7 @@ export const CalendarTable = ({ </div> ) -CalendarTable.propTypes = { +export const CalendarTableProps = { calendarWeekDays: PropTypes.arrayOf( PropTypes.arrayOf( PropTypes.shape({ @@ -70,3 +70,5 @@ CalendarTable.propTypes = { weekDayLabels: PropTypes.arrayOf(PropTypes.string), width: PropTypes.string, } + +CalendarTable.propTypes = CalendarTableProps diff --git a/components/calendar/src/calendar/calendar.js b/components/calendar/src/calendar/calendar.js index 51176ea25d..f03a415293 100644 --- a/components/calendar/src/calendar/calendar.js +++ b/components/calendar/src/calendar/calendar.js @@ -2,11 +2,9 @@ import { useDatePicker, useResolvedDirection, } from '@dhis2/multi-calendar-dates' -import { colors } from '@dhis2/ui-constants' import PropTypes from 'prop-types' -import React, { useState } from 'react' -import { CalendarTable } from './calendar-table.js' -import { NavigationContainer } from './navigation-container.js' +import React, { useMemo, useState } from 'react' +import { CalendarContainer } from './calendar-container.js' export const Calendar = ({ onDateSelect, @@ -20,9 +18,6 @@ export const Calendar = ({ width, cellSize, }) => { - const wrapperBorderColor = colors.grey300 - const backgroundColor = 'none' - const [selectedDateString, setSelectedDateString] = useState(date) const languageDirection = useResolvedDirection(dir, locale) @@ -34,7 +29,7 @@ export const Calendar = ({ weekDayFormat, } - const pickerOptions = useDatePicker({ + const pickerResults = useDatePicker({ onDateSelect: (result) => { const { calendarDateString } = result setSelectedDateString(calendarDateString) @@ -44,43 +39,33 @@ export const Calendar = ({ options, }) - const { calendarWeekDays, weekDayLabels } = pickerOptions + const calendarProps = useMemo(() => { + return { + date, + dir, + locale, + width, + cellSize, + // minDate, + // maxDate, + // validation, // todo: clarify how we use validation props (and format) in Calendar (not CalendarInput) + // format, + isValid: pickerResults.isValid, + calendarWeekDays: pickerResults.calendarWeekDays, + weekDayLabels: pickerResults.weekDayLabels, + currMonth: pickerResults.currMonth, + currYear: pickerResults.currYear, + nextMonth: pickerResults.nextMonth, + nextYear: pickerResults.nextYear, + prevMonth: pickerResults.prevMonth, + prevYear: pickerResults.prevYear, + languageDirection, + } + }, [cellSize, date, dir, locale, pickerResults, width, languageDirection]) return ( <div> - <div - className="calendar-wrapper" - dir={languageDirection} - data-test="calendar" - > - <NavigationContainer - pickerOptions={pickerOptions} - languageDirection={languageDirection} - /> - <CalendarTable - selectedDate={selectedDateString} - calendarWeekDays={calendarWeekDays} - weekDayLabels={weekDayLabels} - cellSize={cellSize} - width={width} - /> - </div> - <style jsx>{` - .calendar-wrapper { - font-family: Roboto, sans-serif; - font-weight: 400; - font-size: 14px; - background-color: ${backgroundColor}; - display: flex; - flex-direction: column; - border: 1px solid ${wrapperBorderColor}; - border-radius: 3px; - min-width: ${width}; - width: max-content; - box-shadow: 0px 4px 6px -2px #2129340d; - box-shadow: 0px 10px 15px -3px #2129341a; - } - `}</style> + <CalendarContainer {...calendarProps} /> </div> ) } diff --git a/components/calendar/src/calendar/navigation-container.js b/components/calendar/src/calendar/navigation-container.js index 933f9d6e0d..87f9a1953d 100644 --- a/components/calendar/src/calendar/navigation-container.js +++ b/components/calendar/src/calendar/navigation-container.js @@ -7,15 +7,20 @@ import i18n from '../locales/index.js' const wrapperBorderColor = colors.grey300 const headerBackground = colors.grey050 -export const NavigationContainer = ({ languageDirection, pickerOptions }) => { +export const NavigationContainer = ({ + languageDirection, + currMonth, + currYear, + nextMonth, + nextYear, + prevMonth, + prevYear, +}) => { const PreviousIcon = languageDirection === 'ltr' ? IconChevronLeft16 : IconChevronRight16 const NextIcon = languageDirection === 'ltr' ? IconChevronRight16 : IconChevronLeft16 - const { currMonth, currYear, nextMonth, nextYear, prevMonth, prevYear } = - pickerOptions - // 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/, '') @@ -155,30 +160,30 @@ export const NavigationContainer = ({ languageDirection, pickerOptions }) => { ) } -NavigationContainer.propTypes = { +export const NavigationContainerProps = { + currMonth: PropTypes.shape({ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + }), + currYear: PropTypes.shape({ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + }), languageDirection: PropTypes.oneOf(['ltr', 'rtl']), - pickerOptions: PropTypes.shape({ - currMonth: PropTypes.shape({ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - }), - currYear: PropTypes.shape({ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - }), - nextMonth: PropTypes.shape({ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - navigateTo: PropTypes.func, - }), - nextYear: PropTypes.shape({ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - navigateTo: PropTypes.func, - }), - prevMonth: PropTypes.shape({ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - navigateTo: PropTypes.func, - }), - prevYear: PropTypes.shape({ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - navigateTo: PropTypes.func, - }), + nextMonth: PropTypes.shape({ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + navigateTo: PropTypes.func, + }), + nextYear: PropTypes.shape({ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + navigateTo: PropTypes.func, + }), + prevMonth: PropTypes.shape({ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + navigateTo: PropTypes.func, + }), + prevYear: PropTypes.shape({ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + navigateTo: PropTypes.func, }), } + +NavigationContainer.propTypes = NavigationContainerProps From 0831239aa0acdd484f270f708bc8c54dee4f5dc6 Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Wed, 31 Jul 2024 00:43:35 +0300 Subject: [PATCH 09/11] chore: rename passed props --- components/calendar/src/calendar-input/calendar-input.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/components/calendar/src/calendar-input/calendar-input.js b/components/calendar/src/calendar-input/calendar-input.js index 34be79361c..c670653b9c 100644 --- a/components/calendar/src/calendar-input/calendar-input.js +++ b/components/calendar/src/calendar-input/calendar-input.js @@ -8,7 +8,7 @@ import { useResolvedDirection, } from '@dhis2/multi-calendar-dates' import cx from 'classnames' -import React, { useRef, useState, useMemo, useCallback } from 'react' +import React, { useRef, useState, useMemo } from 'react' import { CalendarContainer } from '../calendar/calendar-container.js' import { CalendarProps } from '../calendar/calendar.js' import i18n from '../locales/index.js' @@ -32,11 +32,10 @@ export const CalendarInput = ({ width, cellSize, clearable, - editable, minDate, maxDate, format, // todo: props and types for format and validation - validation, + strictValidation, ...rest } = {}) => { const ref = useRef() @@ -61,7 +60,7 @@ export const CalendarInput = ({ date, minDate: minDate, maxDate: maxDate, - validation: validation, + strictValidation: strictValidation, format: format, options: useDatePickerOptions, }) @@ -103,7 +102,7 @@ export const CalendarInput = ({ type="text" onFocus={onFocus} value={date} - onChange={editable ? handleChange : undefined} + onChange={handleChange} validationText={ pickerResults.errorMessage || pickerResults.warningMessage From b845ae1529ee12cb3154e4d8078e2ac6df521b5b Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Wed, 31 Jul 2024 21:59:40 +0300 Subject: [PATCH 10/11] fix: label in storybook --- .../src/stories/calendar-input.stories.js | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/components/calendar/src/stories/calendar-input.stories.js b/components/calendar/src/stories/calendar-input.stories.js index be4a73db98..472489a8f7 100644 --- a/components/calendar/src/stories/calendar-input.stories.js +++ b/components/calendar/src/stories/calendar-input.stories.js @@ -22,20 +22,17 @@ export default { }, } -const buildCalendar = - ({ date, locale, calendar }) => - () => - ( - <CalendarStoryWrapper - component={CalendarInput} - dir="ltr" - timeZone="Africa/Khartoum" - weekDayFormat="short" - date={date} - locale={locale} - calendar={calendar} - /> - ) +const buildCalendar = ({ date, locale, calendar }) => () => ( + <CalendarStoryWrapper + component={CalendarInput} + dir="ltr" + timeZone="Africa/Khartoum" + weekDayFormat="short" + date={date} + locale={locale} + calendar={calendar} + /> +) export const EthiopicWithAmharic = buildCalendar({ calendar: 'ethiopic', @@ -128,7 +125,6 @@ export function CalendarWithEditiableInput() { const date = selectedDate?.calendarDateString setDate(date) }} - label="ooo" width={'700px'} inputWidth="900px" timeZone={'UTC'} From e77b9ced64724850827c298a9b059d06ea3c8d4d Mon Sep 17 00:00:00 2001 From: Alaa Yahia <alaay873@live.com> Date: Wed, 31 Jul 2024 22:44:29 +0300 Subject: [PATCH 11/11] fix: lint issue --- .../src/stories/calendar-input.stories.js | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/components/calendar/src/stories/calendar-input.stories.js b/components/calendar/src/stories/calendar-input.stories.js index 472489a8f7..7d3917ad00 100644 --- a/components/calendar/src/stories/calendar-input.stories.js +++ b/components/calendar/src/stories/calendar-input.stories.js @@ -22,17 +22,20 @@ export default { }, } -const buildCalendar = ({ date, locale, calendar }) => () => ( - <CalendarStoryWrapper - component={CalendarInput} - dir="ltr" - timeZone="Africa/Khartoum" - weekDayFormat="short" - date={date} - locale={locale} - calendar={calendar} - /> -) +const buildCalendar = + ({ date, locale, calendar }) => + () => + ( + <CalendarStoryWrapper + component={CalendarInput} + dir="ltr" + timeZone="Africa/Khartoum" + weekDayFormat="short" + date={date} + locale={locale} + calendar={calendar} + /> + ) export const EthiopicWithAmharic = buildCalendar({ calendar: 'ethiopic',