Skip to content

feat: add jalali calendar#1406

Open
mohammad-moa wants to merge 5 commits intobpmn-io:developfrom
mohammad-moa:feature/jalali-calendar
Open

feat: add jalali calendar#1406
mohammad-moa wants to merge 5 commits intobpmn-io:developfrom
mohammad-moa:feature/jalali-calendar

Conversation

@mohammad-moa
Copy link
Copy Markdown

@mohammad-moa mohammad-moa commented Jul 4, 2025

In this PR, Jalali calendar has been added using a side library related to flatpickr called flatpickr-jalali-support.

To use it, you must use locale: 'fa' in the Datetime.js file in the path
packages/form-js-viewer/src/render/components/form-fields/Datetime.js

Similarly, in the Datepicker.js component in the path
packages/form-js-viewer/src/render/components/form-fields/parts/Datepicker.js
import Persian

import { Persian } from 'flatpickr-jalali-support/dist/l10n/fa';

the config variable must be used as follows

    let config = {
      allowInput: true,
      dateFormat: getLocaleDateFlatpickrConfig('fa'),
      static: true,
      clickOpens: false,
      locale: Persian,
      // TODO: support dates prior to 1900 (https://github.com/bpmn-io/form-js/issues/533)
      minDate: disallowPassedDates ? 'today' : '01/01/1900',
      errorHandler: () => {
        /* do nothing, we expect the values to sometimes be erroneous and we don't want warnings polluting the console */
      },
    };

Also to display the input placeholder, you should use

getLocaleReadableDateFormat('fa')

Related to issue

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jul 4, 2025

CLA assistant check
All committers have signed the CLA.

@vsgoulart
Copy link
Copy Markdown
Contributor

@mohammad-moa could you follow the instructions and sign the CLA in the comment above?

@mohammad-moa
Copy link
Copy Markdown
Author

Yeah @vsgoulart , thanks for your attention
I'll read and sign the CLA.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial building blocks for Jalali (Persian) calendar support in the form-js viewer’s datetime/date picker by introducing a Jalali-capable flatpickr wrapper, locale-specific date formatting helpers, and some datetime parsing/serialization adjustments.

Changes:

  • Add flatpickr-jalali-support and switch the Datepicker implementation to import it.
  • Introduce fa-specific handling in localisation utilities (date format + readable placeholder).
  • Adjust datetime parsing (Luxon ISO handling) and datetime serialization (clone date before applying time).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/form-js-viewer/src/render/components/util/localisationUtil.js Adds fa special-casing for date format + readable placeholder.
packages/form-js-viewer/src/render/components/util/dateTimeUtil.js Tweaks datetime serialization to clone the date before applying time.
packages/form-js-viewer/src/render/components/form-fields/parts/Datepicker.js Switches flatpickr import to Jalali-support build and adjusts onChange handler signature.
packages/form-js-viewer/src/render/components/form-fields/Datetime.js Threads a locale field property through to the Datepicker and improves ISO parsing for datetime subtype.
package.json Adds flatpickr-jalali-support dependency (currently at the repo root).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +9 to +11
if (locale === 'fa') {
return 'Y/m/dd';
}
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are existing unit tests for these localisation helpers (packages/form-js-viewer/test/spec/.../localisationUtil.spec.js), but none assert the new fa branch behavior. Please add tests for the expected fa outputs (date format, flatpickr format, and readable placeholder) to avoid regressions.

Copilot uses AI. Check for mistakes.
@@ -1,4 +1,4 @@
import flatpickr from 'flatpickr';
import flatpickr from 'flatpickr-jalali-support';
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flatpickr-jalali-support is imported here, but the Datepicker currently doesn’t apply the locale it receives (and still calls getLocaleDateFlatpickrConfig() / getLocaleReadableDateFormat() without a locale argument). As a result, the new Jalali dependency won’t actually be activated for fa. Consider wiring props.locale into the flatpickr config (config.locale) and into the dateFormat/placeholder helpers so fa renders the Jalali calendar as intended.

Copilot uses AI. Check for mistakes.
Comment on lines +104 to +108
flatpickrInstance.config.onChange = [
(dates) => {
setDate(dates[0]);
setIsInputDirty(false);
},
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onChange can be invoked with an empty selectedDates array (e.g. when the input is cleared or the value becomes invalid). In that case dates[0] is undefined, and later flatpickrInstance.setDate(date, true) will receive undefined, which can lead to unexpected behavior (e.g. jumping to today instead of clearing). Handle the empty-array case explicitly (clear the picker / set an invalid date) before calling setDate.

Copilot uses AI. Check for mistakes.
Comment on lines 42 to 46
disallowPassedDates,
timeInterval,
timeSerializingFormat,
locale,
} = field;
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

locale is now read from the field config, but the JSON schema currently does not define/allow a locale property for datetime components. That means forms using this will likely fail schema validation (and the editor won’t be able to persist it). To make this usable, add locale to the schema + allowed-properties rules for datetime (and bump schemaVersion if required by this repo’s schema versioning process).

Copilot uses AI. Check for mistakes.
date: dateTime.date,
readonly,
setDate,
locale,
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

locale is forwarded to Datepicker here, but Datepicker doesn’t currently consume it, so this prop has no effect. Once Jalali support is wired up, ensure the prop is actually used to set the flatpickr locale/dateFormat/placeholder; otherwise this becomes dead configuration surface.

Suggested change
locale,

Copilot uses AI. Check for mistakes.
Comment thread package.json
"eslint-plugin-bpmn-io": "^2.2.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-react-hooks": "^5.2.0",
"flatpickr-jalali-support": "^1.0.3",
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding flatpickr-jalali-support only to the root devDependencies is not sufficient for published packages: @bpmn-io/form-js-viewer now imports it at runtime (Datepicker.js), but packages/form-js-viewer/package.json does not declare it as a dependency. This will cause "Cannot find module 'flatpickr-jalali-support'" for consumers. Move/add the dependency to @bpmn-io/form-js-viewer (and update its rollup externals accordingly), and consider whether flatpickr should remain a direct dependency.

Suggested change
"flatpickr-jalali-support": "^1.0.3",

Copilot uses AI. Check for mistakes.
*/
export function getLocaleDateFormat(locale = 'default') {
if (locale === 'fa') {
return 'Y/m/dd';
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getLocaleDateFormat('fa') returns Y/m/dd, which mixes flatpickr tokens (Y, m) with this util's own d/M/y token convention. This makes getLocaleDateFlatpickrConfig('fa') rely on accidental passthrough rather than the flatpickerizeDateFormat conversion logic. Consider returning the same d/M/y-style pattern as other locales (e.g. dd/MM/yyyy) and let flatpickerizeDateFormat do the flatpickr mapping.

Suggested change
return 'Y/m/dd';
return 'dd/MM/yyyy';

Copilot uses AI. Check for mistakes.
@AlekseyManetov
Copy link
Copy Markdown

Hey @mohammad-moa, thanks for the contribution!

Could you help me understand the intended usage — how would a user activate Jalali calendar mode? I believe it should be configurable, and doesn't break our current default behavior.

Also, could you add tests covering the expected configuration and behavior? That would help us understand the API surface and make sure things work end-to-end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants